001: /****************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one *
003: * or more contributor license agreements. See the NOTICE file *
004: * distributed with this work for additional information *
005: * regarding copyright ownership. The ASF licenses this file *
006: * to you under the Apache License, Version 2.0 (the *
007: * "License"); you may not use this file except in compliance *
008: * with the License. You may obtain a copy of the License at *
009: * *
010: * http://www.apache.org/licenses/LICENSE-2.0 *
011: * *
012: * Unless required by applicable law or agreed to in writing, *
013: * software distributed under the License is distributed on an *
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
015: * KIND, either express or implied. See the License for the *
016: * specific language governing permissions and limitations *
017: * under the License. *
018: ****************************************************************/package org.apache.james.userrepository;
019:
020: import org.apache.avalon.cornerstone.services.store.ObjectRepository;
021: import org.apache.avalon.cornerstone.services.store.Store;
022: import org.apache.avalon.framework.activity.Initializable;
023: import org.apache.avalon.framework.configuration.Configurable;
024: import org.apache.avalon.framework.configuration.Configuration;
025: import org.apache.avalon.framework.configuration.ConfigurationException;
026: import org.apache.avalon.framework.configuration.DefaultConfiguration;
027: import org.apache.avalon.framework.logger.AbstractLogEnabled;
028: import org.apache.avalon.framework.service.ServiceException;
029: import org.apache.avalon.framework.service.ServiceManager;
030: import org.apache.avalon.framework.service.Serviceable;
031: import org.apache.james.services.User;
032: import org.apache.james.services.UsersRepository;
033:
034: import java.io.File;
035: import java.util.Iterator;
036:
037: /**
038: * Implementation of a Repository to store users on the File System.
039: *
040: * Requires a configuration element in the .conf.xml file of the form:
041: * <repository destinationURL="file://path-to-root-dir-for-repository"
042: * type="USERS"
043: * model="SYNCHRONOUS"/>
044: * Requires a logger called UsersRepository.
045: *
046: *
047: * @version CVS $Revision: 494012 $
048: *
049: */
050: public class UsersFileRepository extends AbstractLogEnabled implements
051: UsersRepository, Configurable, Serviceable, Initializable {
052:
053: /**
054: * Whether 'deep debugging' is turned on.
055: */
056: protected static boolean DEEP_DEBUG = false;
057:
058: private Store store;
059: private ObjectRepository or;
060:
061: /**
062: * The destination URL used to define the repository.
063: */
064: private String destination;
065:
066: /**
067: * @see org.apache.avalon.framework.service.Serviceable#service(ServiceManager)
068: */
069: public void service(final ServiceManager componentManager)
070: throws ServiceException {
071:
072: try {
073: store = (Store) componentManager.lookup(Store.ROLE);
074: } catch (Exception e) {
075: final String message = "Failed to retrieve Store component:"
076: + e.getMessage();
077: getLogger().error(message, e);
078: throw new ServiceException("", message, e);
079: }
080: }
081:
082: /**
083: * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
084: */
085: public void configure(final Configuration configuration)
086: throws ConfigurationException {
087:
088: destination = configuration.getChild("destination")
089: .getAttribute("URL");
090:
091: if (!destination.endsWith(File.separator)) {
092: destination += File.separator;
093: }
094: }
095:
096: /**
097: * @see org.apache.avalon.framework.activity.Initializable#initialize()
098: */
099: public void initialize() throws Exception {
100:
101: try {
102: //prepare Configurations for object and stream repositories
103: final DefaultConfiguration objectConfiguration = new DefaultConfiguration(
104: "repository",
105: "generated:UsersFileRepository.compose()");
106:
107: objectConfiguration.setAttribute("destinationURL",
108: destination);
109: objectConfiguration.setAttribute("type", "OBJECT");
110: objectConfiguration.setAttribute("model", "SYNCHRONOUS");
111:
112: or = (ObjectRepository) store.select(objectConfiguration);
113: if (getLogger().isDebugEnabled()) {
114: StringBuffer logBuffer = new StringBuffer(192).append(
115: this .getClass().getName()).append(
116: " created in ").append(destination);
117: getLogger().debug(logBuffer.toString());
118: }
119: } catch (Exception e) {
120: if (getLogger().isErrorEnabled()) {
121: getLogger().error(
122: "Failed to initialize repository:"
123: + e.getMessage(), e);
124: }
125: throw e;
126: }
127: }
128:
129: /**
130: * List users in repository.
131: *
132: * @return Iterator over a collection of Strings, each being one user in the repository.
133: */
134: public Iterator list() {
135: return or.list();
136: }
137:
138: /**
139: * Update the repository with the specified user object. A user object
140: * with this username must already exist.
141: *
142: * @param user the user to be added.
143: *
144: * @return true if successful.
145: */
146: public synchronized boolean addUser(User user) {
147: String username = user.getUserName();
148: if (contains(username)) {
149: return false;
150: }
151: try {
152: or.put(username, user);
153: } catch (Exception e) {
154: throw new RuntimeException(
155: "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: } else {
166: throw new RuntimeException(
167: "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(
184: "Exception while retrieving user: "
185: + e.getMessage());
186: }
187: } else {
188: return null;
189: }
190: }
191:
192: public User getUserByNameCaseInsensitive(String name) {
193: String realName = getRealName(name);
194: if (realName == null) {
195: return null;
196: }
197: return getUserByName(realName);
198: }
199:
200: public String getRealName(String name) {
201: Iterator it = list();
202: while (it.hasNext()) {
203: String temp = (String) it.next();
204: if (name.equalsIgnoreCase(temp)) {
205: return temp;
206: }
207: }
208: return null;
209: }
210:
211: public boolean updateUser(User user) {
212: String username = user.getUserName();
213: if (!contains(username)) {
214: return false;
215: }
216: try {
217: or.put(username, user);
218: } catch (Exception e) {
219: throw new RuntimeException(
220: "Exception caught while storing user: " + e);
221: }
222: return true;
223: }
224:
225: public synchronized void removeUser(String name) {
226: or.remove(name);
227: }
228:
229: public boolean contains(String name) {
230: return or.containsKey(name);
231: }
232:
233: public boolean containsCaseInsensitive(String name) {
234: Iterator it = list();
235: while (it.hasNext()) {
236: if (name.equalsIgnoreCase((String) it.next())) {
237: return true;
238: }
239: }
240: return false;
241: }
242:
243: public boolean test(String name, String password) {
244: User user;
245: try {
246: if (contains(name)) {
247: user = (User) or.get(name);
248: } else {
249: return false;
250: }
251: } catch (Exception e) {
252: throw new RuntimeException("Exception retrieving User" + e);
253: }
254: return user.verifyPassword(password);
255: }
256:
257: public int countUsers() {
258: int count = 0;
259: for (Iterator it = list(); it.hasNext(); it.next()) {
260: count++;
261: }
262: return count;
263: }
264:
265: }
|