001: /*
002: * This file is part of DrFTPD, Distributed FTP Daemon.
003: *
004: * DrFTPD is free software; you can redistribute it and/or modify it under the
005: * terms of the GNU General Public License as published by the Free Software
006: * Foundation; either version 2 of the License, or (at your option) any later
007: * version.
008: *
009: * DrFTPD is distributed in the hope that it will be useful, but WITHOUT ANY
010: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
011: * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
012: *
013: * You should have received a copy of the GNU General Public License along with
014: * DrFTPD; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
015: * Suite 330, Boston, MA 02111-1307 USA
016: */
017: package org.drftpd.usermanager;
018:
019: import java.io.File;
020: import java.io.IOException;
021: import java.util.ArrayList;
022: import java.util.Collection;
023: import java.util.Hashtable;
024: import java.util.Iterator;
025: import java.util.Date;
026:
027: import net.sf.drftpd.DuplicateElementException;
028: import net.sf.drftpd.FileExistsException;
029:
030: import org.apache.log4j.Logger;
031: import org.drftpd.GlobalContext;
032: import org.drftpd.commands.Nuke;
033: import org.drftpd.commands.UserManagement;
034: import org.drftpd.dynamicdata.KeyNotFoundException;
035: import org.drftpd.plugins.Statistics;
036:
037: import se.mog.io.PermissionDeniedException;
038:
039: /**
040: * This is the base class of all the user manager classes. If we want to add a
041: * new user manager, we have to override this class.
042: *
043: * @author <a href="mailto:rana_b@yahoo.com">Rana Bhattacharyya </a>
044: * @version $Id: AbstractUserManager.java 1069 2005-03-01 00:49:56Z zubov $
045: */
046: public abstract class AbstractUserManager implements UserManager {
047: protected Hashtable<String, User> _users = new Hashtable<String, User>();
048: private static final Logger logger = Logger
049: .getLogger(AbstractUserManager.class);
050: private GlobalContext _gctx;
051:
052: /**
053: * For DummyUserManager, skips creation of userfile directory.
054: */
055: public AbstractUserManager() {
056: }
057:
058: /**
059: * <p>Cannot be a constructor because the child class fields don't get
060: * initialized until super (this) class gets run.</p>
061: */
062: protected void init(boolean createIfNoUser)
063: throws UserFileException {
064: if (!getUserpathFile().exists() && !getUserpathFile().mkdirs()) {
065: throw new UserFileException(new IOException(
066: "Error creating directories: " + getUserpathFile()));
067: }
068: if (createIfNoUser) {
069: String[] userfilenames = getUserpathFile().list();
070: boolean hasUsers = false;
071:
072: for (int i = 0; i < userfilenames.length; i++) {
073: String string = userfilenames[i];
074:
075: if (string.endsWith(".xml")) {
076: hasUsers = true;
077:
078: break;
079: }
080: }
081:
082: if (!hasUsers) {
083: createSiteopUser();
084: }
085: }
086: }
087:
088: protected abstract File getUserpathFile();
089:
090: protected void createSiteopUser() throws UserFileException {
091: User user = createUser("drftpd");
092: user.setGroup("drftpd");
093: user.setPassword("drftpd");
094: user.getKeyedMap()
095: .setObject(UserManagement.RATIO, new Float(0));
096: user.getKeyedMap().setObject(UserManagement.GROUPSLOTS, 0);
097: user.getKeyedMap().setObject(UserManagement.LEECHSLOTS, 0);
098: user.getKeyedMap().setObject(UserManagement.MAXLOGINS, 0);
099: user.getKeyedMap().setObject(UserManagement.MAXLOGINSIP, 0);
100: user.getKeyedMap().setObject(UserManagement.MAXSIMUP, 0);
101: user.getKeyedMap().setObject(UserManagement.MAXSIMDN, 0);
102: user.getKeyedMap().setObject(Statistics.LOGINS, 0);
103: user.getKeyedMap()
104: .setObject(UserManagement.CREATED, new Date());
105: user.getKeyedMap().setObject(UserManagement.LASTSEEN,
106: new Date());
107: user.getKeyedMap().setObject(UserManagement.WKLY_ALLOTMENT,
108: new Long(0));
109: user.getKeyedMap().setObject(UserManagement.COMMENT,
110: "Auto-Generated");
111: user.getKeyedMap().setObject(UserManagement.IRCIDENT, "N/A");
112: user.getKeyedMap().setObject(UserManagement.TAGLINE, "drftpd");
113: user.getKeyedMap().setObject(UserManagement.BAN_TIME,
114: new Date());
115: user.getKeyedMap().setObject(Nuke.NUKED, 0);
116: user.getKeyedMap().setObject(Nuke.NUKEDBYTES, new Long(0));
117:
118: try {
119: user.addIPMask("*@127.0.0.1");
120: user.addIPMask("*@0:0:0:0:0:0:0:1");
121: } catch (DuplicateElementException e) {
122: }
123:
124: try {
125: user.addSecondaryGroup("siteop");
126: } catch (DuplicateElementException e1) {
127: }
128:
129: user.commit();
130: }
131:
132: public User create(String username) throws UserFileException {
133: try {
134: getUserByName(username);
135:
136: //bad
137: throw new FileExistsException("User " + username
138: + " already exists");
139: } catch (IOException e) {
140: //bad
141: throw new UserFileException(e);
142: } catch (NoSuchUserException e) {
143: //good
144: }
145:
146: //User user = _connManager.getGlobalContext().getUserManager().createUser(username);
147: User user = createUser(username);
148: user.commit();
149:
150: return user;
151: }
152:
153: protected abstract User createUser(String username);
154:
155: /**
156: * final for now to remove duplicate implementations
157: */
158: public void delete(String username) {
159: if (!getUserFile(username).delete())
160: throw new RuntimeException(new PermissionDeniedException());
161: _users.remove(username);
162: }
163:
164: protected abstract File getUserFile(String username);
165:
166: public Collection getAllGroups() throws UserFileException {
167: Collection users = getAllUsers();
168: ArrayList<String> ret = new ArrayList<String>();
169:
170: for (Iterator iter = users.iterator(); iter.hasNext();) {
171: User myUser = (User) iter.next();
172: Collection myGroups = myUser.getGroups();
173:
174: for (Iterator iterator = myGroups.iterator(); iterator
175: .hasNext();) {
176: String myGroup = (String) iterator.next();
177:
178: if (!ret.contains(myGroup)) {
179: ret.add(myGroup);
180: }
181: }
182:
183: if (!ret.contains(myUser.getGroup())) {
184: ret.add(myUser.getGroup());
185: }
186: }
187:
188: return ret;
189: }
190:
191: /**
192: * Get all user names in the system.
193: */
194: public Collection getAllUsers() throws UserFileException {
195: ArrayList<AbstractUser> users = new ArrayList<AbstractUser>();
196: String[] userpaths = getUserpathFile().list();
197:
198: for (int i = 0; i < userpaths.length; i++) {
199: String userpath = userpaths[i];
200:
201: if (!userpath.endsWith(".xml")) {
202: continue;
203: }
204:
205: String username = userpath.substring(0, userpath.length()
206: - ".xml".length());
207:
208: try {
209: users
210: .add((AbstractUser) getUserByNameUnchecked(username));
211:
212: // throws IOException
213: } catch (NoSuchUserException e) {
214: } // continue
215: }
216:
217: return users;
218: }
219:
220: public Collection getAllUsersByGroup(String group)
221: throws UserFileException {
222: Collection<User> c = new ArrayList<User>();
223:
224: for (Iterator iter = getAllUsers().iterator(); iter.hasNext();) {
225: User user = (User) iter.next();
226:
227: if (user.isMemberOf(group)) {
228: c.add(user);
229: }
230: }
231:
232: return c;
233: }
234:
235: //TODO garbage collected Map of users.
236: public User getUserByNameIncludeDeleted(String username)
237: throws NoSuchUserException, UserFileException {
238: User user = getUserByNameUnchecked(username);
239: user.reset(getGlobalContext());
240: return user;
241: }
242:
243: public User getUserByName(String username)
244: throws NoSuchUserException, UserFileException {
245: User user = getUserByNameIncludeDeleted(username);
246:
247: if (user.isDeleted()) {
248: throw new NoSuchUserException(user.getName()
249: + " is deleted");
250: }
251:
252: return user;
253: }
254:
255: public GlobalContext getGlobalContext() {
256: return _gctx;
257: }
258:
259: public User getUserByIdent(String ident)
260: throws NoSuchUserException, UserFileException {
261: for (Iterator iter = getAllUsers().iterator(); iter.hasNext();) {
262: User user = (User) iter.next();
263: try {
264: String uident = (String) user.getKeyedMap().getObject(
265: UserManagement.IRCIDENT);
266: if (uident.equals(ident)) {
267: return user;
268: }
269: } catch (KeyNotFoundException e1) {
270: }
271: }
272: throw new NoSuchUserException("No user found with ident = "
273: + ident);
274: }
275:
276: public abstract User getUserByNameUnchecked(String username)
277: throws NoSuchUserException, UserFileException;
278:
279: /**
280: * A kind of constuctor defined in the interface for allowing the
281: * usermanager to get a hold of the ConnectionManager object for dispatching
282: * events etc.
283: */
284: public void init(GlobalContext gctx) {
285: _gctx = gctx;
286: }
287:
288: public void remove(User user) {
289: _users.remove(user.getName());
290: }
291:
292: protected void rename(User oldUser, String newUsername)
293: throws UserExistsException, UserFileException {
294: if (!_users.contains(newUsername)) {
295: try {
296: getUserByNameUnchecked(newUsername);
297: } catch (NoSuchUserException e) {
298: _users.remove(oldUser.getName());
299: _users.put(newUsername, oldUser);
300: return;
301: }
302: }
303:
304: throw new UserExistsException("user " + newUsername + " exists");
305: }
306:
307: public void saveAll() throws UserFileException {
308: logger.info("Saving userfiles");
309: for (User user : _users.values()) {
310: user.commit();
311: }
312: }
313: }
|