Rev 1071 | 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 | backupMe(); |
919 | dev | 91 | this.login = login; |
92 | } |
||
93 | |||
1015 | dev | 94 | protected void addPasswordStore(PasswordStore ps) |
919 | dev | 95 | { |
1015 | dev | 96 | if(passwords == null) passwords = new HashSet(); |
97 | passwords.add(ps); |
||
919 | dev | 98 | } |
99 | |||
1015 | dev | 100 | protected PasswordStore getDefaultPasswordStore() |
101 | throws ModelException |
||
919 | dev | 102 | { |
1015 | dev | 103 | if(passwords == null) |
104 | throw new ModelException("No password store"); |
||
105 | |||
106 | for(Iterator i = passwords.iterator(); i.hasNext(); ) { |
||
107 | Object o = i.next(); |
||
108 | if(!(o instanceof PasswordStore)) |
||
109 | throw new ModelException("It's not a password store"); |
||
110 | PasswordStore ps = (PasswordStore)o; |
||
111 | if(DEFAULT_PASSWORD_STORE.equals(ps.getDigest())) |
||
112 | return ps; |
||
113 | } |
||
114 | |||
115 | throw new ModelException("No password store for digest " + DEFAULT_PASSWORD_STORE); |
||
919 | dev | 116 | } |
117 | |||
1015 | dev | 118 | public String getPassword(User editor) |
119 | throws ModelException |
||
120 | { |
||
121 | if(!partEditableBy(editor)) |
||
122 | throw new ModelSecurityException(); |
||
123 | |||
124 | return getDefaultPasswordStore().getPassword(); |
||
125 | } |
||
126 | |||
1082 | dev | 127 | public String getPassword(User editor, String digest) |
128 | throws ModelException |
||
129 | { |
||
130 | if(!partEditableBy(editor)) |
||
131 | throw new ModelSecurityException(); |
||
132 | |||
133 | for(Iterator i = passwords.iterator(); i.hasNext(); ) { |
||
134 | Object o = i.next(); |
||
135 | if(!(o instanceof PasswordStore)) |
||
136 | throw new ModelException("It's not a password store"); |
||
137 | |||
138 | PasswordStore ps = (PasswordStore)o; |
||
139 | if(ps.getDigest().equals(digest)) { |
||
140 | return ps.getPassword(); |
||
141 | } |
||
142 | } |
||
143 | |||
144 | throw new ModelException("Digest " + digest + " not found"); |
||
145 | } |
||
146 | |||
919 | dev | 147 | public void setPassword(User editor, String password) |
148 | throws ModelException |
||
149 | { |
||
950 | dev | 150 | if(!partEditableBy(editor)) |
919 | dev | 151 | throw new ModelSecurityException(); |
152 | |||
153 | if(password == null) |
||
154 | throw new NullPointerException("Null password"); |
||
155 | |||
1010 | dev | 156 | backupMe(); |
1015 | dev | 157 | |
158 | for(Iterator i = passwords.iterator(); i.hasNext(); ) { |
||
159 | Object o = i.next(); |
||
160 | if(!(o instanceof PasswordStore)) |
||
161 | throw new ModelException("It's not a password store"); |
||
162 | ((PasswordStore)o).setNewPassword(password); |
||
163 | } |
||
919 | dev | 164 | } |
165 | |||
166 | public boolean checkPassword(String password) |
||
1015 | dev | 167 | throws ModelException |
919 | dev | 168 | { |
169 | if(password == null) |
||
170 | throw new NullPointerException("Null password"); |
||
171 | |||
1015 | dev | 172 | return getDefaultPasswordStore().checkPassword(password); |
919 | dev | 173 | } |
174 | |||
1024 | dev | 175 | /** |
176 | * |
||
177 | * @hibernate.set cascade="all" lazy="true" |
||
178 | * @hibernate.collection-key column="obj" |
||
179 | * @hibernate.collection-one-to-many class="ak.hostadmiral.core.model.PasswordStoreAbstract" |
||
180 | */ |
||
181 | protected Collection getPasswords() |
||
182 | { |
||
183 | return passwords; |
||
184 | } |
||
185 | |||
1015 | dev | 186 | protected void setPasswords(Collection passwords) |
919 | dev | 187 | { |
1015 | dev | 188 | this.passwords = passwords; |
919 | dev | 189 | } |
911 | dev | 190 | |
191 | /** |
||
192 | * |
||
193 | * @hibernate.many-to-one |
||
194 | */ |
||
195 | public User getBoss() |
||
196 | { |
||
197 | return boss; |
||
198 | } |
||
199 | |||
918 | dev | 200 | protected void setBoss(User boss) |
911 | dev | 201 | { |
202 | this.boss = boss; |
||
203 | } |
||
204 | |||
918 | dev | 205 | public void setBoss(User editor, User boss) |
919 | dev | 206 | throws ModelException |
918 | dev | 207 | { |
1010 | dev | 208 | if(!mayChangeBoss(editor)) |
919 | dev | 209 | throw new ModelSecurityException(); |
210 | |||
1010 | dev | 211 | backupMe(); |
918 | dev | 212 | this.boss = boss; |
213 | } |
||
214 | |||
911 | dev | 215 | /** |
216 | * |
||
217 | * @hibernate.property |
||
218 | */ |
||
219 | public Boolean getSuperuser() |
||
220 | { |
||
221 | return superuser; |
||
222 | } |
||
223 | |||
914 | dev | 224 | public boolean isSuperuser() |
225 | { |
||
226 | return (superuser != null) && superuser.booleanValue(); |
||
227 | } |
||
919 | dev | 228 | |
918 | dev | 229 | protected void setSuperuser(Boolean superuser) |
911 | dev | 230 | { |
231 | this.superuser = superuser; |
||
232 | } |
||
233 | |||
918 | dev | 234 | public void setSuperuser(User editor, Boolean superuser) |
919 | dev | 235 | throws ModelException |
918 | dev | 236 | { |
919 | dev | 237 | if(!mayChangeSuperuser(editor)) |
238 | throw new ModelSecurityException(); |
||
239 | |||
1010 | dev | 240 | backupMe(); |
918 | dev | 241 | this.superuser = superuser; |
242 | } |
||
919 | dev | 243 | |
949 | dev | 244 | /** |
245 | * |
||
950 | dev | 246 | * @hibernate.property column="locale" |
247 | */ |
||
248 | protected String getLocaleName() |
||
249 | { |
||
250 | return locale.toString(); |
||
251 | } |
||
252 | |||
253 | protected void setLocaleName(String localeName) |
||
254 | { |
||
255 | String language = null; |
||
256 | String country = null; |
||
257 | |||
258 | if(localeName != null) { |
||
259 | StringTokenizer t = new StringTokenizer(localeName, "_"); |
||
260 | if(t.hasMoreTokens()) language = t.nextToken(); |
||
261 | if(t.hasMoreTokens()) country = t.nextToken(); |
||
262 | } |
||
263 | |||
264 | if(language == null) |
||
265 | this.locale = Locale.getDefault(); |
||
266 | else if(country == null) |
||
267 | this.locale = new Locale(language); |
||
268 | else |
||
269 | this.locale = new Locale(language, country); |
||
270 | } |
||
271 | |||
272 | public void setLocaleName(User editor, String localeName) |
||
273 | throws ModelException |
||
274 | { |
||
275 | if(!partEditableBy(editor)) |
||
276 | throw new ModelSecurityException(); |
||
277 | |||
1010 | dev | 278 | backupMe(); |
950 | dev | 279 | setLocaleName(localeName); |
280 | } |
||
281 | |||
282 | public Locale getLocale() |
||
283 | { |
||
284 | return locale; |
||
285 | } |
||
286 | |||
1071 | dev | 287 | public void setLocale(Locale locale) |
288 | { |
||
289 | this.locale = locale; |
||
290 | } |
||
291 | |||
950 | dev | 292 | public void setLocale(User editor, Locale locale) |
293 | throws ModelException |
||
294 | { |
||
295 | if(!partEditableBy(editor)) |
||
296 | throw new ModelSecurityException(); |
||
297 | |||
1010 | dev | 298 | backupMe(); |
950 | dev | 299 | this.locale = locale; |
300 | } |
||
301 | |||
302 | /** |
||
303 | * |
||
949 | dev | 304 | * @hibernate.set lazy="true" |
305 | * @hibernate.collection-key column="usr" |
||
306 | * @hibernate.collection-one-to-many class="ak.hostadmiral.core.model.UserLogin" |
||
307 | */ |
||
308 | protected Collection getLoginHistory() |
||
309 | { |
||
310 | return loginHistory; |
||
311 | } |
||
312 | |||
313 | public Collection getLogins() |
||
314 | { |
||
315 | return Collections.unmodifiableCollection(loginHistory); |
||
316 | } |
||
317 | |||
318 | protected void setLoginHistory(Collection loginHistory) |
||
319 | { |
||
320 | this.loginHistory = loginHistory; |
||
321 | } |
||
322 | |||
950 | dev | 323 | protected void update(User origin) |
324 | { |
||
325 | this.login = origin.login; |
||
326 | this.boss = origin.boss; |
||
327 | this.superuser = origin.superuser; |
||
328 | this.locale = origin.locale; |
||
329 | } |
||
330 | |||
919 | dev | 331 | public String getTypeKey() |
332 | { |
||
1051 | dev | 333 | return ak.hostadmiral.core.resources.CoreResources.TYPE_USER; |
919 | dev | 334 | } |
335 | |||
336 | public String getIdentKey() |
||
337 | { |
||
1051 | dev | 338 | return ak.hostadmiral.core.resources.CoreResources.IDENT_USER; |
919 | dev | 339 | } |
340 | |||
341 | public Object[] getIdentParams() |
||
342 | { |
||
343 | return new Object[] { getLogin() }; |
||
344 | } |
||
345 | |||
346 | public boolean viewableBy(User user) |
||
347 | { |
||
348 | return user.isSuperuser() || user.equals(boss) || user.equals(this); |
||
349 | } |
||
350 | |||
351 | public boolean editableBy(User user) |
||
352 | { |
||
353 | return user.isSuperuser() || user.equals(boss); |
||
354 | } |
||
355 | |||
356 | public boolean deleteableBy(User user) |
||
357 | { |
||
946 | dev | 358 | return !user.equals(this) && (user.isSuperuser() || user.equals(boss)); |
919 | dev | 359 | } |
360 | |||
950 | dev | 361 | // editor is allowed to change some additional properties |
362 | public boolean partEditableBy(User user) |
||
919 | dev | 363 | { |
364 | return user.isSuperuser() || user.equals(boss) || user.equals(this); |
||
365 | } |
||
366 | |||
1010 | dev | 367 | public boolean mayChangeBoss(User user) |
368 | { |
||
369 | return user.isSuperuser(); |
||
370 | } |
||
371 | |||
919 | dev | 372 | public boolean mayChangeSuperuser(User user) |
373 | { |
||
374 | return user.isSuperuser() && !user.equals(this); |
||
375 | } |
||
376 | |||
949 | dev | 377 | public boolean mayViewAllLogins() |
378 | { |
||
379 | return isSuperuser(); |
||
380 | } |
||
381 | |||
919 | dev | 382 | protected static boolean allowedToCreate(UserManager manager, User editor) |
383 | throws ModelException |
||
384 | { |
||
1010 | dev | 385 | return editor.isSuperuser() |
386 | || InetDomainManager.getInstance().areInetDomainsAvailable(editor); |
||
387 | // FIXME: or allow any user to create "subusers"? |
||
919 | dev | 388 | } |
946 | dev | 389 | |
390 | protected static User createLimitedCopy(User origin) |
||
391 | { |
||
392 | User u = new User(); |
||
393 | u.setLogin(origin.getLogin()); |
||
394 | return u; |
||
395 | } |
||
1010 | dev | 396 | |
397 | public String toString() |
||
398 | { |
||
1056 | dev | 399 | return "User id=[" + getId() + "] login=[" + login + "]"; |
1010 | dev | 400 | } |
919 | dev | 401 | } |