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