Subversion Repositories general

Rev

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