1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.caleigo.security;
20
21
22 import java.util.*;
23
24 import org.caleigo.service.*;
25 import org.caleigo.toolkit.log.*;
26
27 /*** The UserInfo class is used to define a container for user specific data
28 * and properties. Another very important service provided by the class is
29 * is static access methods for fetching and setting the current user.
30 *
31 * @author Dennis Zikovic
32 * @version 1.00
33 *
34 *//*
35 *
36 * WHEN WHO WHY & WHAT
37 * -----------------------------------------------------------------------------
38 * 2002-09-24 Dennis Zikovic Creation
39 */
40 public abstract class UserInfo implements java.io.Serializable
41 {
42
43 private transient static Object sLoginServiceIdentity;
44 private transient static InheritableThreadLocal sCurrentUserInfo = new InheritableThreadLocal();
45 private transient static UserInfo sDefaultUserInfo;
46
47
48
49 public static void setLoginServiceIdentity(Object serviceIdentity)
50 {
51 sLoginServiceIdentity = serviceIdentity;
52 }
53
54 protected static ILoginService getLoginServiceIdentity()
55 {
56 ILoginService loginService = (ILoginService) ServiceProvider.getInstance().getService(ILoginService.class, ILoginService.class, sLoginServiceIdentity);
57 if (loginService == null)
58 throw new RuntimeException("Couldn't find login service");
59 return loginService;
60 }
61
62 /*** Returns the UserID of the current user in the system for the scope
63 * defined by the current thread.
64 */
65 public static String getCurrentUserID()
66 throws LoginCanceledException, SecurityException
67 {
68 return getCurrentUserInfo().getUserID();
69 }
70
71 /*** Returns the UserInfo object that defines the current user in the system
72 * for the scope defined by the current thread.
73 */
74 public static UserInfo getCurrentUserInfo()
75 throws LoginCanceledException, SecurityException
76 {
77 UserInfo userInfo = (UserInfo)sCurrentUserInfo.get();
78 if(userInfo != null)
79 return userInfo;
80 else if(sDefaultUserInfo!=null)
81 return sDefaultUserInfo;
82 else
83 return getUserInfoByLogin();
84 }
85
86 /*** Sets the UserInfo object that defines the current user in the system.
87 * This is done locally for the current thread but will be inherited by
88 * future threads created by the origin thread. <p)
89 * Note that to change the user in all child threads one should instead
90 * update the userID on the allready existing current user.
91 */
92 public static void setCurrentUserInfo(UserInfo userInfo)
93 {
94 sCurrentUserInfo.set(userInfo);
95 }
96
97 /*** Sets the default UserInfo object that will be used as the
98 * UserInfo object for all threads that has not had another info
99 * explicitly set. <p>
100 * The UserInfo object will also be inherited by future threads created in
101 * the calling thread or any of its unmodified child threads.<p>
102 */
103 public static void setDefaultUserInfo(UserInfo userInfo)
104 {
105 sDefaultUserInfo = userInfo;
106 }
107
108 private static UserInfo getUserInfoByLogin()
109 throws LoginCanceledException, SecurityException
110 {
111 if(sLoginServiceIdentity == null)
112 throw new IllegalStateException("No login service identity has been set");
113
114 boolean isLoggedIn = false;
115 int nbrOfLoginTries = 0;
116 UserInfo userInfo = null;
117
118 ILoginService loginService = (ILoginService) ServiceProvider.getInstance().getService(ILoginService.class, ILoginService.class, sLoginServiceIdentity);
119 if (loginService == null)
120 throw new RuntimeException("Couldn't find login service");
121
122 int maxLoginTries = loginService.getMaximumNumberOfLoginTries();
123 while (!isLoggedIn && nbrOfLoginTries < maxLoginTries)
124 {
125 try
126 {
127 userInfo = loginService.login();
128 if (userInfo != null)
129 isLoggedIn = true;
130 else
131 break;
132 }
133 catch (SecurityException e)
134 {
135 loginService.handleError("Login failed, reason: " + e.getMessage());
136 Log.printError(null, "Login failed", e);
137 nbrOfLoginTries++;
138 }
139 }
140 if (!isLoggedIn)
141 {
142 if (nbrOfLoginTries == maxLoginTries)
143 throw new SecurityException("Maximum number of login tries reached: " + maxLoginTries);
144 else
145 throw new LoginCanceledException();
146 }
147
148 setCurrentUserInfo(userInfo);
149 setDefaultUserInfo(userInfo);
150 return userInfo;
151 }
152
153
154 public void copyFrom(UserInfo userInfo)
155 {
156 this.setCurrentUserID(userInfo.getUserID());
157 this.setSessionID(userInfo.getSessionID());
158 Enumeration propNames = userInfo.getPropertyNames();
159 if (propNames != null)
160 while (propNames.hasMoreElements())
161 {
162 String currentProp = propNames.nextElement().toString();
163 this.setProperty(currentProp, userInfo.getProperty(currentProp));
164 }
165 }
166
167
168
169 /*** Access method that returns the user ID defined by the user info object.
170 */
171 public abstract String getUserID();
172
173 /*** Returns the session ID defined by the user info object.
174 */
175 public abstract int getSessionID();
176
177 /*** Mutation method that sets the user ID defined by the user info object.
178 */
179 public abstract void setCurrentUserID(String userID);
180
181 /*** Sets the session ID defined by the user info object.
182 */
183 public abstract void setSessionID(int sessionID);
184
185 /*** Access nethod that returns a named property value from the called
186 * user info object. Returns null if the name could not be identified.
187 */
188 public abstract Object getProperty(String name);
189
190 /*** Access nethod that returns a named property value from the called
191 * user info object. Returns the default value if the name could not be
192 * identified.
193 */
194 public abstract Object getProperty(String name, Object defaultValue);
195
196 /*** Updates the named property with provided value. All property data
197 * in a UserInfo object should implement ISerializable.
198 */
199 public abstract void setProperty(String name, Object value);
200
201 public abstract Enumeration getPropertyNames();
202
203 public abstract void logout();
204
205
206 public static class DefaultUserInfo extends UserInfo
207 {
208
209 private String mUserID;
210 private int mSessionID = -1;
211 private Hashtable mUserProperties;
212
213
214
215 /*** Access method that returns the user ID defined by the user info object.
216 */
217 public String getUserID()
218 {
219 return mUserID;
220 }
221
222 /*** Returns the session ID defined by the user info object.
223 */
224 public int getSessionID()
225 {
226 return mSessionID;
227 }
228
229 /*** Mutation method that sets the user ID defined by the called
230 * user info object. Note that any stored properties will be cleared
231 * when this method is called!
232 */
233 public void setCurrentUserID(String userID)
234 {
235 mUserID = userID;
236 if(mUserProperties!=null)
237 mUserProperties.clear();
238 }
239
240 /*** Sets the session ID defined by the user info object.
241 */
242 public void setSessionID(int sessionID)
243 {
244 mSessionID = sessionID;
245 }
246
247 /*** Access nethod that returns a named property value from the called
248 * user info object. Returns null if the name could not be identified.
249 */
250 public Object getProperty(String name)
251 {
252 if(mUserProperties!=null)
253 return mUserProperties.get(name);
254 else
255 return null;
256 }
257
258 /*** Access nethod that returns a named property value from the called
259 * user info object. Returns the default value if the name could not be
260 * identified.
261 */
262 public Object getProperty(String name, Object defaultValue)
263 {
264 Object value = defaultValue;
265 if(mUserProperties!=null)
266 return mUserProperties.get(name);
267 return value;
268 }
269
270 /*** Updates the named property with provided value. Note that
271 */
272 public void setProperty(String name, Object value)
273 {
274 if(mUserProperties==null)
275 mUserProperties = new Hashtable();
276 mUserProperties.put(name, value);
277 }
278
279 public Enumeration getPropertyNames()
280 {
281 if(mUserProperties!=null)
282 return mUserProperties.keys();
283 else
284 return null;
285 }
286
287 public void logout()
288 {
289 getLoginServiceIdentity().logout(this);
290 }
291 }
292 }