View Javadoc

1   /************************************************************************
2    * Copyright (c) 2000-2006 The Apache Software Foundation.             *
3    * All rights reserved.                                                *
4    * ------------------------------------------------------------------- *
5    * Licensed under the Apache License, Version 2.0 (the "License"); you *
6    * may not use this file except in compliance with the License. You    *
7    * may obtain a copy of the License at:                                *
8    *                                                                     *
9    *     http://www.apache.org/licenses/LICENSE-2.0                      *
10   *                                                                     *
11   * Unless required by applicable law or agreed to in writing, software *
12   * distributed under the License is distributed on an "AS IS" BASIS,   *
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or     *
14   * implied.  See the License for the specific language governing       *
15   * permissions and limitations under the License.                      *
16   ***********************************************************************/
17  
18  package org.apache.james.userrepository;
19  
20  import org.apache.avalon.cornerstone.services.store.ObjectRepository;
21  import org.apache.avalon.cornerstone.services.store.Store;
22  import org.apache.avalon.framework.activity.Initializable;
23  import org.apache.avalon.framework.configuration.Configurable;
24  import org.apache.avalon.framework.configuration.Configuration;
25  import org.apache.avalon.framework.configuration.ConfigurationException;
26  import org.apache.avalon.framework.configuration.DefaultConfiguration;
27  import org.apache.avalon.framework.logger.AbstractLogEnabled;
28  import org.apache.avalon.framework.service.ServiceException;
29  import org.apache.avalon.framework.service.ServiceManager;
30  import org.apache.avalon.framework.service.Serviceable;
31  import org.apache.james.services.User;
32  import org.apache.james.services.UsersRepository;
33  
34  import java.io.File;
35  import java.util.Iterator;
36  
37  /***
38   * Implementation of a Repository to store users on the File System.
39   *
40   * Requires a configuration element in the .conf.xml file of the form:
41   *  <repository destinationURL="file://path-to-root-dir-for-repository"
42   *              type="USERS"
43   *              model="SYNCHRONOUS"/>
44   * Requires a logger called UsersRepository.
45   *
46   *
47   * @version CVS $Revision: 407988 $
48   *
49   */
50  public class UsersFileRepository
51      extends AbstractLogEnabled
52      implements UsersRepository, Configurable, Serviceable, Initializable {
53   
54      /***
55       * Whether 'deep debugging' is turned on.
56       */
57      protected static boolean DEEP_DEBUG = false;
58  
59      private Store store;
60      private ObjectRepository or;
61  
62      /***
63       * The destination URL used to define the repository.
64       */
65      private String destination;
66  
67      /***
68       * @see org.apache.avalon.framework.service.Serviceable#service(ServiceManager)
69       */
70      public void service( final ServiceManager componentManager )
71          throws ServiceException {
72  
73          try {
74              store = (Store)componentManager.lookup( Store.ROLE );
75          } catch (Exception e) {
76              final String message = "Failed to retrieve Store component:" + e.getMessage();
77              getLogger().error( message, e );
78              throw new ServiceException ("", message, e );
79          }
80      }
81  
82      /***
83       * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
84       */
85      public void configure( final Configuration configuration )
86          throws ConfigurationException {
87  
88          destination = configuration.getChild( "destination" ).getAttribute( "URL" );
89  
90          if (!destination.endsWith(File.separator)) {
91              destination += File.separator;
92          }
93      }
94  
95      /***
96       * @see org.apache.avalon.framework.activity.Initializable#initialize()
97       */
98      public void initialize()
99          throws Exception {
100 
101         try {
102             //prepare Configurations for object and stream repositories
103             final DefaultConfiguration objectConfiguration
104                 = new DefaultConfiguration( "repository",
105                                             "generated:UsersFileRepository.compose()" );
106 
107             objectConfiguration.setAttribute( "destinationURL", destination );
108             objectConfiguration.setAttribute( "type", "OBJECT" );
109             objectConfiguration.setAttribute( "model", "SYNCHRONOUS" );
110 
111             or = (ObjectRepository)store.select( objectConfiguration );
112             if (getLogger().isDebugEnabled()) {
113                 StringBuffer logBuffer =
114                     new StringBuffer(192)
115                             .append(this.getClass().getName())
116                             .append(" created in ")
117                             .append(destination);
118                 getLogger().debug(logBuffer.toString());
119             }
120         } catch (Exception e) {
121             if (getLogger().isErrorEnabled()) {
122                 getLogger().error("Failed to initialize repository:" + e.getMessage(), e );
123             }
124             throw e;
125         }
126     }
127 
128     /***
129      * List users in repository.
130      *
131      * @return Iterator over a collection of Strings, each being one user in the repository.
132      */
133     public Iterator list() {
134         return or.list();
135     }
136 
137     /***
138      * Update the repository with the specified user object. A user object
139      * with this username must already exist.
140      *
141      * @param user the user to be added.
142      *
143      * @return true if successful.
144      */
145     public synchronized boolean addUser(User user) {
146         String username = user.getUserName();
147         if (contains(username)) {
148             return false;
149         }
150         try {
151             or.put(username, user);
152         } catch (Exception e) {
153             throw new RuntimeException("Exception caught while storing user: " + e );
154         }
155         return true;
156     }
157 
158     public void addUser(String name, Object attributes) {
159         if (attributes instanceof String) {
160             User newbie = new DefaultUser(name, "SHA");
161             newbie.setPassword( (String) attributes);
162             addUser(newbie);
163         }
164         else {
165             throw new RuntimeException("Improper use of deprecated method"
166                                        + " - use addUser(User user)");
167         }
168     }
169 
170     public boolean addUser(String username, String password) {
171         User newbie = new DefaultJamesUser(username, "SHA");
172         newbie.setPassword(password);
173         return addUser(newbie);
174     }
175 
176     public synchronized User getUserByName(String name) {
177         if (contains(name)) {
178             try {
179                 return (User)or.get(name);
180             } catch (Exception e) {
181                 throw new RuntimeException("Exception while retrieving user: "
182                                            + e.getMessage());
183             }
184         } else {
185             return null;
186         }
187     }
188 
189     public User getUserByNameCaseInsensitive(String name) {
190         String realName = getRealName(name);
191         if (realName == null ) {
192             return null;
193         }
194         return getUserByName(realName);
195     }
196 
197     public String getRealName(String name) {
198         Iterator it = list();
199         while (it.hasNext()) {
200             String temp = (String) it.next();
201             if (name.equalsIgnoreCase(temp)) {
202                 return temp;
203             }
204         }
205         return null;
206     }
207 
208     public boolean updateUser(User user) {
209         String username = user.getUserName();
210         if (!contains(username)) {
211             return false;
212         }
213         try {
214             or.put(username, user);
215         } catch (Exception e) {
216             throw new RuntimeException("Exception caught while storing user: " + e );
217         }
218         return true;
219     }
220 
221     public synchronized void removeUser(String name) {
222         or.remove(name);
223     }
224 
225     public boolean contains(String name) {
226         return or.containsKey(name);
227     }
228 
229     public boolean containsCaseInsensitive(String name) {
230         Iterator it = list();
231         while (it.hasNext()) {
232             if (name.equalsIgnoreCase((String)it.next())) {
233                 return true;
234             }
235         }
236         return false;
237     }
238 
239     public boolean test(String name, String password) {
240         User user;
241         try {
242             if (contains(name)) {
243                 user = (User) or.get(name);
244             } else {
245                return false;
246             }
247         } catch (Exception e) {
248             throw new RuntimeException("Exception retrieving User" + e);
249         }
250         return user.verifyPassword(password);
251     }
252 
253     public int countUsers() {
254         int count = 0;
255         for (Iterator it = list(); it.hasNext(); it.next()) {
256             count++;
257         }
258         return count;
259     }
260 
261 }