1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.wa.starter.saml.idp.metadata;
20
21 import com.github.benmanes.caffeine.cache.Cache;
22 import java.nio.charset.StandardCharsets;
23 import java.util.Base64;
24 import java.util.Optional;
25 import org.apache.syncope.common.lib.SyncopeClientException;
26 import org.apache.syncope.common.lib.to.SAML2IdPEntityTO;
27 import org.apache.syncope.common.lib.types.ClientExceptionType;
28 import org.apache.syncope.common.rest.api.service.SAML2IdPEntityService;
29 import org.apache.syncope.wa.bootstrap.WARestClient;
30 import org.apereo.cas.support.saml.idp.metadata.locator.AbstractSamlIdPMetadataLocator;
31 import org.apereo.cas.support.saml.services.SamlRegisteredService;
32 import org.apereo.cas.support.saml.services.idp.metadata.SamlIdPMetadataDocument;
33 import org.apereo.cas.util.crypto.CipherExecutor;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 public class WASamlIdPMetadataLocator extends AbstractSamlIdPMetadataLocator {
38
39 protected static final Logger LOG = LoggerFactory.getLogger(WASamlIdPMetadataLocator.class);
40
41 protected final WARestClient waRestClient;
42
43 public WASamlIdPMetadataLocator(
44 final CipherExecutor<String, String> metadataCipherExecutor,
45 final Cache<String, SamlIdPMetadataDocument> metadataCache,
46 final WARestClient waRestClient) {
47
48 super(metadataCipherExecutor, metadataCache);
49 this.waRestClient = waRestClient;
50 }
51
52 protected SAML2IdPEntityTO fetchFromCore(final Optional<SamlRegisteredService> registeredService) {
53 SAML2IdPEntityService idpEntityService = waRestClient.getService(SAML2IdPEntityService.class);
54
55 SAML2IdPEntityTO result = null;
56 try {
57 result = idpEntityService.get(registeredService.
58 map(SamlRegisteredService::getName).
59 orElse(SAML2IdPEntityService.DEFAULT_OWNER));
60 } catch (SyncopeClientException e) {
61 if (e.getType() == ClientExceptionType.NotFound && registeredService.isPresent()) {
62 result = idpEntityService.get(SAML2IdPEntityService.DEFAULT_OWNER);
63 } else {
64 throw e;
65 }
66 }
67
68 return result;
69 }
70
71 @Override
72 public SamlIdPMetadataDocument fetchInternal(final Optional<SamlRegisteredService> registeredService) {
73 try {
74 LOG.info("Locating SAML2 IdP metadata document");
75
76 SAML2IdPEntityTO entityTO = fetchFromCore(registeredService);
77 if (entityTO != null) {
78 SamlIdPMetadataDocument document = new SamlIdPMetadataDocument();
79 document.setAppliesTo(entityTO.getKey());
80 document.setMetadata(new String(Base64.getDecoder().decode(
81 entityTO.getMetadata()), StandardCharsets.UTF_8));
82 if (entityTO.getSigningCertificate() != null) {
83 document.setSigningCertificate(new String(Base64.getDecoder().decode(
84 entityTO.getSigningCertificate()), StandardCharsets.UTF_8));
85 }
86 if (entityTO.getSigningKey() != null) {
87 document.setSigningKey(new String(Base64.getDecoder().decode(
88 entityTO.getSigningKey().getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8));
89 }
90 if (entityTO.getEncryptionCertificate() != null) {
91 document.setEncryptionCertificate(new String(Base64.getDecoder().decode(
92 entityTO.getEncryptionCertificate()), StandardCharsets.UTF_8));
93 }
94 if (entityTO.getEncryptionKey() != null) {
95 document.setEncryptionKey(new String(Base64.getDecoder().decode(
96 entityTO.getEncryptionKey().getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8));
97 }
98
99 if (document.isValid()) {
100 LOG.debug("Found SAML2 IdP metadata document: {}", document.getId());
101 return document;
102 }
103 }
104
105 LOG.warn("Not a valid SAML2 IdP metadata document");
106 return null;
107 } catch (Exception e) {
108 if (e instanceof SyncopeClientException
109 && ((SyncopeClientException) e).getType() == ClientExceptionType.NotFound) {
110 LOG.info(e.getMessage());
111 } else {
112 if (LOG.isDebugEnabled()) {
113 LOG.error("While fetching SAML2 IdP metadata", e);
114 } else {
115 LOG.error("While fetching SAML2 IdP metadata: " + e.getMessage());
116 }
117 }
118 }
119
120 return null;
121 }
122 }