View Javadoc

1   /**
2    * Copyright (C) 2005-2009 Alfresco Software Limited.
3    *
4    * This file is part of the Spring Surf Extension project.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * 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, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.springframework.extensions.config;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.io.Serializable;
24  import java.security.GeneralSecurityException;
25  import java.security.KeyStore;
26  import java.util.HashMap;
27  import java.util.List;
28  
29  import javax.net.ssl.KeyManagerFactory;
30  
31  import org.apache.abdera.protocol.client.util.ClientAuthSSLProtocolSocketFactory;
32  import org.apache.commons.httpclient.protocol.Protocol;
33  import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
34  import org.dom4j.Element;
35  import org.springframework.extensions.config.element.ConfigElementAdapter;
36  import org.springframework.extensions.surf.exception.PlatformRuntimeException;
37  
38  /**
39   * Describes the connection, authentication and endpoint properties stored
40   * within the <remote> block of the current configuration.  This block
41   * provides settings for creating and working with remote services.
42   * 
43   * @author muzquiano
44   */
45  public class RemoteConfigElement extends ConfigElementAdapter implements RemoteConfigProperties
46  {
47      private static final String REMOTE_KEYSTORE = "keystore";  
48      private static final String REMOTE_ENDPOINT = "endpoint";
49      private static final String REMOTE_AUTHENTICATOR = "authenticator";
50      private static final String REMOTE_CONNECTOR = "connector";
51      private static final String CONFIG_ELEMENT_ID = "remote";
52  
53      protected KeyStoreDescriptor keyStoreDescriptor;
54      protected HashMap<String, ConnectorDescriptor> connectors = null;
55      protected HashMap<String, AuthenticatorDescriptor> authenticators = null;
56      protected HashMap<String, EndpointDescriptor> endpoints = null;
57  
58      protected String defaultEndpointId;
59      protected String defaultCredentialVaultProviderId;
60  
61      /**
62       * Constructs a new Remote Config Element
63       */
64      public RemoteConfigElement()
65      {
66          super(CONFIG_ELEMENT_ID);
67  
68          connectors = new HashMap<String, ConnectorDescriptor>(10);
69          authenticators = new HashMap<String, AuthenticatorDescriptor>(10);
70          endpoints = new HashMap<String, EndpointDescriptor>(10);
71      }
72  
73      /* (non-Javadoc)
74       * @see org.springframework.extensions.surf.config.element.ConfigElementAdapter#combine(org.springframework.extensions.surf.config.ConfigElement)
75       */
76      public ConfigElement combine(ConfigElement element)
77      {
78          RemoteConfigElement configElement = (RemoteConfigElement) element;
79  
80          // new combined element
81          RemoteConfigElement combinedElement = new RemoteConfigElement();
82  
83          // copy in our things
84          combinedElement.connectors.putAll(this.connectors);
85          combinedElement.authenticators.putAll(this.authenticators);
86          combinedElement.endpoints.putAll(this.endpoints);
87  
88          // override with things from the merging object
89          combinedElement.connectors.putAll(configElement.connectors);
90          combinedElement.authenticators.putAll(configElement.authenticators);
91          combinedElement.endpoints.putAll(configElement.endpoints);
92          
93          // SSL KeyStore configuration
94          combinedElement.keyStoreDescriptor = this.keyStoreDescriptor;
95          if(configElement.keyStoreDescriptor != null)
96          {
97             combinedElement.keyStoreDescriptor = configElement.keyStoreDescriptor;
98          }
99          
100         // default endpoint id
101         combinedElement.defaultEndpointId = this.defaultEndpointId;
102         if(configElement.defaultEndpointId != null)
103         {
104             combinedElement.defaultEndpointId = configElement.defaultEndpointId;
105         }
106 
107         // default credential vault provider id
108         combinedElement.defaultCredentialVaultProviderId = this.defaultCredentialVaultProviderId;
109         if(configElement.defaultCredentialVaultProviderId != null)
110         {
111             combinedElement.defaultCredentialVaultProviderId = configElement.defaultCredentialVaultProviderId;
112         }
113 
114         // return the combined element
115         return combinedElement;
116     }
117 
118     // remote connectors
119     public String[] getConnectorIds()
120     {
121         return this.connectors.keySet().toArray(new String[this.connectors.size()]);
122     }
123 
124     public ConnectorDescriptor getConnectorDescriptor(String id)
125     {
126         return (ConnectorDescriptor) this.connectors.get(id);
127     }
128 
129     // remote authenticators
130     public String[] getAuthenticatorIds()
131     {
132         return this.authenticators.keySet().toArray(new String[this.authenticators.size()]);
133     }
134 
135     public AuthenticatorDescriptor getAuthenticatorDescriptor(String id)
136     {
137         return (AuthenticatorDescriptor) this.authenticators.get(id);
138     }
139 
140     // remote endpoints
141     public String[] getEndpointIds()
142     {
143         return this.endpoints.keySet().toArray(new String[this.endpoints.size()]);
144     }
145 
146     public EndpointDescriptor getEndpointDescriptor(String id)
147     {
148         return (EndpointDescriptor) this.endpoints.get(id);
149     }
150 
151     // defaults
152     public String getDefaultEndpointId()
153     {
154         if(defaultEndpointId == null)
155         {
156             return "alfresco";
157         }
158         return defaultEndpointId;
159     }
160 
161     public String getDefaultCredentialVaultProviderId()
162     {
163         if(defaultCredentialVaultProviderId == null)
164         {
165             return "credential.vault.provider";
166         }
167         return defaultCredentialVaultProviderId;
168     }
169 
170 
171     /**
172      * EndPoint Descriptor class
173      */
174     public static class Descriptor implements Serializable
175     {
176         private static final String ID = "id";
177 
178         protected HashMap<String, Object> map = new HashMap<String, Object>();
179 
180         Descriptor(Element el)
181         {
182             List elements = el.elements();
183             for(int i = 0; i < elements.size(); i++)
184             {
185                 Element element = (Element) elements.get(i);
186                 put(element);
187             }
188         }
189 
190         public void put(Element el)
191         {
192             String key = el.getName();
193             Object value = (Object) el.getTextTrim();
194             if(value != null)
195             {
196                 this.map.put(key, value);
197             }
198         }
199 
200         public Object get(String key)
201         {
202             return (Object) this.map.get(key);
203         }	
204 
205         public String getId() 
206         {
207             return (String) get(ID);
208         }		
209 
210         public Object getProperty(String key)
211         {
212             return get(key);
213         }
214 
215         public String getStringProperty(String key)
216         {
217             return (String) get(key);
218         }
219 
220         @Override
221         public String toString()
222         {
223             // TODO Auto-generated method stub
224             return map.toString();
225         }
226     }
227 
228     /**
229      * The Class KeyStoreDescriptor.
230      */
231     public static class KeyStoreDescriptor extends Descriptor
232     {
233         private static final String PATH = "path";
234         private static final String TYPE = "type";
235         private static final String PASSWORD = "password";
236 
237         /**
238          * Initializes SSL client certificate configuration, if appropriate
239          * 
240          * @param elem the element
241          */
242         KeyStoreDescriptor(Element el)
243         {
244             super(el);
245             String keyStorePath = getStringProperty(PATH);
246             InputStream keyStoreIn;
247             if (keyStorePath != null && (keyStoreIn = getClass().getResourceAsStream("/" + keyStorePath)) != null)
248             {
249                 try
250                 {
251                     KeyStore keyStore = KeyStore.getInstance(getStringProperty(TYPE));
252                     String password = getStringProperty(PASSWORD);
253                     keyStore.load(keyStoreIn, password.toCharArray());
254                     Protocol authHttps = new Protocol("https",
255                             (ProtocolSocketFactory) new ClientAuthSSLProtocolSocketFactory(keyStore, password,
256                                     "TLS", KeyManagerFactory.getDefaultAlgorithm(), null), 443);
257                     Protocol.registerProtocol("https", authHttps);
258                 }
259                 catch (GeneralSecurityException e)
260                 {
261                     throw new PlatformRuntimeException("Error loading keyStore: " + keyStorePath, e);
262                 }
263                 catch (IOException e)
264                 {
265                     throw new PlatformRuntimeException("Error loading keyStore: " + keyStorePath, e);
266                 }
267             }            
268         }
269     }
270 
271     /**
272      * The Class ConnectorDescriptor.
273      */
274     public static class ConnectorDescriptor extends Descriptor
275     {
276         private static final String CLAZZ = "class";
277         private static final String DESCRIPTION = "description";
278         private static final String NAME = "name";
279         private static final String AUTHENTICATOR_ID = "authenticator-id";
280         private static final String UNAUTHENTICATED_MODE = "unauthenticated-mode";
281 
282         /**
283          * Instantiates a new remote connector descriptor.
284          * 
285          * @param elem the elem
286          */
287         ConnectorDescriptor(Element el)
288         {
289             super(el);
290         }
291 
292         public String getImplementationClass() 
293         {
294             return getStringProperty(CLAZZ);
295         }
296         
297         public String getDescription() 
298         {
299             return getStringProperty(DESCRIPTION);
300         }
301         
302         public String getName() 
303         {
304             return getStringProperty(NAME);
305         } 
306         
307         public String getAuthenticatorId()
308         {
309             return getStringProperty(AUTHENTICATOR_ID);
310         }	    
311         
312         public String getUnauthenticatedMode()
313         {
314             return getStringProperty(UNAUTHENTICATED_MODE);
315         }
316     }
317 
318     /**
319      * The Class AuthenticatorDescriptor.
320      */
321     public static class AuthenticatorDescriptor extends Descriptor
322     {
323         private static final String CLAZZ = "class";
324         private static final String DESCRIPTION = "description";
325         private static final String NAME = "name";
326 
327         /**
328          * Instantiates a new remote authenticator descriptor.
329          * 
330          * @param elem the elem
331          */
332         AuthenticatorDescriptor(Element el)
333         {
334             super(el);
335         }
336 
337         public String getImplementationClass() 
338         {
339             return getStringProperty(CLAZZ);
340         }
341         public String getDescription() 
342         {
343             return getStringProperty(DESCRIPTION);
344         }
345         public String getName() 
346         {
347             return getStringProperty(NAME);
348         }    		    
349     }
350 
351     /**
352      * The Class EndpointDescriptor.
353      */
354     public static class EndpointDescriptor extends Descriptor
355     {    	
356         private static final String PASSWORD = "password";
357         private static final String USERNAME = "username";
358         private static final String IDENTITY = "identity";
359         private static final String ENDPOINT_URL = "endpoint-url";
360         private static final String AUTH_ID = "auth-id";
361         private static final String CONNECTOR_ID = "connector-id";
362         private static final String DESCRIPTION = "description";
363         private static final String NAME = "name";
364         private static final String UNSECURE = "unsecure";
365         private static final String PERSISTENT = "persistent";
366         private static final String BASIC_AUTH = "basic-auth";
367         private static final String EXTERNAL_AUTH = "external-auth";
368 
369         /**
370          * Instantiates a new remote endpoint descriptor.
371          * 
372          * @param elem the elem
373          */
374         EndpointDescriptor(Element el)
375         {
376             super(el);
377         }
378 
379         public String getDescription() 
380         {
381             return getStringProperty(DESCRIPTION);
382         }
383 
384         public String getName() 
385         {
386             return getStringProperty(NAME);
387         }    
388 
389         public String getConnectorId() 
390         {
391             return getStringProperty(CONNECTOR_ID);
392         }
393 
394         public String getAuthId()
395         {
396             return getStringProperty(AUTH_ID);
397         }
398 
399         public String getEndpointUrl()
400         {
401             return getStringProperty(ENDPOINT_URL);
402         }
403 
404         public IdentityType getIdentity()
405         {
406             IdentityType identityType = IdentityType.NONE;
407             String identity = getStringProperty(IDENTITY);
408             if (identity != null)
409             {
410                 identityType = IdentityType.valueOf(identity.toUpperCase());
411             }
412             return identityType;
413         }
414 
415         public String getUsername()
416         {
417             return getStringProperty(USERNAME);
418         }
419 
420         public String getPassword()
421         {
422             return getStringProperty(PASSWORD);
423         }
424         
425         public boolean getUnsecure()
426         {
427             return Boolean.parseBoolean(getStringProperty(UNSECURE));
428         }
429         
430         public boolean getPersistent()
431         {
432             return Boolean.parseBoolean(getStringProperty(PERSISTENT));
433         }
434         
435         public boolean getBasicAuth()
436         {
437             return Boolean.parseBoolean(getStringProperty(BASIC_AUTH));
438         }
439         
440         public boolean getExternalAuth()
441         {
442             return Boolean.parseBoolean(getStringProperty(EXTERNAL_AUTH));
443         }
444     }
445 
446     /**
447      * New instance.
448      * 
449      * @param elem the elem
450      * 
451      * @return the remote config element
452      */
453     protected static RemoteConfigElement newInstance(Element elem)
454     {
455         RemoteConfigElement configElement = new RemoteConfigElement();
456 
457         // connectors
458         List connectors = elem.elements(REMOTE_CONNECTOR);
459         for(int i = 0; i < connectors.size(); i++)
460         {
461             Element el = (Element) connectors.get(i);
462             ConnectorDescriptor descriptor = new ConnectorDescriptor(el);
463             configElement.connectors.put(descriptor.getId(), descriptor);
464         }
465 
466         // authenticators
467         List authenticators = elem.elements(REMOTE_AUTHENTICATOR);
468         for(int i = 0; i < authenticators.size(); i++)
469         {
470             Element el = (Element) authenticators.get(i);
471             AuthenticatorDescriptor descriptor = new AuthenticatorDescriptor(el);
472             configElement.authenticators.put(descriptor.getId(), descriptor);
473         }
474 
475         // endpoints
476         List endpoints = elem.elements(REMOTE_ENDPOINT);
477         for(int i = 0; i < endpoints.size(); i++)
478         {
479             Element el = (Element) endpoints.get(i);
480             EndpointDescriptor descriptor = new EndpointDescriptor(el);
481             configElement.endpoints.put(descriptor.getId(), descriptor);
482         }
483 
484         String _defaultEndpointId = elem.elementTextTrim("default-endpoint-id");
485         if(_defaultEndpointId != null && _defaultEndpointId.length() > 0)
486         {
487             configElement.defaultEndpointId = _defaultEndpointId;
488         }
489 
490         String _defaultCredentialVaultProviderId = elem.elementTextTrim("default-credential-vault-provider-id");
491         if(_defaultCredentialVaultProviderId != null && _defaultCredentialVaultProviderId.length() > 0)
492         {
493             configElement.defaultCredentialVaultProviderId = _defaultCredentialVaultProviderId;
494         }
495 
496         return configElement;
497     }
498     
499     
500     /**
501      * Enum describing the Identity Type for an Endpoint
502      */
503     public enum IdentityType
504     {
505         DECLARED, USER, NONE;
506     }
507 }