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