Subversion Repositories general

Rev

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