Subversion Repositories general

Rev

Rev 1014 | Rev 1018 | 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 {
1014 dev 30
				/* FIMXE: do the same for all classes
919 dev 31
				HibernateUtil.getConfiguration().addResource(
950 dev 32
					"ak/hostadmiral/core/model/User.hbm.xml");
949 dev 33
				HibernateUtil.getConfiguration().addResource(
950 dev 34
					"ak/hostadmiral/core/model/UserLogin.hbm.xml");
1010 dev 35
                */
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(
949 dev 131
				"from User where login = ? and 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()) {
291
				return HibernateUtil.currentSession().find("from User");
292
			}
293
			else {
294
				return HibernateUtil.currentSession().find(
295
					"from User u where u = ? or u.boss = ?",
296
					new Object[] { editor, editor},
297
					new Type[] { Hibernate.entity(User.class), Hibernate.entity(User.class) } );
298
			}
299
		}
1010 dev 300
		catch(HibernateException ex) {
919 dev 301
			throw new ModelException(ex);
302
		}
303
	}
304
 
923 dev 305
	public boolean areUsersAvailable(User editor)
919 dev 306
		throws ModelException
307
	{
308
		try {
309
			if(editor.isSuperuser()) {
310
				return true;
311
			}
312
			else {
313
				return ((Integer)HibernateUtil.currentSession().iterate(
923 dev 314
					"select count(*) from User u where u = ? or u.boss = ?",
919 dev 315
					new Object[] { editor, editor},
316
					new Type[] { Hibernate.entity(User.class), Hibernate.entity(User.class) } )
317
					.next()).intValue() > 0;
318
			}
319
		}
1010 dev 320
		catch(HibernateException ex) {
919 dev 321
			throw new ModelException(ex);
322
		}
323
	}
324
 
949 dev 325
	public User loginUser(String login, String password, String ip)
919 dev 326
		throws ModelException
327
	{
949 dev 328
		User      user      = (login == null || password == null) ? null : findForLogin(login);
329
		boolean   success   = (user == null) ? false : user.checkPassword(password);
951 dev 330
		UserLogin userLogin = new UserLogin(user, login, new Date(), Boolean.valueOf(success), ip);
919 dev 331
 
949 dev 332
		// save login information
333
		try {
334
			HibernateUtil.currentSession().saveOrUpdate(userLogin);
919 dev 335
		}
1010 dev 336
		catch(HibernateException ex) {
949 dev 337
			throw new ModelException(ex);
338
		}
919 dev 339
 
950 dev 340
		if(success) {
1010 dev 341
			user = new User(user);   // unbind the user from hibernate
950 dev 342
			loggedinUsers.put(user, Boolean.TRUE);
949 dev 343
			return user;
950 dev 344
		}
345
		else {
949 dev 346
			return null; // wrong login or password
950 dev 347
		}
919 dev 348
	}
349
 
949 dev 350
	public Collection listFailedLogins(User editor)
946 dev 351
		throws ModelException
919 dev 352
	{
949 dev 353
		if(!editor.mayViewAllLogins())
354
		{
355
			throw new ModelSecurityException();
356
        }
357
 
358
		try {
359
			return HibernateUtil.currentSession().find(
360
				"from UserLogin where success = ?",
951 dev 361
				Boolean.FALSE, Hibernate.BOOLEAN);
949 dev 362
		}
1010 dev 363
		catch(HibernateException ex) {
364
            throw new ModelException(ex);
949 dev 365
		}
366
	}
367
 
368
	public Collection userBeforeDelete(User editor, User user, Collection known)
369
		throws ModelException
370
	{
946 dev 371
        Collection subusers;
919 dev 372
 
946 dev 373
		try {
374
			subusers = HibernateUtil.currentSession().find(
375
				"from User where boss = ?",
376
				user, Hibernate.entity(User.class) );
377
		}
1010 dev 378
		catch(HibernateException ex) {
946 dev 379
			throw new ModelException(ex);
380
		}
381
 
382
    	Collection cascade = new ArrayList();
383
		for(Iterator i = subusers.iterator(); i.hasNext(); ) {
384
			User u = (User)i.next();
385
            if(u.viewableBy(editor)) {
386
				if(u.deleteableBy(editor))
387
					cascade.add(new CascadeDeleteElement(u, CascadeDeleteElement.DELETE,
949 dev 388
						this.beforeDelete(editor, u, known)));
946 dev 389
				else
390
					cascade.add(new CascadeDeleteElement(u, CascadeDeleteElement.FORBIDDEN, null));
391
			}
392
			else {
393
				cascade.add(new CascadeDeleteElement(User.createLimitedCopy(u),
394
					CascadeDeleteElement.FORBIDDEN, null));
395
			}
396
		}
397
 
398
    	return cascade;
919 dev 399
	}
400
 
1014 dev 401
	public void userDeleting(User editor, User user)
402
		throws ModelException
403
	{
404
        Collection subusers;
405
 
406
		try {
407
			subusers = HibernateUtil.currentSession().find(
408
				"from User where boss = ?",
409
				user, Hibernate.entity(User.class) );
410
		}
411
		catch(HibernateException ex) {
412
			throw new ModelException(ex);
413
		}
414
 
415
		for(Iterator i = subusers.iterator(); i.hasNext(); ) {
416
			delete(editor, (User)i.next());
417
		}
418
	}
419
 
919 dev 420
	public static final Comparator LOGIN_COMPARATOR = new LoginComparator();
949 dev 421
	public static final Comparator LOGINS_TIME_COMPARATOR = new LoginsTimeComparator();
919 dev 422
 
423
	private static class LoginComparator
424
		implements Comparator
425
	{
426
		public int compare(Object o1, Object o2)
427
		{
428
			if(!(o1 instanceof User) || !(o2 instanceof User))
429
				throw new ClassCastException("not a User");
430
 
431
		    User a1 = (User)o1;
432
		    User a2 = (User)o2;
433
 
434
		    if(a1 == null && a2 == null)
435
		    	return 0;
436
		    else if(a1 == null && a2 != null)
437
		    	return -1;
438
		    else if(a1 != null && a2 == null)
439
		    	return 1;
440
		    else
441
		    	return a1.getLogin().compareToIgnoreCase(a2.getLogin());
442
		}
443
 
444
		public boolean equals(Object obj)
445
		{
446
			return (obj instanceof LoginComparator);
447
		}
448
	}
949 dev 449
 
450
	private static class LoginsTimeComparator
451
		implements Comparator
452
	{
453
		public int compare(Object o1, Object o2)
454
		{
455
			if(!(o1 instanceof UserLogin) || !(o2 instanceof UserLogin))
456
				throw new ClassCastException("not a UserLogin");
457
 
458
		    UserLogin a1 = (UserLogin)o1;
459
		    UserLogin a2 = (UserLogin)o2;
460
 
461
		    if(a1 == null && a2 == null)
462
		    	return 0;
463
		    else if(a1 == null && a2 != null)
464
		    	return -1;
465
		    else if(a1 != null && a2 == null)
466
		    	return 1;
467
		    else
468
		    	return a1.getLoginTime().compareTo(a2.getLoginTime());
469
		}
470
 
471
		public boolean equals(Object obj)
472
		{
473
			return (obj instanceof LoginComparator);
474
		}
475
	}
919 dev 476
}