View Javadoc

1   /**
2    * Copyright 2005-2012 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krad;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.core.api.config.property.ConfigContext;
20  import org.kuali.rice.core.api.exception.RiceRuntimeException;
21  import org.kuali.rice.kim.api.identity.Person;
22  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
23  import org.kuali.rice.krad.util.SessionTicket;
24  
25  import java.io.Serializable;
26  import java.util.ArrayList;
27  import java.util.Collections;
28  import java.util.HashMap;
29  import java.util.List;
30  import java.util.Map;
31  import java.util.concurrent.atomic.AtomicInteger;
32  
33  /**
34   * Holds info about the User Session
35   *
36   * @author Kuali Rice Team (rice.collab@kuali.org)
37   */
38  public class UserSession implements Serializable {
39      private static final long serialVersionUID = 4532616762540067557L;
40  
41      private Person person;
42      private Person backdoorUser;
43      private AtomicInteger nextObjectKey;
44      private Map<String, Object> objectMap;
45      private String kualiSessionId;
46  
47      /**
48       * @return the kualiSessionId
49       */
50      public String getKualiSessionId() {
51          return this.kualiSessionId;
52      }
53  
54      /**
55       * @param kualiSessionId the kualiSessionId to set
56       */
57      public void setKualiSessionId(String kualiSessionId) {
58          this.kualiSessionId = kualiSessionId;
59      }
60  
61      /**
62       * Take in a netid, and construct the user from that.
63       *
64       * @param principalName
65       */
66      public UserSession(String principalName) {
67          this.person = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(principalName);
68          if (this.person == null) {
69              throw new IllegalArgumentException(
70                      "Failed to locate a principal with principal name '" + principalName + "'");
71          }
72          this.nextObjectKey = new AtomicInteger(0);
73          this.objectMap = Collections.synchronizedMap(new HashMap<String, Object>());
74      }
75  
76      /**
77       * @return the principalId of the current user in the system, backdoor principalId if backdoor is set
78       */
79      public String getPrincipalId() {
80          if (backdoorUser != null) {
81              return backdoorUser.getPrincipalId();
82          }
83          return person.getPrincipalId();
84      }
85  
86      /**
87       * @return the principalName of the current user in the system, backdoor principalName if backdoor is set
88       */
89      public String getPrincipalName() {
90          if (backdoorUser != null) {
91              return backdoorUser.getPrincipalName();
92          }
93          return person.getPrincipalName();
94      }
95  
96      /**
97       * This returns who is logged in. If the backdoor is in use, this will return the network id of the person that is
98       * standing in
99       * as the backdoor user.
100      *
101      * @return String
102      */
103     public String getLoggedInUserPrincipalName() {
104         if (person != null) {
105             return person.getPrincipalName();
106         }
107         return "";
108     }
109 
110     /**
111      * @return the KualiUser which is the current user in the system, backdoor if backdoor is set
112      */
113     public Person getPerson() {
114         if (backdoorUser != null) {
115             return backdoorUser;
116         }
117         return person;
118     }
119 
120     /**
121      * override the current user in the system by setting the backdoor networkId, which is useful when dealing with
122      * routing or other
123      * reasons why you would need to assume an identity in the system
124      *
125      * @param principalName
126      */
127     public void setBackdoorUser(String principalName) {
128         // only allow backdoor in non-production environments
129         if (!isProductionEnvironment()) {
130             this.backdoorUser = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(principalName);
131             if (backdoorUser == null) {
132                 throw new RiceRuntimeException(principalName + " is not a valid principalName");
133             }
134         }
135     }
136 
137     private boolean isProductionEnvironment() {
138         return ConfigContext.getCurrentContextConfig().isProductionEnvironment();
139     }
140 
141     /**
142      * clear the backdoor user
143      */
144     public void clearBackdoorUser() {
145         this.backdoorUser = null;
146     }
147 
148     /**
149      * allows adding an arbitrary object to the session and returns a string key that can be used to later access this
150      * object from
151      * the session using the retrieveObject method in this class. This allows for a prefix to be placed in front of the
152      * incremented key. So if the prefix is "searchResults" and the nextObjectKey (local int that holds the key value)
153      * is 2 then
154      * the new key will be "searchResults3". "searchResults3" will be returned from the method.
155      *
156      * @param object
157      */
158     public String addObjectWithGeneratedKey(Serializable object, String keyPrefix) {
159         String objectKey = keyPrefix + nextObjectKey.incrementAndGet();
160         objectMap.put(objectKey, object);
161         return objectKey;
162     }
163 
164     /**
165      * allows adding an arbitrary object to the session and returns a string key that can be used to later access this
166      * object from
167      * the session using the retrieveObject method in this class. The key is generated from an integer and incremented
168      * for every
169      * object added.  So the first object added with have a key of "1".  This key will be returned from the method.
170      *
171      * @param object
172      */
173     public String addObjectWithGeneratedKey(Object object) {
174         String objectKey = nextObjectKey.incrementAndGet() + "";
175         objectMap.put(objectKey, object);
176         return objectKey;
177     }
178 
179     /**
180      * allows adding an arbitrary object to the session with static a string key that can be used to later access this
181      * object from
182      * the session using the retrieveObject method in this class
183      *
184      * @param object
185      */
186     public void addObject(String key, Object object) {
187         objectMap.put(key, object);
188     }
189 
190     /**
191      * allows for fetching an object that has been put into the userSession based on the key that would have been
192      * returned when
193      * adding the object
194      *
195      * @param objectKey
196      */
197     public Object retrieveObject(String objectKey) {
198         return this.objectMap.get(objectKey);
199     }
200 
201     /**
202      * allows for removal of an object from session that has been put into the userSession based on the key that would
203      * have been
204      * assigned
205      *
206      * @param objectKey
207      */
208     public void removeObject(String objectKey) {
209         this.objectMap.remove(objectKey);
210     }
211 
212     /**
213      * allows for removal of an object from session that has been put into the userSession based on a key that starts
214      * with the given
215      * prefix
216      */
217     public void removeObjectsByPrefix(String objectKeyPrefix) {
218         synchronized (objectMap) {
219             List<String> removeKeys = new ArrayList<String>();
220             for (String key : objectMap.keySet()) {
221                 if (key.startsWith(objectKeyPrefix)) {
222                     removeKeys.add(key);
223                 }
224             }
225 
226             for (String key : removeKeys) {
227                 this.objectMap.remove(key);
228             }
229         }
230     }
231 
232     /**
233      * @return boolean indicating if the backdoor is in use
234      */
235     public boolean isBackdoorInUse() {
236         return backdoorUser != null;
237     }
238 
239     /**
240      * Adds the given SessionTicket to the objectMap and returns the associated key
241      *
242      * @param ticket - SessionTicket to add
243      * @return the objectMap key for the ticket as a String
244      */
245     public String putSessionTicket(SessionTicket ticket) {
246         return addObjectWithGeneratedKey(ticket);
247     }
248 
249     /**
250      * Retrieves all SessionTicket instances currently in the UserSession#objectMap
251      *
252      * @return List<SessionTicket> contained in user session
253      */
254     public List<SessionTicket> getAllSessionTickets() {
255         List<SessionTicket> sessionTickets = new ArrayList<SessionTicket>();
256 
257         synchronized (objectMap) {
258             for (Object object : objectMap.values()) {
259                 if (object instanceof SessionTicket) {
260                     sessionTickets.add((SessionTicket) object);
261                 }
262             }
263         }
264 
265         return sessionTickets;
266     }
267 
268     /**
269      * Retrieves all SessionTicket instances currently in the UserSession#objectMap that are of a given ticket type
270      *
271      * @return List<SessionTicket> contained in user session
272      */
273     public List<SessionTicket> getAllSessionTicketsByType(String ticketTypeName) {
274         List<SessionTicket> sessionTickets = new ArrayList<SessionTicket>();
275 
276         for (SessionTicket ticket : getAllSessionTickets()) {
277             if (StringUtils.equalsIgnoreCase(ticket.getTicketTypeName(), ticketTypeName)) {
278                 sessionTickets.add(ticket);
279             }
280         }
281 
282         return sessionTickets;
283     }
284 
285     /**
286      * Determines if the UserSession contains a ticket of the given type that matches the given context. To match context
287      * the ticket must
288      * contain all the same keys at the given context and the values must be equal with the exception of case
289      *
290      * @param ticketTypeName - Name of the ticket type to match
291      * @param matchContext - Map on context parameters to match on
292      * @return true if a ticket was found in the UserSession that matches the request, false if one was not found
293      */
294     public boolean hasMatchingSessionTicket(String ticketTypeName, Map<String, String> matchContext) {
295         boolean hasTicket = false;
296 
297         for (SessionTicket ticket : getAllSessionTicketsByType(ticketTypeName)) {
298             Map<String, String> ticketContext = ticket.getTicketContext();
299 
300             boolean keySetMatch = ticketContext.keySet().equals(matchContext.keySet());
301             if (keySetMatch) {
302                 boolean valuesMatch = true;
303                 for (String contextKey : ticketContext.keySet()) {
304                     String ticketValue = ticketContext.get(contextKey);
305                     String matchValue = matchContext.get(contextKey);
306                     if (!StringUtils.equalsIgnoreCase(ticketValue, matchValue)) {
307                         valuesMatch = false;
308                     }
309                 }
310 
311                 if (valuesMatch) {
312                     hasTicket = true;
313                     break;
314                 }
315             }
316         }
317 
318         return hasTicket;
319     }
320 
321     /**
322      * retrieves an unmodifiable view of the objectMap.
323      */
324     public Map<String, Object> getObjectMap() {
325         return Collections.unmodifiableMap(this.objectMap);
326     }
327 }