resolveInternal(RequestContext)   F
last analyzed

Complexity

Conditions 10

Size

Total Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 48
c 0
b 0
f 0
cc 10
rs 3.6

How to fix   Complexity   

Complexity

Complex classes like org.apereo.cas.oidc.web.flow.OidcAuthenticationContextWebflowEventEventResolver.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.oidc.web.flow;
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.services.MultifactorAuthenticationProvider;
11
import org.apereo.cas.services.MultifactorAuthenticationProviderSelector;
12
import org.apereo.cas.services.RegisteredService;
13
import org.apereo.cas.services.ServicesManager;
14
import org.apereo.cas.support.oauth.OAuth20Constants;
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.jasig.cas.client.util.URIBuilder;
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.Collection;
28
import java.util.Map;
29
import java.util.Optional;
30
import java.util.Set;
31
32
/**
33
 * This is {@link OidcAuthenticationContextWebflowEventEventResolver}.
34
 *
35
 * @author Misagh Moayyed
36
 * @since 5.0.0
37
 */
38
public class OidcAuthenticationContextWebflowEventEventResolver extends BaseMultifactorAuthenticationProviderEventResolver {
39
    private static final Logger LOGGER = LoggerFactory.getLogger(OidcAuthenticationContextWebflowEventEventResolver.class);
40
    
41
    public OidcAuthenticationContextWebflowEventEventResolver(final AuthenticationSystemSupport authenticationSystemSupport,
42
                                                              final CentralAuthenticationService centralAuthenticationService,
43
                                                              final ServicesManager servicesManager,
44
                                                              final TicketRegistrySupport ticketRegistrySupport,
45
                                                              final CookieGenerator warnCookieGenerator,
46
                                                              final AuthenticationServiceSelectionPlan authenticationSelectionStrategies,
47
                                                              final MultifactorAuthenticationProviderSelector selector) {
48
        super(authenticationSystemSupport, centralAuthenticationService, servicesManager,
49
                ticketRegistrySupport, warnCookieGenerator,
50
                authenticationSelectionStrategies, selector);
51
    }
52
53
    @Override
54
    public Set<Event> resolveInternal(final RequestContext context) {
55
        final RegisteredService service = resolveRegisteredServiceInRequestContext(context);
56
        final Authentication authentication = WebUtils.getAuthentication(context);
57
        final HttpServletRequest request = WebUtils.getHttpServletRequestFromExternalWebflowContext(context);
58
59
        if (service == null || authentication == null) {
60
            LOGGER.debug("No service or authentication is available to determine event for principal");
61
            return null;
62
        }
63
64
        String acr = request.getParameter(OAuth20Constants.ACR_VALUES);
65
        if (StringUtils.isBlank(acr)) {
66
            final URIBuilder builderContext = new URIBuilder(StringUtils.trimToEmpty(context.getFlowExecutionUrl()));
67
            final Optional<URIBuilder.BasicNameValuePair> parameter = builderContext.getQueryParams()
68
                    .stream().filter(p -> p.getName().equals(OAuth20Constants.ACR_VALUES))
69
                    .findFirst();
70
            if (parameter.isPresent()) {
71
                acr = parameter.get().getValue();
72
            }
73
        }
74
        if (StringUtils.isBlank(acr)) {
75
            LOGGER.debug("No ACR provided in the authentication request");
76
            return null;
77
        }
78
        final Set<String> values = org.springframework.util.StringUtils.commaDelimitedListToSet(acr);
79
        if (values.isEmpty()) {
80
            LOGGER.debug("No ACR provided in the authentication request");
81
            return null;
82
        }
83
84
        final Map<String, MultifactorAuthenticationProvider> providerMap =
85
                MultifactorAuthenticationUtils.getAvailableMultifactorAuthenticationProviders(this.applicationContext);
86
        if (providerMap == null || providerMap.isEmpty()) {
87
            LOGGER.error("No multifactor authentication providers are available in the application context to handle [{}]", values);
88
            throw new AuthenticationException();
89
        }
90
91
        final Collection<MultifactorAuthenticationProvider> flattenedProviders = flattenProviders(providerMap.values());
92
        final Optional<MultifactorAuthenticationProvider> provider = flattenedProviders
93
                .stream()
94
                .filter(v -> values.contains(v.getId()))
95
                .findAny();
96
97
        if (provider.isPresent()) {
98
            return CollectionUtils.wrapSet(new Event(this, provider.get().getId()));
99
        }
100
        LOGGER.warn("The requested authentication class [{}] cannot be satisfied by any of the MFA providers available", values);
101
        throw new AuthenticationException();
102
    }
103
}
104