1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kim.sesn;
17
18 import java.util.Date;
19 import java.util.HashMap;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Map;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.kuali.rice.kim.sesn.timeouthandlers.TimeoutHandler;
27 import org.springframework.dao.IncorrectResultSizeDataAccessException;
28 import org.springframework.jdbc.core.JdbcTemplate;
29
30
31
32
33
34
35
36
37 public class DistributedSession {
38 public static final String DEFAULT_PREFIX="DST";
39 private static String prefix = DEFAULT_PREFIX;
40 private JdbcTemplate jdbcTemplate;
41 private TimeoutHandler timeoutHandler;
42 private boolean allowInsertOnTouch = false;
43
44 private static final Log logger = LogFactory.getLog(DistributedSession.class);
45
46
47
48
49 public void setTimeoutHandler(TimeoutHandler timeoutHandler) {
50 this.timeoutHandler = timeoutHandler;
51 }
52
53
54
55
56 public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
57 this.jdbcTemplate = jdbcTemplate;
58 }
59
60
61
62
63
64
65
66 public boolean isSesnValid(String DST) {
67 logger.debug("isSesnValid(DST)");
68 return isSesnValid (DST, new HashMap<String,Object>());
69 }
70
71
72
73
74
75
76
77
78 public boolean isSesnValid(String DST, Map<String,Object> timeoutArgs) {
79 logger.debug("isSesnValid(DST, timeoutArgs)");
80 boolean bRet = false;
81 String sql = "select sesnID, lastAccessDt, maxIdleTime from authnsesn where sesnID=?";
82
83 if (DST != null) {
84 Object[] args = { DST };
85
86 try {
87 Map<String,Object> fields = jdbcTemplate.queryForMap(sql, args);
88 fields.put("maxIdleTime", this.getMaxIdleTime((Long)fields.get("maxIdleTime"), (Date)fields.get("lastAccessDt")));
89 fields.putAll(timeoutArgs);
90
91 if (logger.isDebugEnabled()) {
92 logger.debug("ARGUMENTS number:" + fields.size());
93 for (Iterator<Map.Entry<String,Object>> i = fields.entrySet().iterator(); i.hasNext(); ) {
94 Map.Entry<String,Object> entry = (Map.Entry<String,Object>)i.next();
95 logger.debug("ARGUMENT " + entry.getKey() + ":" + entry.getValue());
96 }
97 }
98
99 if(!timeoutHandler.hasTimedOut(fields)) {
100 logger.debug("Session not timed out");
101 bRet = true;
102 } else {
103 logger.debug("Session timed out");
104 }
105 } catch (Exception e) {
106 logger.debug(e);
107 }
108 }
109 else {
110 logger.debug("Session ID is null");
111 }
112
113 return bRet;
114 }
115
116
117
118
119
120
121
122
123
124 public List<String> getAuthenticatedPricipals(String DST) {
125 String sql = "select principalID from authnsesn where sesnID=?";
126 Object args[] = { DST };
127
128 return jdbcTemplate.queryForList(sql, args, String.class);
129 }
130
131
132
133
134
135
136 public void clearSesn(String DST) {
137 String sql = "delete from authnsesn where sesnID='" + DST + "'";
138
139 jdbcTemplate.execute(sql);
140 }
141
142
143
144
145
146
147
148
149
150 public String createSesn(String principalID) {
151 String DST = this.generateDST();
152
153 this.touchSesn(DST);
154 this.addPrincipalToSesn(DST, principalID);
155
156 return DST;
157 }
158
159
160
161
162
163
164 public String generateDST() {
165 return prefix + "-" + SessionIdGenerator.getNewString();
166 }
167
168
169
170
171
172
173 public void touchSesn(String DST) {
174 String sql = "select lastAccessDt, maxIdleTime from authnsesn where sesnID=?";
175 String updateSql = "";
176 Object[] args = { DST },
177 updateArgs;
178 Long maxIdleTime;
179
180 try {
181 if (logger.isDebugEnabled()) {
182 logger.debug("ARGUMENTS number:" + args.length);
183 logger.debug("ARGUMENTS 0:" + args[0]);
184 }
185 Map<String,Object> fields = jdbcTemplate.queryForMap(sql, args);
186 Date lastAccessDt = (Date)fields.get("lastAccessDt");
187 if (logger.isDebugEnabled()) {
188 logger.debug("Last Access:" + lastAccessDt);
189 }
190 maxIdleTime = getMaxIdleTime((Long)fields.get("maxIdleTime"), lastAccessDt);
191
192
193 updateSql = "update authnsesn set lastAccessDt=NOW(), maxIdleTime = ? where sesnID=?";
194 updateArgs = new Object[] { maxIdleTime, DST };
195 jdbcTemplate.update(updateSql, updateArgs);
196 }
197
198 catch (IncorrectResultSizeDataAccessException ex) {
199 if (this.allowInsertOnTouch) {
200 maxIdleTime = new Long(0);
201
202 updateSql = "insert into authnsesn (sesnID, insertDt, lastAccessDt, maxIdleTime) values (?, NOW(), NOW(), ?)";
203 updateArgs = new Object[] { DST, maxIdleTime };
204 jdbcTemplate.update(updateSql, updateArgs);
205 }
206 }
207 }
208
209
210
211
212
213
214
215
216
217
218 public Long getMaxIdleTime(Long oldMaxIdleTime, Date lastAccessDt) {
219 Long maxIdleTime = oldMaxIdleTime;
220
221 if (logger.isDebugEnabled()) {
222 logger.debug("Max Idle:" + maxIdleTime);
223 }
224 long curIdleTime = System.currentTimeMillis()-lastAccessDt.getTime();
225 if (logger.isDebugEnabled()) {
226 logger.debug("Curr Idle:" + curIdleTime);
227 }
228 if (curIdleTime > maxIdleTime) {
229 maxIdleTime = new Long(curIdleTime);
230 }
231
232 return maxIdleTime;
233 }
234
235
236
237
238
239
240
241 public void addPrincipalToSesn(String DST, String principalID) {
242
243 try {
244 String updateSql = "insert into authnsesnprincipal (sesnID, principalID) values (?, ?)";
245
246 jdbcTemplate.update(updateSql, new Object[] { DST, principalID });
247 if (logger.isDebugEnabled()) {
248 logger.debug("Added Principal to Sesn:" + principalID + " " + DST);
249 }
250 }
251 catch (Exception e) {
252 if (logger.isDebugEnabled()) {
253 logger.debug("Principal Probably already exists:" + principalID + " " + DST);
254 }
255 }
256 }
257
258
259
260
261 public static String getPrefix() {
262 return DistributedSession.prefix;
263 }
264
265
266
267
268 public static void setPrefix(String prefix) {
269 DistributedSession.prefix = prefix;
270 }
271
272
273
274
275 public void setAllowInsertOnTouch(boolean allowInsertOnTouch) {
276 this.allowInsertOnTouch = allowInsertOnTouch;
277 }
278 }