Subversion Repositories general

Rev

Rev 1044 | Rev 1046 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
924 dev 1
package ak.hostadmiral.core.model;
919 dev 2
 
1041 dev 3
import java.util.Collection;
4
import java.util.ArrayList;
5
import java.util.Iterator;
6
import java.util.Map;
7
import java.util.WeakHashMap;
8
import java.util.Comparator;
9
import java.util.Date;
10
 
11
import ak.hostadmiral.util.ConfigInit;
1028 dev 12
import ak.hostadmiral.util.CollectionInfo;
924 dev 13
import ak.hostadmiral.util.ModelException;
14
import ak.hostadmiral.util.ModelSecurityException;
1041 dev 15
import ak.hostadmiral.core.model.store.UserStore;
919 dev 16
 
17
public class UserManager
1014 dev 18
	implements
1041 dev 19
		ConfigInit,
1014 dev 20
		UserBeforeDeleteListener,
21
		UserDeletingListener
919 dev 22
{
1044 dev 23
	private UserStore     store;
24
	private UserValidator userValidator;
946 dev 25
 
1010 dev 26
	private Collection createdListeners      = new ArrayList();
27
	private Collection modifiedListeners     = new ArrayList();
946 dev 28
	private Collection beforeDeleteListeners = new ArrayList();
1014 dev 29
	private Collection deletingListeners     = new ArrayList();
1010 dev 30
	private Collection deletedListeners      = new ArrayList();
1041 dev 31
 
950 dev 32
	private Map loggedinUsers = new WeakHashMap();
946 dev 33
 
1041 dev 34
	public UserManager()
35
		throws ModelException
919 dev 36
	{
946 dev 37
		addBeforeDeleteListener(this);
1014 dev 38
		addDeletingListener(this);
919 dev 39
	}
40
 
41
	public User create(User editor)
42
		throws ModelException
43
	{
44
		if(!allowedToCreate(editor)) throw new ModelSecurityException();
45
 
1010 dev 46
		User user = new User();
47
 
48
		if(!user.mayChangeBoss(editor)) { // ordinal user can create only own "subusers"
49
			user.setBoss(editor);
50
		}
51
 
1015 dev 52
        // FIXME: make this configurable
53
		user.addPasswordStore(new PasswordStoreMd5());
54
		user.addPasswordStore(new PasswordStoreCrypt());
55
		user.addPasswordStore(new PasswordStorePlain());
56
 
1010 dev 57
		return user;
919 dev 58
	}
59
 
60
	public boolean allowedToCreate(User editor)
61
		throws ModelException
62
	{
63
		return User.allowedToCreate(this, editor);
64
	}
65
 
66
	public User get(User editor, Long id)
67
		throws ModelException
68
	{
1041 dev 69
		User user = store.get(id);
919 dev 70
 
71
		if(!user.viewableBy(editor))
72
			throw new ModelSecurityException();
73
 
74
		return user;
75
	}
76
 
923 dev 77
	public boolean loginExists(User editor, User user, String login)
78
		throws ModelException
79
	{
1041 dev 80
		return store.loginExists(user, login);
923 dev 81
	}
82
 
1041 dev 83
	public User findForLogin(User editor, String login)
919 dev 84
		throws ModelException
85
	{
1041 dev 86
		User user = store.findForLogin(login);
919 dev 87
 
1041 dev 88
		if(user != null && !user.viewableBy(editor))
89
			throw new ModelSecurityException();
90
 
91
		return user;
919 dev 92
	}
93
 
94
	public void save(User editor, User user)
95
		throws ModelException
96
	{
950 dev 97
		if(!user.editableBy(editor) && !user.partEditableBy(editor)
919 dev 98
			&& !user.mayChangeSuperuser(editor))
99
		{
100
			throw new ModelSecurityException();
101
        }
102
 
1044 dev 103
		if(userValidator != null)
104
			userValidator.validateUser(editor, user);
105
 
1010 dev 106
        boolean isNew = user.isNew();
919 dev 107
 
1010 dev 108
		//user.setModUser(editor); // FIXME: disabled because hb throws exception
109
		                           // if user edits itself
110
 
1041 dev 111
		store.save(user);
950 dev 112
 
113
		// update user if he is logged in
114
		for(Iterator i = loggedinUsers.keySet().iterator(); i.hasNext(); ) {
115
			User u = (User)i.next();
116
			if(u.equals(user))
117
				u.update(user);
118
		}
1010 dev 119
 
120
        // inform listeners
121
        if(isNew) {
122
        	for(Iterator i = createdListeners.iterator(); i.hasNext(); ) {
123
        		UserCreatedListener listener = (UserCreatedListener)i.next();
124
    			listener.userCreated(editor, user);
125
        	}
126
        }
127
        else {
128
            User oldUser = user.getOrigin();
129
            if(oldUser == null) oldUser = user;
130
        	for(Iterator i = modifiedListeners.iterator(); i.hasNext(); ) {
131
        		UserModifiedListener listener = (UserModifiedListener)i.next();
132
    			listener.userModified(editor, user, oldUser);
133
        	}
134
        }
1045 dev 135
 
136
        // reset backup
137
        user.resetOrigin();
919 dev 138
	}
139
 
1010 dev 140
    public void addCreatedListener(UserCreatedListener listener)
141
    {
142
    	createdListeners.add(listener);
143
    }
144
 
145
    public void removeCreatedListener(UserCreatedListener listener)
146
    {
147
    	createdListeners.remove(listener);
148
    }
149
 
150
    public void addModifiedListener(UserModifiedListener listener)
151
    {
152
    	modifiedListeners.add(listener);
153
    }
154
 
155
    public void removeModifiedListener(UserModifiedListener listener)
156
    {
157
    	modifiedListeners.remove(listener);
158
    }
159
 
946 dev 160
    public void addBeforeDeleteListener(UserBeforeDeleteListener listener)
161
    {
162
    	beforeDeleteListeners.add(listener);
163
    }
164
 
165
    public void removeBeforeDeleteListener(UserBeforeDeleteListener listener)
166
    {
167
    	beforeDeleteListeners.remove(listener);
168
    }
169
 
1010 dev 170
    public void addDeletedListener(UserDeletedListener listener)
171
    {
172
    	deletedListeners.add(listener);
173
    }
174
 
175
    public void removeDeletedListener(UserDeletedListener listener)
176
    {
177
    	deletedListeners.remove(listener);
178
    }
179
 
1014 dev 180
    public void addDeletingListener(UserDeletingListener listener)
181
    {
182
    	deletingListeners.add(listener);
183
    }
184
 
185
    public void removeDeletingListener(UserDeletingListener listener)
186
    {
187
    	deletingListeners.remove(listener);
188
    }
189
 
949 dev 190
    public Collection beforeDelete(User editor, User user, Collection known)
946 dev 191
		throws ModelException
192
    {
193
    	Collection cascade = new ArrayList();
194
 
195
    	for(Iterator i = beforeDeleteListeners.iterator(); i.hasNext(); ) {
196
    		UserBeforeDeleteListener listener = (UserBeforeDeleteListener)i.next();
949 dev 197
			Collection subcascade = listener.userBeforeDelete(editor, user, known);
946 dev 198
    		if(subcascade != null)
199
    			cascade.addAll(subcascade);
200
    	}
201
 
202
    	return cascade;
203
    }
204
 
919 dev 205
	public void delete(User editor, User user)
206
		throws ModelException
207
	{
1011 dev 208
	    // check rights
919 dev 209
		if(!user.deleteableBy(editor))
210
			throw new ModelSecurityException();
211
 
1014 dev 212
        // inform deleting listeners
213
    	for(Iterator i = deletingListeners.iterator(); i.hasNext(); ) {
214
    		UserDeletingListener listener = (UserDeletingListener)i.next();
215
			listener.userDeleting(editor, user);
216
    	}
217
 
1010 dev 218
        // backup copy
219
        User oldUser = new User(user);
220
 
221
        // delete it
1041 dev 222
		store.delete(user);
1010 dev 223
 
1014 dev 224
        // inform delete listeners
1010 dev 225
    	for(Iterator i = deletedListeners.iterator(); i.hasNext(); ) {
226
    		UserDeletedListener listener = (UserDeletedListener)i.next();
227
			listener.userDeleted(editor, oldUser);
228
    	}
919 dev 229
	}
230
 
231
	public Collection listUsers(User editor)
232
		throws ModelException
233
	{
1028 dev 234
		return listUsers(null, 0, 0, null, editor);
235
	}
236
 
237
	public Collection listUsers(CollectionInfo info, int rowsPerPage, int pageNumber,
238
			Integer[] sortingKeys, User editor)
239
		throws ModelException
240
	{
1041 dev 241
		if(editor.isSuperuser())
242
			return store.listAllUsers(info, rowsPerPage, pageNumber, sortingKeys);
243
		else
244
			return store.listUsers(info, rowsPerPage, pageNumber, sortingKeys, editor);
919 dev 245
	}
246
 
923 dev 247
	public boolean areUsersAvailable(User editor)
919 dev 248
		throws ModelException
249
	{
1041 dev 250
		return true;
919 dev 251
	}
252
 
949 dev 253
	public User loginUser(String login, String password, String ip)
919 dev 254
		throws ModelException
255
	{
1041 dev 256
		User      user      = (login == null || password == null)
257
			? null : store.findForLogin(login);
258
 
949 dev 259
		boolean   success   = (user == null) ? false : user.checkPassword(password);
951 dev 260
		UserLogin userLogin = new UserLogin(user, login, new Date(), Boolean.valueOf(success), ip);
919 dev 261
 
949 dev 262
		// save login information
1041 dev 263
		store.saveUserLogin(userLogin);
919 dev 264
 
950 dev 265
		if(success) {
1041 dev 266
			user = new User(user);   // unbind the user from store
950 dev 267
			loggedinUsers.put(user, Boolean.TRUE);
949 dev 268
			return user;
950 dev 269
		}
270
		else {
949 dev 271
			return null; // wrong login or password
950 dev 272
		}
919 dev 273
	}
274
 
949 dev 275
	public Collection listFailedLogins(User editor)
946 dev 276
		throws ModelException
919 dev 277
	{
949 dev 278
		if(!editor.mayViewAllLogins())
279
			throw new ModelSecurityException();
280
 
1041 dev 281
		return store.listFailedLogins();
949 dev 282
	}
283
 
284
	public Collection userBeforeDelete(User editor, User user, Collection known)
285
		throws ModelException
286
	{
1041 dev 287
        Collection subusers = store.listSubusers(user);
919 dev 288
 
946 dev 289
    	Collection cascade = new ArrayList();
290
		for(Iterator i = subusers.iterator(); i.hasNext(); ) {
291
			User u = (User)i.next();
292
            if(u.viewableBy(editor)) {
293
				if(u.deleteableBy(editor))
294
					cascade.add(new CascadeDeleteElement(u, CascadeDeleteElement.DELETE,
949 dev 295
						this.beforeDelete(editor, u, known)));
946 dev 296
				else
297
					cascade.add(new CascadeDeleteElement(u, CascadeDeleteElement.FORBIDDEN, null));
298
			}
299
			else {
300
				cascade.add(new CascadeDeleteElement(User.createLimitedCopy(u),
301
					CascadeDeleteElement.FORBIDDEN, null));
302
			}
303
		}
304
 
305
    	return cascade;
919 dev 306
	}
307
 
1014 dev 308
	public void userDeleting(User editor, User user)
309
		throws ModelException
310
	{
1041 dev 311
        Collection subusers = store.listSubusers(user);
1014 dev 312
 
313
		for(Iterator i = subusers.iterator(); i.hasNext(); ) {
314
			delete(editor, (User)i.next());
315
		}
316
	}
317
 
1028 dev 318
	public static final Integer SORT_LOGIN = new Integer(1);
319
 
919 dev 320
	public static final Comparator LOGIN_COMPARATOR = new LoginComparator();
949 dev 321
	public static final Comparator LOGINS_TIME_COMPARATOR = new LoginsTimeComparator();
919 dev 322
 
323
	private static class LoginComparator
324
		implements Comparator
325
	{
326
		public int compare(Object o1, Object o2)
327
		{
328
			if(!(o1 instanceof User) || !(o2 instanceof User))
329
				throw new ClassCastException("not a User");
330
 
331
		    User a1 = (User)o1;
332
		    User a2 = (User)o2;
333
 
334
		    if(a1 == null && a2 == null)
335
		    	return 0;
336
		    else if(a1 == null && a2 != null)
337
		    	return -1;
338
		    else if(a1 != null && a2 == null)
339
		    	return 1;
340
		    else
341
		    	return a1.getLogin().compareToIgnoreCase(a2.getLogin());
342
		}
343
 
344
		public boolean equals(Object obj)
345
		{
346
			return (obj instanceof LoginComparator);
347
		}
348
	}
949 dev 349
 
350
	private static class LoginsTimeComparator
351
		implements Comparator
352
	{
353
		public int compare(Object o1, Object o2)
354
		{
355
			if(!(o1 instanceof UserLogin) || !(o2 instanceof UserLogin))
356
				throw new ClassCastException("not a UserLogin");
357
 
358
		    UserLogin a1 = (UserLogin)o1;
359
		    UserLogin a2 = (UserLogin)o2;
360
 
361
		    if(a1 == null && a2 == null)
362
		    	return 0;
363
		    else if(a1 == null && a2 != null)
364
		    	return -1;
365
		    else if(a1 != null && a2 == null)
366
		    	return 1;
367
		    else
368
		    	return a1.getLoginTime().compareTo(a2.getLoginTime());
369
		}
370
 
371
		public boolean equals(Object obj)
372
		{
373
			return (obj instanceof LoginComparator);
374
		}
375
	}
1041 dev 376
 
377
	public void init(Map params)
378
		throws ModelException
379
	{
380
		try {
381
    		userManager = this;
382
 
383
			Class c = Class.forName((String)params.get("store"));
384
			store = (UserStore)c.newInstance();
1044 dev 385
 
386
			String userValidatorName = (String)params.get("userValidator");
387
			if(userValidatorName != null) {
388
				Class c2 = Class.forName(userValidatorName);
389
				userValidator = (UserValidator)c2.newInstance();
390
			}
1041 dev 391
        }
392
        catch(Exception ex) {
393
        	throw new ModelException(ex);
394
        }
395
	}
396
 
397
	private static UserManager userManager = null;
398
 
399
	public static UserManager getInstance()
400
	{
401
		return userManager;
402
	}
919 dev 403
}