Subversion Repositories general

Rev

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