resolveInternal(RequestContext)   F
last analyzed

Complexity

Conditions 10

Size

Total Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 43
c 0
b 0
f 0
cc 10
rs 3.1304

How to fix   Complexity   

Complexity

Complex classes like org.apereo.cas.web.flow.resolver.impl.mfa.RequestParameterMultifactorAuthenticationPolicyEventResolver.resolveInternal(RequestContext) often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
package org.apereo.cas.web.flow.resolver.impl.mfa;
2
3
import org.apache.commons.lang3.StringUtils;
4
import org.apereo.cas.CentralAuthenticationService;
5
import org.apereo.cas.authentication.Authentication;
6
import org.apereo.cas.authentication.AuthenticationException;
7
import org.apereo.cas.authentication.AuthenticationServiceSelectionPlan;
8
import org.apereo.cas.authentication.AuthenticationSystemSupport;
9
import org.apereo.cas.authentication.MultifactorAuthenticationUtils;
10
import org.apereo.cas.configuration.CasConfigurationProperties;
11
import org.apereo.cas.services.MultifactorAuthenticationProvider;
12
import org.apereo.cas.services.MultifactorAuthenticationProviderSelector;
13
import org.apereo.cas.services.RegisteredService;
14
import org.apereo.cas.services.ServicesManager;
15
import org.apereo.cas.ticket.registry.TicketRegistrySupport;
16
import org.apereo.cas.util.CollectionUtils;
17
import org.apereo.cas.web.flow.authentication.BaseMultifactorAuthenticationProviderEventResolver;
18
import org.apereo.cas.web.support.WebUtils;
19
import org.apereo.inspektr.audit.annotation.Audit;
20
import org.slf4j.Logger;
21
import org.slf4j.LoggerFactory;
22
import org.springframework.web.util.CookieGenerator;
23
import org.springframework.webflow.execution.Event;
24
import org.springframework.webflow.execution.RequestContext;
25
26
import javax.servlet.http.HttpServletRequest;
27
import java.util.Map;
28
import java.util.Optional;
29
import java.util.Set;
30
31
/**
32
 * This is {@link RequestParameterMultifactorAuthenticationPolicyEventResolver}
33
 * that attempts to resolve the next event based on the authentication providers of this service.
34
 *
35
 * @author Misagh Moayyed
36
 * @since 5.0.0
37
 */
38
public class RequestParameterMultifactorAuthenticationPolicyEventResolver extends BaseMultifactorAuthenticationProviderEventResolver {
39
    private static final Logger LOGGER = LoggerFactory.getLogger(RequestParameterMultifactorAuthenticationPolicyEventResolver.class);
40
41
    private final String mfaRequestParameter;
42
43
    public RequestParameterMultifactorAuthenticationPolicyEventResolver(final AuthenticationSystemSupport authenticationSystemSupport,
44
                                                                        final CentralAuthenticationService centralAuthenticationService,
45
                                                                        final ServicesManager servicesManager,
46
                                                                        final TicketRegistrySupport ticketRegistrySupport,
47
                                                                        final CookieGenerator warnCookieGenerator,
48
                                                                        final AuthenticationServiceSelectionPlan authenticationStrategies,
49
                                                                        final MultifactorAuthenticationProviderSelector selector,
50
                                                                        final CasConfigurationProperties casProperties) {
51
        super(authenticationSystemSupport, centralAuthenticationService, servicesManager,
52
                ticketRegistrySupport, warnCookieGenerator, authenticationStrategies, selector);
53
        mfaRequestParameter = casProperties.getAuthn().getMfa().getRequestParameter();
54
    }
55
56
    @Override
57
    public Set<Event> resolveInternal(final RequestContext context) {
58
        final RegisteredService service = resolveRegisteredServiceInRequestContext(context);
59
        final Authentication authentication = WebUtils.getAuthentication(context);
60
61
        if (service == null || authentication == null) {
62
            LOGGER.debug("No service or authentication is available to determine event for principal");
63
            return null;
64
        }
65
        if (StringUtils.isBlank(mfaRequestParameter)) {
66
            LOGGER.debug("No request parameter is defined to trigger multifactor authentication.");
67
            return null;
68
        }
69
        
70
        final HttpServletRequest request = WebUtils.getHttpServletRequestFromExternalWebflowContext(context);
71
        final String[] values = request.getParameterValues(mfaRequestParameter);
72
        if (values != null && values.length > 0) {
73
            LOGGER.debug("Received request parameter [{}] as [{}]", mfaRequestParameter, values);
74
75
            final Map<String, MultifactorAuthenticationProvider> providerMap =
76
                    MultifactorAuthenticationUtils.getAvailableMultifactorAuthenticationProviders(this.applicationContext);
77
            if (providerMap == null || providerMap.isEmpty()) {
78
                LOGGER.error("No multifactor authentication providers are available in the application context to satisfy [{}]", (Object[]) values);
79
                throw new AuthenticationException();
80
            }
81
82
            final Optional<MultifactorAuthenticationProvider> providerFound = resolveProvider(providerMap, values[0]);
83
            if (providerFound.isPresent()) {
84
                final MultifactorAuthenticationProvider provider = providerFound.get();
85
                if (provider.isAvailable(service)) {
86
                    LOGGER.debug("Attempting to build an event based on the authentication provider [{}] and service [{}]", provider, service.getName());
87
                    final Event event = validateEventIdForMatchingTransitionInContext(provider.getId(), context,
88
                            buildEventAttributeMap(authentication.getPrincipal(), service, provider));
89
                    return CollectionUtils.wrapSet(event);
90
                }
91
                LOGGER.warn("Located multifactor provider [{}], yet the provider cannot be reached or verified", providerFound.get());
92
                return null;
93
            }
94
            LOGGER.warn("No multifactor provider could be found for request parameter [{}]", (Object[]) values);
95
            throw new AuthenticationException();
96
        }
97
        LOGGER.debug("No value could be found for request parameter [{}]", mfaRequestParameter);
98
        return null;
99
    }
100
101
    @Audit(action = "AUTHENTICATION_EVENT",
102
            actionResolverName = "AUTHENTICATION_EVENT_ACTION_RESOLVER",
103
            resourceResolverName = "AUTHENTICATION_EVENT_RESOURCE_RESOLVER")
104
    @Override
105
    public Event resolveSingle(final RequestContext context) {
106
        return super.resolveSingle(context);
107
    }
108
}
109