From e1f382c38793ff60277684e9a3288072a78ec86e Mon Sep 17 00:00:00 2001 From: shekhar16 Date: Sat, 28 Sep 2024 00:59:04 +0530 Subject: [PATCH] feat(jans-fido): move fidoconfig folder properties to db #9369 (#9611) * feat(jans-fido): move fidoconfig folder properties to db #9369 Signed-off-by: shekhar16 shekharlaad1609@gmail.com * feat(jans-fido): added specialized exception #9369 Signed-off-by: shekhar16 shekharlaad1609@gmail.com --------- Signed-off-by: shekhar16 shekharlaad1609@gmail.com Co-authored-by: Yuriy Movchan --- .../store/service/DBDocumentService.java | 27 +++++- .../fido2/service/CertificateService.java | 19 ++-- .../io/jans/fido2/service/mds/TocService.java | 96 ++++++++++++------- 3 files changed, 92 insertions(+), 50 deletions(-) diff --git a/jans-core/document-store/src/main/java/io/jans/service/document/store/service/DBDocumentService.java b/jans-core/document-store/src/main/java/io/jans/service/document/store/service/DBDocumentService.java index c50b0f98975..9be84fd6998 100644 --- a/jans-core/document-store/src/main/java/io/jans/service/document/store/service/DBDocumentService.java +++ b/jans-core/document-store/src/main/java/io/jans/service/document/store/service/DBDocumentService.java @@ -31,6 +31,7 @@ public class DBDocumentService implements Serializable { public static final String displayName = "displayName"; public static final String description = "description"; public static final String alias = "jansAlias"; + public static final String jansFilePath = "jansFilePath"; @Inject private Logger logger; @@ -59,7 +60,7 @@ public void init() { /** * Add new Document entry * - * @param Document + * @param document * Document */ public void addDocument(Document document) throws Exception { @@ -70,7 +71,7 @@ public void addDocument(Document document) throws Exception { /** * Remove Document entry * - * @param Document + * @param document * Document */ public void removeDocument(Document document) throws Exception { @@ -98,7 +99,7 @@ public Document getDocumentByInum(String inum) throws Exception { /** * Update Document entry * - * @param Document + * @param document * Document */ public void updateDocument(Document document) throws Exception { @@ -185,7 +186,7 @@ public Document getDocumentByDn(String dn) throws Exception { /** * Get documents by DisplayName * - * @param DisplayName + * @param displayName * @return documents */ public Document getDocumentByDisplayName(String displayName) throws Exception { @@ -248,4 +249,22 @@ public String baseDn() { return String.format("ou=document,%s", "o=jans"); } + public List getDocumentsByFilePath(String filePath){ + Filter searchFilter = null; + if (StringHelper.isNotEmpty(filePath)) { + String[] targetArray = new String[] { filePath }; + Filter displayNameFilter = Filter.createSubstringFilter(jansFilePath, null, targetArray, + null); + searchFilter = Filter.createORFilter(displayNameFilter); + } + List result = new ArrayList<>(); + try { + result = persistenceEntryManager.findEntries(getDnForDocument(null), Document.class, searchFilter, 100); + return result; + } catch (Exception e) { + logger.error("Failed to find Document : ", e); + } + return result; + } + } diff --git a/jans-fido2/server/src/main/java/io/jans/fido2/service/CertificateService.java b/jans-fido2/server/src/main/java/io/jans/fido2/service/CertificateService.java index 40183efb7be..c1955d558d0 100644 --- a/jans-fido2/server/src/main/java/io/jans/fido2/service/CertificateService.java +++ b/jans-fido2/server/src/main/java/io/jans/fido2/service/CertificateService.java @@ -30,6 +30,8 @@ import io.jans.fido2.model.attestation.AttestationErrorResponseType; import io.jans.fido2.model.error.ErrorResponseFactory; +import io.jans.service.document.store.model.Document; +import io.jans.service.document.store.service.DBDocumentService; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @@ -55,6 +57,8 @@ public class CertificateService { @Inject private ErrorResponseFactory errorResponseFactory; + @Inject + private DBDocumentService dbDocumentService; public X509Certificate getCertificate(String x509certificate) { return getCertificate(new ByteArrayInputStream(base64Service.decode(x509certificate))); @@ -120,18 +124,9 @@ public Map getCertificatesMap(String rootCertificatePat public List getCertificates(String rootCertificatePath) { ArrayList certificates = new ArrayList(); - Path path = FileSystems.getDefault().getPath(rootCertificatePath); - try (DirectoryStream directoryStream = Files.newDirectoryStream(path)) { - Iterator iter = directoryStream.iterator(); - while (iter.hasNext()) { - Path filePath = iter.next(); - if (!Files.isDirectory(filePath)) { - certificates.add(getCertificate(Files.newInputStream(filePath))); - } - } - } catch (Exception ex) { - log.error("Failed to load cert from folder: '{}'", rootCertificatePath, ex); - } + List tocCertificatesDocuments = dbDocumentService.getDocumentsByFilePath(rootCertificatePath); + for (Document certDB : tocCertificatesDocuments) + certificates.add(getCertificate(certDB.getDocument())); return certificates; } diff --git a/jans-fido2/server/src/main/java/io/jans/fido2/service/mds/TocService.java b/jans-fido2/server/src/main/java/io/jans/fido2/service/mds/TocService.java index 160395f9388..dcfbd40a938 100644 --- a/jans-fido2/server/src/main/java/io/jans/fido2/service/mds/TocService.java +++ b/jans-fido2/server/src/main/java/io/jans/fido2/service/mds/TocService.java @@ -29,6 +29,7 @@ import io.jans.fido2.service.app.ConfigurationFactory; import io.jans.fido2.service.verifier.CertificateVerifier; import io.jans.service.cdi.event.ApplicationInitialized; +import io.jans.service.document.store.exception.DocumentException; import io.jans.service.document.store.model.Document; import io.jans.service.document.store.service.DBDocumentService; import io.jans.util.Pair; @@ -37,6 +38,7 @@ import jakarta.enterprise.event.Observes; import jakarta.inject.Inject; import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -131,42 +133,47 @@ private Map parseTOCs() { log.warn("Fido2 MDS cert and TOC properties should be set"); return new HashMap(); } + log.info("Populating TOC certs entries from {}", mdsTocRootCertsFolder); log.info("Populating TOC entries from {}", mdsTocFilesFolder); - Path path = FileSystems.getDefault().getPath(mdsTocFilesFolder); + try { + List tocRootCertsDocuments = dbDocumentService.getDocumentsByFilePath(mdsTocRootCertsFolder); + } catch (Exception e) { + log.error("Failed to fetch toc Root Certs Documents ", e); + throw new DocumentException(e); + } + + List tocFilesdocuments = new ArrayList<>(); + try { + tocFilesdocuments = dbDocumentService.getDocumentsByFilePath(mdsTocFilesFolder); + } catch (Exception e) { + log.error("Failed to fetch toc Files Documents ", e); + throw new DocumentException(e); + } + List> maps = new ArrayList<>(); - try (DirectoryStream directoryStream = Files.newDirectoryStream(path)) { - Iterator iter = directoryStream.iterator(); - while (iter.hasNext()) { - Path filePath = iter.next(); + for(Document document :tocFilesdocuments){ try { - Pair> result = parseTOC(mdsTocRootCertsFolder, filePath); + Pair> result = parseTOC(mdsTocRootCertsFolder, document.getDocument()); log.info("Get TOC {} entries with nextUpdate date {}", result.getSecond().size(), result.getFirst()); maps.add(result.getSecond()); } catch (IOException e) { - log.warn("Can't access or open path: {}", filePath, e); + log.warn("Can't access or open path: {}", document.getFileName(), e); } catch (ParseException e) { - log.warn("Can't parse path: {}", filePath, e); + log.warn("Can't parse path: {}", document.getFileName(), e); } } - } catch (Exception e) { - log.warn("Something wrong with path", e); - } return mergeAndResolveDuplicateEntries(maps); } - private Map parseTOC(String mdsTocRootCertFile, String mdsTocFileLocation) { - try { - return parseTOC(mdsTocRootCertFile, FileSystems.getDefault().getPath(mdsTocFileLocation)).getSecond(); - } catch (IOException e) { - throw new Fido2RuntimeException("Unable to read TOC at " + mdsTocFileLocation, e); - } catch (ParseException e) { - throw new Fido2RuntimeException("Unable to parse TOC at " + mdsTocFileLocation, e); - } - } + private Pair> parseTOC(String mdsTocRootCertsFolder, String content) + throws IOException, ParseException { + String decodedString = new String(base64Service.decode(content)); + return readEntriesFromTocJWT(decodedString, mdsTocRootCertsFolder, true); + } private Pair> parseTOC(String mdsTocRootCertsFolder, Path path) throws IOException, ParseException { @@ -279,24 +286,43 @@ public boolean downloadMdsFromServer(URL metadataUrl) { Fido2Configuration fido2Configuration = appConfiguration.getFido2Configuration(); String mdsTocFilesFolder = fido2Configuration.getMdsTocsFolder(); + try { + List documents = dbDocumentService.getDocumentsByFilePath(mdsTocFilesFolder); + for (Document document : documents){ + dbDocumentService.removeDocument(document); + } + } catch (Exception e) { + log.error("Failed to remove old document of mdsTocFilesFolder" , e); + throw new DocumentException(e); + } - Path path = FileSystems.getDefault().getPath(mdsTocFilesFolder); - try (DirectoryStream directoryStream = Files.newDirectoryStream(path)) { - Iterator iter = directoryStream.iterator(); - while (iter.hasNext()) { - Path filePath = iter.next(); - try (InputStream in = metadataUrl.openStream()) { + try (InputStream in = metadataUrl.openStream()) { + byte[] sourceBytes = IOUtils.toByteArray(in); - Files.copy(in, filePath, StandardCopyOption.REPLACE_EXISTING); + String encodedString = base64Service.encodeToString(sourceBytes); - log.info("TOC file updated."); - return true; - } + Document document = new Document(); + document.setFileName("mdsToc"); + document.setDescription("MDS TOC JWT file"); + document.setService(new ArrayList<>(Arrays.asList("Fido2 MDS"))); + document.setFilePath(mdsTocFilesFolder); + try { + document.setDocument(encodedString); + document.setInum(dbDocumentService.generateInumForNewDocument()); + document.setDn(dbDocumentService.getDnForDocument(document.getInum())); + document.setEnabled(true); + dbDocumentService.addDocument(document); + } catch (Exception e) { + log.error("Failed to add new document of mdsTocFilesFolder" , e); + throw new DocumentException(e); } + + log.info("TOC file updated."); + return true; } catch (IOException e) { - log.warn("Can't access or open path: {}", path, e); + log.warn("Can't access or open path: {}", metadataUrl, e); + throw new Fido2RuntimeException("Can't access or open path: {}" + metadataUrl + e.getMessage(), e); } - return false; } private void loadMetadataServiceExternalProvider() { @@ -362,7 +388,8 @@ public List saveMetadataServerCertsInDB(String metadataServer, String bl try { dbDocumentService.removeDocument(certDoc); } catch (Exception e) { - throw new RuntimeException(e); + log.error("Failed to remove document file[ath:'" +certDoc.getFilePath()+ "' : " , e); + throw new DocumentException(e); } } @@ -379,7 +406,8 @@ public List saveMetadataServerCertsInDB(String metadataServer, String bl dbDocumentService.addDocument(document); result.add(document.getInum()); } catch (Exception e) { - throw new RuntimeException(e); + log.error("Failed to add document for '" + document.getFileName() + ", message: " + e.getMessage(), e); + throw new DocumentException(e); } } }