Drop explicit jetty-servlets dependency
[aaa.git] / aaa-shiro / impl / src / main / java / org / opendaylight / aaa / shiro / AAAShiroProvider.java
1 /*
2  * Copyright © 2017 Brocade Communications Systems and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.aaa.shiro;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.collect.Lists;
12 import java.util.List;
13 import javax.servlet.ServletException;
14 import org.opendaylight.aaa.api.AuthenticationService;
15 import org.opendaylight.aaa.api.CredentialAuth;
16 import org.opendaylight.aaa.api.IDMStoreException;
17 import org.opendaylight.aaa.api.IIDMStore;
18 import org.opendaylight.aaa.api.IdMService;
19 import org.opendaylight.aaa.api.IdMServiceImpl;
20 import org.opendaylight.aaa.api.PasswordCredentials;
21 import org.opendaylight.aaa.api.StoreBuilder;
22 import org.opendaylight.aaa.api.TokenAuth;
23 import org.opendaylight.aaa.api.TokenStore;
24 import org.opendaylight.aaa.cert.api.ICertificateManager;
25 import org.opendaylight.aaa.datastore.h2.H2Store;
26 import org.opendaylight.aaa.datastore.h2.H2TokenStore;
27 import org.opendaylight.aaa.datastore.h2.IdmLightConfig;
28 import org.opendaylight.aaa.datastore.h2.IdmLightConfigBuilder;
29 import org.opendaylight.aaa.datastore.h2.IdmLightSimpleConnectionProvider;
30 import org.opendaylight.aaa.shiro.oauth2.OAuth2TokenServlet;
31 import org.opendaylight.aaa.shiro.tokenauthrealm.ServiceLocator;
32 import org.opendaylight.aaa.shiro.tokenauthrealm.auth.AuthenticationManager;
33 import org.opendaylight.aaa.shiro.tokenauthrealm.auth.HttpBasicAuth;
34 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.aaa.app.config.rev170619.DatastoreConfig;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.aaa.app.config.rev170619.ShiroConfiguration;
37 import org.osgi.service.http.HttpService;
38 import org.osgi.service.http.NamespaceException;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42 /**
43  * Provider for AAA shiro implementation.
44  */
45 public class AAAShiroProvider {
46
47     private static final Logger LOG = LoggerFactory.getLogger(AAAShiroProvider.class);
48
49     private static volatile AAAShiroProvider INSTANCE;
50     private static IIDMStore iidmStore;
51
52     private final DataBroker dataBroker;
53     private final ICertificateManager certificateManager;
54     private final HttpService httpService;
55     private final ShiroConfiguration shiroConfiguration;
56     private final String moonEndpointPath;
57     private final String oauth2EndpointPath;
58     private final TokenStore tokenStore;
59
60     /**
61      * Provider for this bundle.
62      *
63      * @param dataBroker injected from blueprint
64      */
65     private AAAShiroProvider(final DataBroker dataBroker, final ICertificateManager certificateManager,
66                              final CredentialAuth<PasswordCredentials> credentialAuth,
67                              final ShiroConfiguration shiroConfiguration,
68                              final HttpService httpService,
69                              final String moonEndpointPath,
70                              final String oauth2EndpointPath,
71                              final DatastoreConfig datastoreConfig,
72                              final String dbUsername,
73                              final String dbPassword) {
74         this.dataBroker = dataBroker;
75         this.certificateManager = certificateManager;
76         this.shiroConfiguration = shiroConfiguration;
77         this.httpService = httpService;
78         this.moonEndpointPath = moonEndpointPath;
79         this.oauth2EndpointPath = oauth2EndpointPath;
80
81         if (datastoreConfig != null && datastoreConfig.getStore()
82                 .equals(DatastoreConfig.Store.H2DataStore)) {
83             final IdmLightConfig config = new IdmLightConfigBuilder()
84                     .dbUser(dbUsername).dbPwd(dbPassword).build();
85             iidmStore = new H2Store(new IdmLightSimpleConnectionProvider(config));
86             tokenStore = new H2TokenStore(datastoreConfig.getTimeToLive().longValue(),
87                     datastoreConfig.getTimeToWait().longValue());
88         } else {
89             iidmStore = null;
90             tokenStore = null;
91             LOG.info("AAA Datastore has not been initialized");
92             return;
93         }
94         this.initializeServices(credentialAuth, iidmStore, tokenStore);
95         try {
96             this.registerServletContexts(this.httpService, this.moonEndpointPath, this.oauth2EndpointPath);
97         } catch (final ServletException | NamespaceException e) {
98             LOG.warn("Could not initialize AAA servlet endpoints", e);
99         }
100     }
101
102     private void registerServletContexts(final HttpService httpService, final String moonEndpointPath,
103                                          final String oauth2EndpointPath)
104             throws ServletException, NamespaceException {
105         LOG.info("attempting registration of AAA moon, oauth2 and auth servlets");
106
107         Preconditions.checkNotNull(httpService, "httpService cannot be null");
108         httpService.registerServlet(moonEndpointPath, new org.opendaylight.aaa.shiro.moon.MoonTokenEndpoint(),
109                 null, null);
110         httpService.registerServlet(oauth2EndpointPath, new OAuth2TokenServlet(), null, null);
111     }
112
113     /**
114      * Initialize AAA Services.  This method will evolve over time as ServiceLocator is refactored/removed.
115      *
116      * @param credentialAuth wired via blueprint
117      * @param iidmStore wired via blueprint
118      * @param tokenStore wired via blueprint
119      */
120     private void initializeServices(final CredentialAuth<PasswordCredentials> credentialAuth,
121                                     final IIDMStore iidmStore, final TokenStore tokenStore) {
122         try {
123             new StoreBuilder(iidmStore).init();
124         } catch (final IDMStoreException e) {
125             LOG.error("Failed to initialize data in store", e);
126         }
127
128         final AuthenticationService authService = new AuthenticationManager();
129         ServiceLocator.getInstance().setAuthenticationService(authService);
130
131         final IdMService idmService = new IdMServiceImpl(iidmStore);
132         ServiceLocator.getInstance().setIdmService(idmService);
133
134         ServiceLocator.getInstance().setCredentialAuth(credentialAuth);
135
136         final TokenAuth tokenAuth = new HttpBasicAuth();
137         final List<TokenAuth> tokenAuthList = Lists.newArrayList(tokenAuth);
138         ServiceLocator.getInstance().setTokenAuthCollection(tokenAuthList);
139
140         ServiceLocator.getInstance().setTokenStore(tokenStore);
141     }
142
143     /**
144      * Singleton creation.
145      *
146      * @param dataBroker The DataBroker
147      * @param certificateManager the certificate manager
148      * @param credentialAuth The CredentialAuth
149      * @param shiroConfiguration shiro config
150      * @param httpService http service
151      * @param moonEndpointPath moon path
152      * @param oauth2EndpointPath oauth path
153      * @param datastoreConfig data store config
154      * @return the Provider
155      */
156     public static AAAShiroProvider newInstance(final DataBroker dataBroker,
157                                                final ICertificateManager certificateManager,
158                                                final CredentialAuth<PasswordCredentials> credentialAuth,
159                                                final ShiroConfiguration shiroConfiguration,
160                                                final HttpService httpService,
161                                                final String moonEndpointPath,
162                                                final String oauth2EndpointPath,
163                                                final DatastoreConfig datastoreConfig,
164                                                final String dbUsername,
165                                                final String dbPassword) {
166         INSTANCE = new AAAShiroProvider(dataBroker, certificateManager, credentialAuth, shiroConfiguration,
167                 httpService, moonEndpointPath, oauth2EndpointPath, datastoreConfig, dbUsername, dbPassword);
168         return INSTANCE;
169     }
170
171     /**
172      * Singleton extraction.
173      *
174      * @return the Provider
175      */
176     public static AAAShiroProvider getInstance() {
177         return INSTANCE;
178     }
179
180     /**
181      * Get IDM data store.
182      *
183      * @return IIDMStore data store
184      */
185     public static IIDMStore getIdmStore() {
186         return iidmStore;
187     }
188
189     /**
190      * Set IDM data store, only used for test.
191      *
192      * @param store data store
193      */
194     public static void setIdmStore(IIDMStore store) {
195         iidmStore = store;
196     }
197
198     /**
199      * Method called when the blueprint container is created.
200      */
201     public void init() {
202         LOG.info("AAAShiroProvider Session Initiated");
203     }
204
205     /**
206      * Method called when the blueprint container is destroyed.
207      */
208     public void close() {
209         LOG.info("AAAShiroProvider Closed");
210         if (httpService != null) {
211             httpService.unregister(moonEndpointPath);
212             httpService.unregister(oauth2EndpointPath);
213         }
214     }
215
216     /**
217      * Extract the data broker.
218      *
219      * @return the data broker
220      */
221     public DataBroker getDataBroker() {
222         return this.dataBroker;
223     }
224
225     /**
226      * Extract the certificate manager.
227      *
228      * @return the certificate manager.
229      */
230     public ICertificateManager getCertificateManager() {
231         return certificateManager;
232     }
233
234     /**
235      * Extract Shiro related configuration.
236      *
237      * @return Shiro related configuration.
238      */
239     public ShiroConfiguration getShiroConfiguration() {
240         return this.shiroConfiguration;
241     }
242 }