Rev 1024 | Rev 1048 | 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 | |
1015 | dev | 3 | import java.util.Iterator; |
949 | dev | 4 | import java.util.Collection; |
5 | import java.util.Collections; |
||
1010 | dev | 6 | import java.util.HashSet; |
950 | dev | 7 | import java.util.Locale; |
8 | import java.util.StringTokenizer; |
||
949 | dev | 9 | |
924 | dev | 10 | import ak.hostadmiral.util.ModelException; |
11 | import ak.hostadmiral.util.ModelSecurityException; |
||
919 | dev | 12 | |
13 | /** |
||
14 | * |
||
15 | * @hibernate.class table="users" |
||
16 | */ |
||
17 | public class User |
||
18 | extends GeneralModelObject |
||
19 | { |
||
1015 | dev | 20 | public static final String DEFAULT_PASSWORD_STORE = "MD5"; |
21 | |||
949 | dev | 22 | private String login; |
1015 | dev | 23 | private Collection passwords; // Collection(PasswordStore) |
949 | dev | 24 | private User boss; |
25 | private Boolean superuser; |
||
950 | dev | 26 | private Locale locale = Locale.getDefault(); |
949 | dev | 27 | private Collection loginHistory; |
1011 | dev | 28 | private User origin; // save original object state before any changes |
919 | dev | 29 | |
30 | protected User() |
||
31 | { |
||
32 | } |
||
33 | |||
1010 | dev | 34 | protected User(User origin) |
35 | { |
||
36 | super(origin); |
||
1015 | dev | 37 | this.login = origin.login; |
38 | |||
39 | if(origin.passwords == null) |
||
40 | this.passwords = null; |
||
41 | else |
||
42 | this.passwords = new HashSet(origin.passwords); |
||
43 | |||
44 | this.boss = origin.boss; |
||
1010 | dev | 45 | this.superuser = origin.superuser; |
1015 | dev | 46 | this.locale = origin.locale; |
47 | |||
1010 | dev | 48 | if(origin.loginHistory == null) |
49 | this.loginHistory = null; |
||
50 | else |
||
51 | this.loginHistory = new HashSet(origin.loginHistory); |
||
52 | } |
||
53 | |||
54 | protected User getOrigin() |
||
55 | { |
||
56 | return origin; |
||
57 | } |
||
58 | |||
59 | protected void backupMe() |
||
60 | { |
||
61 | if(origin == null) |
||
62 | origin = new User(this); |
||
63 | } |
||
64 | |||
1045 | dev | 65 | protected void resetOrigin() |
66 | { |
||
67 | origin = null; |
||
68 | } |
||
69 | |||
919 | dev | 70 | /** |
71 | * |
||
72 | * @hibernate.property |
||
73 | */ |
||
74 | public String getLogin() |
||
75 | { |
||
76 | return login; |
||
77 | } |
||
78 | |||
79 | protected void setLogin(String login) |
||
80 | { |
||
81 | this.login = login; |
||
82 | } |
||
83 | |||
84 | public void setLogin(User editor, String login) |
||
85 | throws ModelException |
||
86 | { |
||
87 | if(!editableBy(editor)) |
||
88 | throw new ModelSecurityException(); |
||
89 | |||
1010 | dev | 90 | // FIXME: domain owner is allowed to change user login |
91 | // with some patern only, e.g. user@domain.com |
||
92 | |||
93 | backupMe(); |
||
919 | dev | 94 | this.login = login; |
95 | } |
||
96 | |||
1015 | dev | 97 | protected void addPasswordStore(PasswordStore ps) |
919 | dev | 98 | { |
1015 | dev | 99 | if(passwords == null) passwords = new HashSet(); |
100 | passwords.add(ps); |
||
919 | dev | 101 | } |
102 | |||
1015 | dev | 103 | protected PasswordStore getDefaultPasswordStore() |
104 | throws ModelException |
||
919 | dev | 105 | { |
1015 | dev | 106 | if(passwords == null) |
107 | throw new ModelException("No password store"); |
||
108 | |||
109 | for(Iterator i = passwords.iterator(); i.hasNext(); ) { |
||
110 | Object o = i.next(); |
||
111 | if(!(o instanceof PasswordStore)) |
||
112 | throw new ModelException("It's not a password store"); |
||
113 | PasswordStore ps = (PasswordStore)o; |
||
114 | if(DEFAULT_PASSWORD_STORE.equals(ps.getDigest())) |
||
115 | return ps; |
||
116 | } |
||
117 | |||
118 | throw new ModelException("No password store for digest " + DEFAULT_PASSWORD_STORE); |
||
919 | dev | 119 | } |
120 | |||
1015 | dev | 121 | public String getPassword(User editor) |
122 | throws ModelException |
||
123 | { |
||
124 | if(!partEditableBy(editor)) |
||
125 | throw new ModelSecurityException(); |
||
126 | |||
127 | return getDefaultPasswordStore().getPassword(); |
||
128 | } |
||
129 | |||
919 | dev | 130 | public void setPassword(User editor, String password) |
131 | throws ModelException |
||
132 | { |
||
950 | dev | 133 | if(!partEditableBy(editor)) |
919 | dev | 134 | throw new ModelSecurityException(); |
135 | |||
136 | if(password == null) |
||
137 | throw new NullPointerException("Null password"); |
||
138 | |||
1010 | dev | 139 | backupMe(); |
1015 | dev | 140 | |
141 | for(Iterator i = passwords.iterator(); i.hasNext(); ) { |
||
142 | Object o = i.next(); |
||
143 | if(!(o instanceof PasswordStore)) |
||
144 | throw new ModelException("It's not a password store"); |
||
145 | ((PasswordStore)o).setNewPassword(password); |
||
146 | } |
||
919 | dev | 147 | } |
148 | |||
149 | public boolean checkPassword(String password) |
||
1015 | dev | 150 | throws ModelException |
919 | dev | 151 | { |
152 | if(password == null) |
||
153 | throw new NullPointerException("Null password"); |
||
154 | |||
1015 | dev | 155 | return getDefaultPasswordStore().checkPassword(password); |
919 | dev | 156 | } |
157 | |||
1024 | dev | 158 | /** |
159 | * |
||
160 | * @hibernate.set cascade="all" lazy="true" |
||
161 | * @hibernate.collection-key column="obj" |
||
162 | * @hibernate.collection-one-to-many class="ak.hostadmiral.core.model.PasswordStoreAbstract" |
||
163 | */ |
||
164 | protected Collection getPasswords() |
||
165 | { |
||
166 | return passwords; |
||
167 | } |
||
168 | |||
1015 | dev | 169 | protected void setPasswords(Collection passwords) |
919 | dev | 170 | { |
1015 | dev | 171 | this.passwords = passwords; |
919 | dev | 172 | } |
911 | dev | 173 | |
174 | /** |
||
175 | * |
||
176 | * @hibernate.many-to-one |
||
177 | */ |
||
178 | public User getBoss() |
||
179 | { |
||
180 | return boss; |
||
181 | } |
||
182 | |||
918 | dev | 183 | protected void setBoss(User boss) |
911 | dev | 184 | { |
185 | this.boss = boss; |
||
186 | } |
||
187 | |||
918 | dev | 188 | public void setBoss(User editor, User boss) |
919 | dev | 189 | throws ModelException |
918 | dev | 190 | { |
1010 | dev | 191 | if(!mayChangeBoss(editor)) |
919 | dev | 192 | throw new ModelSecurityException(); |
193 | |||
1010 | dev | 194 | backupMe(); |
918 | dev | 195 | this.boss = boss; |
196 | } |
||
197 | |||
911 | dev | 198 | /** |
199 | * |
||
200 | * @hibernate.property |
||
201 | */ |
||
202 | public Boolean getSuperuser() |
||
203 | { |
||
204 | return superuser; |
||
205 | } |
||
206 | |||
914 | dev | 207 | public boolean isSuperuser() |
208 | { |
||
209 | return (superuser != null) && superuser.booleanValue(); |
||
210 | } |
||
919 | dev | 211 | |
918 | dev | 212 | protected void setSuperuser(Boolean superuser) |
911 | dev | 213 | { |
214 | this.superuser = superuser; |
||
215 | } |
||
216 | |||
918 | dev | 217 | public void setSuperuser(User editor, Boolean superuser) |
919 | dev | 218 | throws ModelException |
918 | dev | 219 | { |
919 | dev | 220 | if(!mayChangeSuperuser(editor)) |
221 | throw new ModelSecurityException(); |
||
222 | |||
1010 | dev | 223 | backupMe(); |
918 | dev | 224 | this.superuser = superuser; |
225 | } |
||
919 | dev | 226 | |
949 | dev | 227 | /** |
228 | * |
||
950 | dev | 229 | * @hibernate.property column="locale" |
230 | */ |
||
231 | protected String getLocaleName() |
||
232 | { |
||
233 | return locale.toString(); |
||
234 | } |
||
235 | |||
236 | protected void setLocaleName(String localeName) |
||
237 | { |
||
238 | String language = null; |
||
239 | String country = null; |
||
240 | |||
241 | if(localeName != null) { |
||
242 | StringTokenizer t = new StringTokenizer(localeName, "_"); |
||
243 | if(t.hasMoreTokens()) language = t.nextToken(); |
||
244 | if(t.hasMoreTokens()) country = t.nextToken(); |
||
245 | } |
||
246 | |||
247 | if(language == null) |
||
248 | this.locale = Locale.getDefault(); |
||
249 | else if(country == null) |
||
250 | this.locale = new Locale(language); |
||
251 | else |
||
252 | this.locale = new Locale(language, country); |
||
253 | } |
||
254 | |||
255 | public void setLocaleName(User editor, String localeName) |
||
256 | throws ModelException |
||
257 | { |
||
258 | if(!partEditableBy(editor)) |
||
259 | throw new ModelSecurityException(); |
||
260 | |||
1010 | dev | 261 | backupMe(); |
950 | dev | 262 | setLocaleName(localeName); |
263 | } |
||
264 | |||
265 | public Locale getLocale() |
||
266 | { |
||
267 | return locale; |
||
268 | } |
||
269 | |||
270 | public void setLocale(User editor, Locale locale) |
||
271 | throws ModelException |
||
272 | { |
||
273 | if(!partEditableBy(editor)) |
||
274 | throw new ModelSecurityException(); |
||
275 | |||
1010 | dev | 276 | backupMe(); |
950 | dev | 277 | this.locale = locale; |
278 | } |
||
279 | |||
280 | /** |
||
281 | * |
||
949 | dev | 282 | * @hibernate.set lazy="true" |
283 | * @hibernate.collection-key column="usr" |
||
284 | * @hibernate.collection-one-to-many class="ak.hostadmiral.core.model.UserLogin" |
||
285 | */ |
||
286 | protected Collection getLoginHistory() |
||
287 | { |
||
288 | return loginHistory; |
||
289 | } |
||
290 | |||
291 | public Collection getLogins() |
||
292 | { |
||
293 | return Collections.unmodifiableCollection(loginHistory); |
||
294 | } |
||
295 | |||
296 | protected void setLoginHistory(Collection loginHistory) |
||
297 | { |
||
298 | this.loginHistory = loginHistory; |
||
299 | } |
||
300 | |||
919 | dev | 301 | public boolean equals(Object o) |
302 | { |
||
303 | if(o == null || !(o instanceof User)) return false; |
||
304 | |||
305 | User u = (User)o; |
||
945 | dev | 306 | return (getId() != null) && (u.getId() != null) && (getId().equals(u.getId())); |
919 | dev | 307 | } |
308 | |||
950 | dev | 309 | protected void update(User origin) |
310 | { |
||
311 | this.login = origin.login; |
||
312 | this.boss = origin.boss; |
||
313 | this.superuser = origin.superuser; |
||
314 | this.locale = origin.locale; |
||
315 | } |
||
316 | |||
919 | dev | 317 | public int hashCode() |
318 | { |
||
945 | dev | 319 | if(getId() == null) |
919 | dev | 320 | return 0; |
321 | else |
||
945 | dev | 322 | return getId().hashCode(); |
919 | dev | 323 | } |
324 | |||
325 | public String getTypeKey() |
||
326 | { |
||
924 | dev | 327 | return ak.hostadmiral.core.CoreResources.TYPE_USER; |
919 | dev | 328 | } |
329 | |||
330 | public String getIdentKey() |
||
331 | { |
||
924 | dev | 332 | return ak.hostadmiral.core.CoreResources.IDENT_USER; |
919 | dev | 333 | } |
334 | |||
335 | public Object[] getIdentParams() |
||
336 | { |
||
337 | return new Object[] { getLogin() }; |
||
338 | } |
||
339 | |||
340 | public boolean viewableBy(User user) |
||
341 | { |
||
342 | return user.isSuperuser() || user.equals(boss) || user.equals(this); |
||
343 | } |
||
344 | |||
345 | public boolean editableBy(User user) |
||
346 | { |
||
347 | return user.isSuperuser() || user.equals(boss); |
||
348 | } |
||
349 | |||
350 | public boolean deleteableBy(User user) |
||
351 | { |
||
946 | dev | 352 | return !user.equals(this) && (user.isSuperuser() || user.equals(boss)); |
919 | dev | 353 | } |
354 | |||
950 | dev | 355 | // editor is allowed to change some additional properties |
356 | public boolean partEditableBy(User user) |
||
919 | dev | 357 | { |
358 | return user.isSuperuser() || user.equals(boss) || user.equals(this); |
||
359 | } |
||
360 | |||
1010 | dev | 361 | public boolean mayChangeBoss(User user) |
362 | { |
||
363 | return user.isSuperuser(); |
||
364 | } |
||
365 | |||
919 | dev | 366 | public boolean mayChangeSuperuser(User user) |
367 | { |
||
368 | return user.isSuperuser() && !user.equals(this); |
||
369 | } |
||
370 | |||
949 | dev | 371 | public boolean mayViewAllLogins() |
372 | { |
||
373 | return isSuperuser(); |
||
374 | } |
||
375 | |||
919 | dev | 376 | protected static boolean allowedToCreate(UserManager manager, User editor) |
377 | throws ModelException |
||
378 | { |
||
1010 | dev | 379 | return editor.isSuperuser() |
380 | || InetDomainManager.getInstance().areInetDomainsAvailable(editor); |
||
381 | // FIXME: or allow any user to create "subusers"? |
||
919 | dev | 382 | } |
946 | dev | 383 | |
384 | protected static User createLimitedCopy(User origin) |
||
385 | { |
||
386 | User u = new User(); |
||
387 | u.setLogin(origin.getLogin()); |
||
388 | return u; |
||
389 | } |
||
1010 | dev | 390 | |
391 | public String toString() |
||
392 | { |
||
393 | return getClass().getName() + " [" + getId() + "] [" + getLogin() + "]"; |
||
394 | } |
||
919 | dev | 395 | } |