View Javadoc

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