View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.wa.starter.mapping;
20  
21  import java.util.HashSet;
22  import java.util.List;
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.commons.lang3.tuple.Pair;
28  import org.apache.syncope.common.lib.auth.MFAAuthModuleConf;
29  import org.apache.syncope.common.lib.auth.Pac4jAuthModuleConf;
30  import org.apache.syncope.common.lib.policy.AuthPolicyConf;
31  import org.apache.syncope.common.lib.policy.AuthPolicyTO;
32  import org.apache.syncope.common.lib.policy.DefaultAuthPolicyConf;
33  import org.apache.syncope.common.lib.to.AuthModuleTO;
34  import org.apereo.cas.authentication.AuthenticationEventExecutionPlan;
35  import org.apereo.cas.authentication.AuthenticationHandler;
36  import org.apereo.cas.authentication.MultifactorAuthenticationHandler;
37  import org.apereo.cas.authentication.MultifactorAuthenticationProvider;
38  import org.apereo.cas.services.AnyAuthenticationHandlerRegisteredServiceAuthenticationPolicyCriteria;
39  import org.apereo.cas.services.DefaultRegisteredServiceAuthenticationPolicy;
40  import org.apereo.cas.services.DefaultRegisteredServiceDelegatedAuthenticationPolicy;
41  import org.apereo.cas.services.DefaultRegisteredServiceMultifactorPolicy;
42  import org.slf4j.Logger;
43  import org.slf4j.LoggerFactory;
44  import org.springframework.beans.factory.ObjectProvider;
45  
46  public class DefaultAuthMapper implements AuthMapper {
47  
48      protected static final Logger LOG = LoggerFactory.getLogger(DefaultAuthMapper.class);
49  
50      @Override
51      public boolean supports(final AuthPolicyConf conf) {
52          return DefaultAuthPolicyConf.class.equals(conf.getClass());
53      }
54  
55      @Override
56      public AuthMapperResult build(
57              final String pac4jCoreName,
58              final ObjectProvider<AuthenticationEventExecutionPlan> authEventExecPlan,
59              final List<MultifactorAuthenticationProvider> multifactorAuthenticationProviders,
60              final AuthPolicyTO policy,
61              final List<AuthModuleTO> authModules) {
62  
63          DefaultRegisteredServiceAuthenticationPolicy authPolicy = new DefaultRegisteredServiceAuthenticationPolicy();
64  
65          Set<String> mfaAuthHandlers = new HashSet<>();
66          Set<Pair<String, String>> delegatedAuthHandlers = new HashSet<>();
67  
68          DefaultAuthPolicyConf policyConf = (DefaultAuthPolicyConf) policy.getConf();
69          Set<String> authHandlers = authModules.stream().map(AuthModuleTO::getKey).
70                  collect(Collectors.toCollection(HashSet::new));
71          if (!authHandlers.isEmpty()) {
72              mfaAuthHandlers.addAll(authEventExecPlan.getObject().getAuthenticationHandlers().stream().
73                      filter(MultifactorAuthenticationHandler.class::isInstance).
74                      filter(mfaAuthHander -> policyConf.getAuthModules().contains(mfaAuthHander.getName())).
75                      map(AuthenticationHandler::getName).
76                      collect(Collectors.toSet()));
77              authHandlers.removeAll(mfaAuthHandlers);
78  
79              delegatedAuthHandlers.addAll(authModules.stream().
80                      filter(m -> m.getConf() instanceof Pac4jAuthModuleConf).
81                      map(m -> Pair.of(
82                      m.getKey(),
83                      Optional.ofNullable(((Pac4jAuthModuleConf) m.getConf()).getClientName()).orElse(m.getKey()))).
84                      collect(Collectors.toSet()));
85              if (!delegatedAuthHandlers.isEmpty()) {
86                  authHandlers.removeAll(delegatedAuthHandlers.stream().map(Pair::getLeft).collect(Collectors.toSet()));
87                  authHandlers.add(pac4jCoreName);
88              }
89  
90              authPolicy.setRequiredAuthenticationHandlers(authHandlers);
91          }
92  
93          AnyAuthenticationHandlerRegisteredServiceAuthenticationPolicyCriteria criteria =
94                  new AnyAuthenticationHandlerRegisteredServiceAuthenticationPolicyCriteria();
95          criteria.setTryAll(policyConf.isTryAll());
96          authPolicy.setCriteria(criteria);
97  
98          DefaultRegisteredServiceMultifactorPolicy mfaPolicy = null;
99          if (!mfaAuthHandlers.isEmpty()) {
100             Set<String> fns = mfaAuthHandlers.stream().
101                     map(handler -> authModules.stream().filter(am -> handler.equals(am.getKey())).findFirst()).
102                     filter(Optional::isPresent).
103                     map(Optional::get).
104                     filter(am -> am.getConf() instanceof MFAAuthModuleConf).
105                     map(am -> ((MFAAuthModuleConf) am.getConf()).getFriendlyName()).
106                     collect(Collectors.toSet());
107 
108             Set<String> mfaProviders = multifactorAuthenticationProviders.stream().
109                     filter(map -> fns.contains(map.getFriendlyName())).
110                     map(MultifactorAuthenticationProvider::getId).
111                     collect(Collectors.toSet());
112 
113             mfaPolicy = new DefaultRegisteredServiceMultifactorPolicy();
114 
115             if (StringUtils.isNotBlank(policyConf.getBypassPrincipalAttributeName())
116                     && StringUtils.isNotBlank(policyConf.getBypassPrincipalAttributeValue())) {
117                 mfaPolicy.setBypassPrincipalAttributeName(policyConf.getBypassPrincipalAttributeName());
118                 mfaPolicy.setBypassPrincipalAttributeValue(policyConf.getBypassPrincipalAttributeValue());
119             } else {
120                 mfaPolicy.setBypassEnabled(policyConf.isBypassEnabled());
121             }
122 
123             mfaPolicy.setForceExecution(true);
124             mfaPolicy.setMultifactorAuthenticationProviders(mfaProviders);
125         }
126 
127         DefaultRegisteredServiceDelegatedAuthenticationPolicy delegatedAuthPolicy = null;
128         if (!delegatedAuthHandlers.isEmpty()) {
129             delegatedAuthPolicy = new DefaultRegisteredServiceDelegatedAuthenticationPolicy();
130             delegatedAuthPolicy.getAllowedProviders().addAll(
131                     delegatedAuthHandlers.stream().map(Pair::getRight).collect(Collectors.toSet()));
132         }
133 
134         return new AuthMapperResult(authPolicy, mfaPolicy, delegatedAuthPolicy);
135     }
136 }