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.mapping;
20
21 import java.util.HashSet;
22 import java.util.Objects;
23 import java.util.Optional;
24 import java.util.Set;
25 import java.util.stream.Collectors;
26 import org.apache.commons.lang3.StringUtils;
27 import org.apache.syncope.common.lib.OIDCScopeConstants;
28 import org.apache.syncope.common.lib.to.ClientAppTO;
29 import org.apache.syncope.common.lib.to.OIDCRPClientAppTO;
30 import org.apache.syncope.common.lib.types.OIDCGrantType;
31 import org.apache.syncope.common.lib.types.OIDCResponseType;
32 import org.apache.syncope.common.lib.wa.WAClientApp;
33 import org.apereo.cas.oidc.claims.OidcAddressScopeAttributeReleasePolicy;
34 import org.apereo.cas.oidc.claims.OidcCustomScopeAttributeReleasePolicy;
35 import org.apereo.cas.oidc.claims.OidcEmailScopeAttributeReleasePolicy;
36 import org.apereo.cas.oidc.claims.OidcOpenIdScopeAttributeReleasePolicy;
37 import org.apereo.cas.oidc.claims.OidcPhoneScopeAttributeReleasePolicy;
38 import org.apereo.cas.oidc.claims.OidcProfileScopeAttributeReleasePolicy;
39 import org.apereo.cas.services.BaseMappedAttributeReleasePolicy;
40 import org.apereo.cas.services.ChainingAttributeReleasePolicy;
41 import org.apereo.cas.services.OidcRegisteredService;
42 import org.apereo.cas.services.RegisteredService;
43 import org.apereo.cas.services.RegisteredServiceAccessStrategy;
44 import org.apereo.cas.services.RegisteredServiceAttributeReleasePolicy;
45 import org.apereo.cas.services.RegisteredServiceAuthenticationPolicy;
46 import org.apereo.cas.services.RegisteredServiceMultifactorPolicy;
47 import org.apereo.cas.services.RegisteredServiceProxyGrantingTicketExpirationPolicy;
48 import org.apereo.cas.services.RegisteredServiceProxyTicketExpirationPolicy;
49 import org.apereo.cas.services.RegisteredServiceServiceTicketExpirationPolicy;
50 import org.apereo.cas.services.RegisteredServiceTicketGrantingTicketExpirationPolicy;
51 import org.apereo.cas.services.ReturnAllowedAttributeReleasePolicy;
52
53 public class OIDCRPClientAppTOMapper extends AbstractClientAppMapper {
54
55 @Override
56 public boolean supports(final ClientAppTO clientApp) {
57 return OIDCRPClientAppTO.class.equals(clientApp.getClass());
58 }
59
60 @Override
61 public RegisteredService map(
62 final WAClientApp clientApp,
63 final RegisteredServiceAuthenticationPolicy authPolicy,
64 final RegisteredServiceMultifactorPolicy mfaPolicy,
65 final RegisteredServiceAccessStrategy accessStrategy,
66 final RegisteredServiceAttributeReleasePolicy attributeReleasePolicy,
67 final RegisteredServiceTicketGrantingTicketExpirationPolicy tgtExpirationPolicy,
68 final RegisteredServiceServiceTicketExpirationPolicy stExpirationPolicy,
69 final RegisteredServiceProxyGrantingTicketExpirationPolicy tgtProxyExpirationPolicy,
70 final RegisteredServiceProxyTicketExpirationPolicy stProxyExpirationPolicy) {
71
72 OIDCRPClientAppTO rp = OIDCRPClientAppTO.class.cast(clientApp.getClientAppTO());
73 OidcRegisteredService service = new OidcRegisteredService();
74 setCommon(service, rp);
75
76 service.setServiceId(rp.getRedirectUris().stream().
77 filter(Objects::nonNull).
78 collect(Collectors.joining("|")));
79 service.setClientId(rp.getClientId());
80 service.setClientSecret(rp.getClientSecret());
81 service.setSignIdToken(rp.isSignIdToken());
82 if (!service.isSignIdToken()) {
83 service.setIdTokenSigningAlg("none");
84 }
85 service.setJwtAccessToken(rp.isJwtAccessToken());
86 service.setBypassApprovalPrompt(rp.isBypassApprovalPrompt());
87 service.setGenerateRefreshToken(rp.isGenerateRefreshToken());
88 if (StringUtils.isNotBlank(rp.getJwksUri())) {
89 service.setJwks(rp.getJwksUri());
90 } else {
91 service.setJwks(rp.getJwks());
92 }
93 service.setSupportedGrantTypes(rp.getSupportedGrantTypes().stream().
94 map(OIDCGrantType::name).collect(Collectors.toSet()));
95 service.setSupportedResponseTypes(rp.getSupportedResponseTypes().stream().
96 map(OIDCResponseType::getExternalForm).collect(Collectors.toSet()));
97 Optional.ofNullable(rp.getSubjectType()).ifPresent(st -> service.setSubjectType(st.name()));
98 service.setLogoutUrl(rp.getLogoutUri());
99 service.setTokenEndpointAuthenticationMethod(rp.getTokenEndpointAuthenticationMethod().name());
100
101 service.setScopes(new HashSet<>(rp.getScopes()));
102
103 ChainingAttributeReleasePolicy chain;
104 if (attributeReleasePolicy instanceof ChainingAttributeReleasePolicy) {
105 chain = (ChainingAttributeReleasePolicy) attributeReleasePolicy;
106 } else {
107 chain = new ChainingAttributeReleasePolicy();
108 Optional.ofNullable(attributeReleasePolicy).ifPresent(chain::addPolicies);
109 }
110
111 if (rp.getScopes().contains(OIDCScopeConstants.OPEN_ID)) {
112 chain.addPolicies(new OidcOpenIdScopeAttributeReleasePolicy());
113 }
114 if (rp.getScopes().contains(OIDCScopeConstants.PROFILE)) {
115 chain.addPolicies(new OidcProfileScopeAttributeReleasePolicy());
116 }
117 if (rp.getScopes().contains(OIDCScopeConstants.ADDRESS)) {
118 chain.addPolicies(new OidcAddressScopeAttributeReleasePolicy());
119 }
120 if (rp.getScopes().contains(OIDCScopeConstants.EMAIL)) {
121 chain.addPolicies(new OidcEmailScopeAttributeReleasePolicy());
122 }
123 if (rp.getScopes().contains(OIDCScopeConstants.PHONE)) {
124 chain.addPolicies(new OidcPhoneScopeAttributeReleasePolicy());
125 }
126
127 Set<String> customClaims = new HashSet<>();
128 if (attributeReleasePolicy instanceof BaseMappedAttributeReleasePolicy) {
129 customClaims.addAll(((BaseMappedAttributeReleasePolicy) attributeReleasePolicy).
130 getAllowedAttributes().values().stream().
131 map(Objects::toString).collect(Collectors.toSet()));
132 } else if (attributeReleasePolicy instanceof ReturnAllowedAttributeReleasePolicy) {
133 customClaims.addAll(((ReturnAllowedAttributeReleasePolicy) attributeReleasePolicy).
134 getAllowedAttributes().stream().collect(Collectors.toSet()));
135 } else if (attributeReleasePolicy instanceof ChainingAttributeReleasePolicy) {
136 ((ChainingAttributeReleasePolicy) attributeReleasePolicy).getPolicies().stream().
137 filter(ReturnAllowedAttributeReleasePolicy.class::isInstance).
138 findFirst().map(ReturnAllowedAttributeReleasePolicy.class::cast).
139 map(p -> p.getAllowedAttributes().stream().collect(Collectors.toSet())).
140 ifPresent(customClaims::addAll);
141 }
142 if (rp.getScopes().contains(OIDCScopeConstants.PROFILE)) {
143 customClaims.removeAll(OidcProfileScopeAttributeReleasePolicy.ALLOWED_CLAIMS);
144 }
145 if (rp.getScopes().contains(OIDCScopeConstants.ADDRESS)) {
146 customClaims.removeAll(OidcAddressScopeAttributeReleasePolicy.ALLOWED_CLAIMS);
147 }
148 if (rp.getScopes().contains(OIDCScopeConstants.EMAIL)) {
149 customClaims.removeAll(OidcEmailScopeAttributeReleasePolicy.ALLOWED_CLAIMS);
150 }
151 if (rp.getScopes().contains(OIDCScopeConstants.PHONE)) {
152 customClaims.removeAll(OidcPhoneScopeAttributeReleasePolicy.ALLOWED_CLAIMS);
153 }
154
155 if (!customClaims.isEmpty()) {
156 service.getScopes().add(OIDCScopeConstants.SYNCOPE);
157
158 chain.addPolicies(new OidcCustomScopeAttributeReleasePolicy(
159 OIDCScopeConstants.SYNCOPE, customClaims.stream().collect(Collectors.toList())));
160 }
161
162 setPolicies(service, authPolicy, mfaPolicy, accessStrategy, chain,
163 tgtExpirationPolicy, stExpirationPolicy, tgtProxyExpirationPolicy, stProxyExpirationPolicy);
164
165 return service;
166 }
167 }