Subversion Repositories general

Rev

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