View Javadoc

1   /* (c) Copyright 2003 Caleigo AB, All rights reserved. 
2    * 
3    * This library is free software; you can redistribute it and/or
4    * modify it under the terms of the GNU Lesser General Public
5    * License as published by the Free Software Foundation; either
6    * version 2.1 of the License, or (at your option) any later version.
7    * 
8    * This library is distributed in the hope that it will be useful,
9    * but WITHOUT ANY WARRANTY; without even the implied warranty of
10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11   * Lesser General Public License for more details.
12   * 
13   * You should have received a copy of the GNU Lesser General Public
14   * License along with this library; if not, write to the Free Software
15   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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      // Data members ------------------------------------------------------------
43      private transient static Object sLoginServiceIdentity;
44      private transient static InheritableThreadLocal sCurrentUserInfo = new InheritableThreadLocal();
45      private transient static UserInfo sDefaultUserInfo;
46      
47      // Static methods ----------------------------------------------------------
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     // Action methods ----------------------------------------------------------
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     // Access methods ----------------------------------------------------------
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     // Internal classes --------------------------------------------------------
206     public static class DefaultUserInfo extends UserInfo
207     {
208         // Data members --------------------------------------------------------
209         private String mUserID;
210         private int mSessionID = -1;        
211         private Hashtable mUserProperties;
212         
213         // Access methods ------------------------------------------------------
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 }