Subversion Repositories general

Rev

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