001 /*
002 * Copyright 2006-2011 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.kuali.rice.kns;
018
019 import org.apache.commons.lang.StringUtils;
020 import org.kuali.rice.core.api.config.property.ConfigContext;
021 import org.kuali.rice.core.api.exception.RiceRuntimeException;
022 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
023 import org.kuali.rice.kim.bo.Person;
024 import org.kuali.rice.kns.util.KNSConstants;
025 import org.kuali.rice.kns.util.SessionTicket;
026
027 import java.io.Serializable;
028 import java.util.ArrayList;
029 import java.util.Collections;
030 import java.util.HashMap;
031 import java.util.List;
032 import java.util.Map;
033
034
035 /**
036 * Holds info about the User Session
037 */
038 public class UserSession implements Serializable {
039
040 private static final long serialVersionUID = 4532616762540067557L;
041
042 private Person person;
043 private Person backdoorUser;
044 private int nextObjectKey;
045 private Map<String,Object> objectMap;
046 private String kualiSessionId;
047
048 /**
049 * @return the kualiSessionId
050 */
051 public String getKualiSessionId() {
052 return this.kualiSessionId;
053 }
054
055 /**
056 * @param kualiSessionId the kualiSessionId to set
057 */
058 public void setKualiSessionId(String kualiSessionId) {
059 this.kualiSessionId = kualiSessionId;
060 }
061
062 /**
063 * Take in a netid, and construct the user from that.
064 *
065 * @param principalName
066 */
067 public UserSession(String principalName) {
068 this.person = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(principalName);
069 if (this.person == null) {
070 throw new IllegalArgumentException("Failed to locate a principal with principal name '" + principalName + "'");
071 }
072 this.nextObjectKey = 0;
073 this.objectMap = new HashMap<String,Object>();
074 }
075
076
077 /**
078 * @return the principalId of the current user in the system, backdoor principalId if backdoor is set
079 */
080 public String getPrincipalId() {
081 if (backdoorUser != null) {
082 return backdoorUser.getPrincipalId();
083 }
084 return person.getPrincipalId();
085 }
086
087 /**
088 * @return the principalName of the current user in the system, backdoor principalName if backdoor is set
089 */
090 public String getPrincipalName() {
091 if (backdoorUser != null) {
092 return backdoorUser.getPrincipalName();
093 }
094 return person.getPrincipalName();
095 }
096
097
098 /**
099 * This returns who is logged in. If the backdoor is in use, this will return the network id of the person that is standing in
100 * as the backdoor user.
101 *
102 * @return String
103 */
104 public String getLoggedInUserPrincipalName() {
105 if ( person != null ) {
106 return person.getPrincipalName();
107 }
108 return "";
109 }
110
111 /**
112 * @return the KualiUser which is the current user in the system, backdoor if backdoor is set
113 */
114 public Person getPerson() {
115 if (backdoorUser != null) {
116 return backdoorUser;
117 }
118 return person;
119 }
120
121 /**
122 * override the current user in the system by setting the backdoor networkId, which is useful when dealing with 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().getProperty(KNSConstants.PROD_ENVIRONMENT_CODE_KEY).equalsIgnoreCase(
139 ConfigContext.getCurrentContextConfig().getProperty(KNSConstants.ENVIRONMENT_KEY));
140 }
141
142 /**
143 * clear the backdoor user
144 *
145 */
146 public void clearBackdoorUser() {
147 this.backdoorUser = null;
148 }
149
150 /**
151 * allows adding an arbitrary object to the session and returns a string key that can be used to later access this object from
152 * the session using the retrieveObject method in this class. This allows for a prefix to be placed in front of the
153 * incremented key. So if the prefix is "searchResults" and the nextObjectKey (local int that holds the key value) 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++;
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 object from
166 * the session using the retrieveObject method in this class. The key is generated from an integer and incremented for every
167 * object added. So the first object added with have a key of "1". This key will be returned from the method.
168 *
169 * @param object
170 */
171 public String addObjectWithGeneratedKey(Object object) {
172 String objectKey = nextObjectKey++ + "";
173 objectMap.put(objectKey, object);
174 return objectKey;
175 }
176
177 /**
178 * allows adding an arbitrary object to the session with static a string key that can be used to later access this object from
179 * the session using the retrieveObject method in this class
180 *
181 * @param object
182 *
183 */
184 public void addObject(String key, Object object) {
185
186 objectMap.put(key, object);
187
188 }
189
190 /**
191 * allows for fetching an object that has been put into the userSession based on the key that would have been returned when
192 * adding the object
193 *
194 * @param objectKey
195 */
196 public Object retrieveObject(String objectKey) {
197 return this.objectMap.get(objectKey);
198 }
199
200 /**
201 * allows for removal of an object from session that has been put into the userSession based on the key that would have been
202 * assigned
203 *
204 * @param objectKey
205 */
206 public void removeObject(String objectKey) {
207 this.objectMap.remove(objectKey);
208 }
209
210 /**
211 * allows for removal of an object from session that has been put into the userSession based on a key that starts with the given
212 * prefix
213 */
214 public void removeObjectsByPrefix(String objectKeyPrefix) {
215 List<String> removeKeys = new ArrayList<String>();
216 for (String key : objectMap.keySet()) {
217 if (key.startsWith(objectKeyPrefix)) {
218 removeKeys.add(key);
219 }
220 }
221
222 for (String key : removeKeys) {
223 this.objectMap.remove(key);
224 }
225 }
226
227 /**
228 * @return boolean indicating if the backdoor is in use
229 */
230 public boolean isBackdoorInUse() {
231 return backdoorUser != null;
232 }
233
234 /**
235 * Adds the given SessionTicket to the objectMap and returns the associated key
236 *
237 * @param ticket
238 * - SessionTicket to add
239 * @return the objectMap key for the ticket as a String
240 */
241 public String putSessionTicket(SessionTicket ticket) {
242 return addObjectWithGeneratedKey(ticket);
243 }
244
245 /**
246 * Retrieves all SessionTicket instances currently in the UserSession#objectMap
247 *
248 * @return List<SessionTicket> contained in user session
249 */
250 public List<SessionTicket> getAllSessionTickets() {
251 List<SessionTicket> sessionTickets = new ArrayList<SessionTicket>();
252
253 for (Object object : objectMap.values()) {
254 if (object instanceof SessionTicket) {
255 sessionTickets.add((SessionTicket) object);
256 }
257 }
258
259 return sessionTickets;
260 }
261
262 /**
263 * Retrieves all SessionTicket instances currently in the UserSession#objectMap that are of a given ticket type
264 *
265 * @return List<SessionTicket> contained in user session
266 */
267 public List<SessionTicket> getAllSessionTicketsByType(String ticketTypeName) {
268 List<SessionTicket> sessionTickets = new ArrayList<SessionTicket>();
269
270 for (SessionTicket ticket : getAllSessionTickets()) {
271 if (StringUtils.equalsIgnoreCase(ticket.getTicketTypeName(), ticketTypeName)) {
272 sessionTickets.add(ticket);
273 }
274 }
275
276 return sessionTickets;
277 }
278
279 /**
280 * Determines if the UserSession contains a ticket of the given type that matches the given context. To match context the ticket must
281 * contain all the same keys at the given context and the values must be equal with the exception of case
282 *
283 * @param ticketTypeName
284 * - Name of the ticket type to match
285 * @param matchContext
286 * - Map on context parameters to match on
287 * @return true if a ticket was found in the UserSession that matches the request, false if one was not found
288 */
289 public boolean hasMatchingSessionTicket(String ticketTypeName, Map<String, String> matchContext) {
290 boolean hasTicket = false;
291
292 for (SessionTicket ticket : getAllSessionTicketsByType(ticketTypeName)) {
293 Map<String, String> ticketContext = ticket.getTicketContext();
294
295 boolean keySetMatch = ticketContext.keySet().equals(matchContext.keySet());
296 if (keySetMatch) {
297 boolean valuesMatch = true;
298 for (String contextKey : ticketContext.keySet()) {
299 String ticketValue = ticketContext.get(contextKey);
300 String matchValue = matchContext.get(contextKey);
301 if (!StringUtils.equalsIgnoreCase(ticketValue, matchValue)) {
302 valuesMatch = false;
303 }
304 }
305
306 if (valuesMatch) {
307 hasTicket = true;
308 break;
309 }
310 }
311 }
312
313 return hasTicket;
314 }
315
316 /** retrieves an unmodifiable view of the objectMap. */
317 public Map<String, Object> getObjectMap() {
318 return Collections.unmodifiableMap(this.objectMap);
319 }
320 }