1 package com.atlassian.asap.core.server.filter;
2
3 import com.atlassian.asap.api.server.http.RequestAuthenticator;
4 import com.atlassian.asap.core.server.AuthenticationContext;
5 import com.atlassian.asap.core.server.http.RequestAuthenticatorFactory;
6 import org.apache.commons.lang3.StringUtils;
7 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
8 import org.springframework.web.context.WebApplicationContext;
9 import org.springframework.web.context.support.WebApplicationContextUtils;
10
11 import javax.servlet.FilterConfig;
12 import java.util.Optional;
13 import java.util.function.Supplier;
14
15
16 class SpringRequestAuthenticatorSupplier implements Supplier<RequestAuthenticator> {
17 public static final String SPRING_CONTEXT_NAME_INIT_PARAM_KEY = "springContextName";
18
19 private final WebApplicationContext springContext;
20
21 SpringRequestAuthenticatorSupplier(FilterConfig filterConfig) {
22 springContext = WebApplicationContextUtils.getWebApplicationContext(filterConfig.getServletContext(), getAttributeName(filterConfig));
23 }
24
25 private String getAttributeName(FilterConfig filterConfig) {
26 return StringUtils.defaultIfBlank(filterConfig.getInitParameter(SPRING_CONTEXT_NAME_INIT_PARAM_KEY),
27 WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
28 }
29
30 @Override
31 public RequestAuthenticator get() {
32 AuthenticationContext authContext = getAuthenticationContext();
33
34 return getRequestAuthenticatorFactory().create(authContext);
35 }
36
37 private RequestAuthenticatorFactory getRequestAuthenticatorFactory() {
38 return getBeanForClass(RequestAuthenticatorFactory.class).orElse(new RequestAuthenticatorFactory());
39 }
40
41 private AuthenticationContext getAuthenticationContext() {
42 return getBeanForClass(AuthenticationContext.class)
43 .orElseThrow(() -> new IllegalStateException(
44 "Unable to find unique bean of type " + AuthenticationContext.class.getName() + " " +
45 "in your Spring configuration"
46 ));
47 }
48
49 private <T> Optional<T> getBeanForClass(Class<T> klass) {
50 try {
51 T bean = cast(springContext.getBean(klass));
52 return Optional.of(bean);
53 } catch (NoSuchBeanDefinitionException ex) {
54 return Optional.empty();
55 }
56 }
57
58 @SuppressWarnings("unchecked")
59 private <T> T cast(Object obj) {
60 return (T) obj;
61 }
62 }