001: /*
002: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.tomcat.session;
006:
007: import org.apache.catalina.Manager;
008: import org.apache.catalina.Realm;
009: import org.apache.catalina.Session;
010: import org.apache.catalina.SessionListener;
011: import org.apache.catalina.realm.GenericPrincipal;
012:
013: import com.terracotta.session.SessionData;
014:
015: import java.io.ByteArrayInputStream;
016: import java.io.ByteArrayOutputStream;
017: import java.io.IOException;
018: import java.io.ObjectInputStream;
019: import java.io.ObjectOutputStream;
020: import java.security.Principal;
021: import java.util.ArrayList;
022: import java.util.Collection;
023: import java.util.Iterator;
024: import java.util.List;
025:
026: import javax.servlet.http.HttpSession;
027:
028: public class SessionInternal implements Session {
029:
030: private static final String AUTH_TYPE = "tomcatAuthType";
031: private static final String NOTE = "tomcatNote";
032: private static final String TOMCAT_PRINCIPAL = "tomcatPrincipal";
033: private static final String PORTABLE_PRINCIPAL = "tomcatPortablePrincipal";
034:
035: private final com.terracotta.session.Session tcSession;
036: private final SessionData sessionData;
037: private final Realm realm;
038:
039: public SessionInternal(com.terracotta.session.Session tcSession,
040: Realm realm) {
041: this .tcSession = tcSession;
042: this .sessionData = tcSession.getSessionData();
043: this .realm = realm;
044: }
045:
046: public void access() {
047: //
048: }
049:
050: public void addSessionListener(SessionListener listener) {
051: //
052: }
053:
054: public void endAccess() {
055: //
056: }
057:
058: public void expire() {
059: throw new UnsupportedOperationException();
060: }
061:
062: public String getAuthType() {
063: return (String) sessionData.getTransientAttribute(AUTH_TYPE);
064: }
065:
066: public long getCreationTime() {
067: return tcSession.getCreationTime();
068: }
069:
070: public String getId() {
071: return tcSession.getId();
072: }
073:
074: public String getIdInternal() {
075: return tcSession.getId();
076: }
077:
078: public String getInfo() {
079: return "TerracottaSessionInternal";
080: }
081:
082: public long getLastAccessedTime() {
083: return tcSession.getLastAccessedTime();
084: }
085:
086: public long getLastAccessedTimeInternal() {
087: throw new UnsupportedOperationException();
088: }
089:
090: public Manager getManager() {
091: throw new UnsupportedOperationException();
092: }
093:
094: public int getMaxInactiveInterval() {
095: return tcSession.getMaxInactiveInterval();
096: }
097:
098: public Object getNote(String name) {
099: return sessionData.getTransientAttribute(makeNoteName(name));
100: }
101:
102: public Iterator getNoteNames() {
103: Collection keys = sessionData.getTransientAttributeKeys();
104: for (Iterator i = keys.iterator(); i.hasNext();) {
105: String key = (String) i.next();
106: if (!key.startsWith(NOTE)) {
107: i.remove();
108: }
109: }
110:
111: return keys.iterator();
112: }
113:
114: public Principal getPrincipal() {
115: Principal p = (Principal) sessionData
116: .getInternalAttribute(PORTABLE_PRINCIPAL);
117: if (p != null) {
118: return p;
119: }
120:
121: byte[] principal = (byte[]) sessionData
122: .getInternalAttribute(TOMCAT_PRINCIPAL);
123: if (principal != null) {
124: return deserializeGenericPrincipal(principal);
125: }
126:
127: return null;
128: }
129:
130: public HttpSession getSession() {
131: return tcSession;
132: }
133:
134: public boolean isValid() {
135: return tcSession.isValid();
136: }
137:
138: public void recycle() {
139: //
140: }
141:
142: public void removeNote(String name) {
143: sessionData.removeTransientAttribute(makeNoteName(name));
144: }
145:
146: public void removeSessionListener(SessionListener listener) {
147: //
148: }
149:
150: public void setAuthType(String authType) {
151: sessionData.setTransientAttribute(AUTH_TYPE, authType);
152: }
153:
154: public void setCreationTime(long time) {
155: throw new UnsupportedOperationException();
156: }
157:
158: public void setId(String id) {
159: throw new UnsupportedOperationException();
160: }
161:
162: public void setManager(Manager manager) {
163: throw new UnsupportedOperationException();
164: }
165:
166: public void setMaxInactiveInterval(int interval) {
167: throw new UnsupportedOperationException();
168: }
169:
170: public void setNew(boolean isNew) {
171: throw new UnsupportedOperationException();
172: }
173:
174: public void setNote(String name, Object value) {
175: sessionData.setTransientAttribute(makeNoteName(name), value);
176: }
177:
178: public void setPrincipal(Principal principal) {
179: if (principal == null) {
180: sessionData.removeInternalAttribute(TOMCAT_PRINCIPAL);
181: sessionData.removeAttribute(PORTABLE_PRINCIPAL);
182: }
183:
184: final boolean isTomcatInternalPrincipal = (principal instanceof GenericPrincipal);
185: sessionData
186: .removeAttribute(isTomcatInternalPrincipal ? PORTABLE_PRINCIPAL
187: : TOMCAT_PRINCIPAL);
188:
189: if (isTomcatInternalPrincipal) {
190: sessionData
191: .setInternalAttribute(
192: TOMCAT_PRINCIPAL,
193: serializeGenericPrincipal((GenericPrincipal) principal));
194: } else {
195: sessionData.setInternalAttribute(PORTABLE_PRINCIPAL,
196: principal);
197: }
198: }
199:
200: private static byte[] serializeGenericPrincipal(
201: GenericPrincipal principal) {
202: ByteArrayOutputStream baos = new ByteArrayOutputStream();
203:
204: try {
205: ObjectOutputStream oos = new ObjectOutputStream(baos);
206:
207: oos.writeUTF(principal.getName());
208:
209: oos.writeBoolean(principal.getPassword() != null);
210: if (principal.getPassword() != null)
211: oos.writeUTF(principal.getPassword());
212:
213: String[] roles = principal.getRoles();
214: if (roles == null)
215: roles = new String[] {};
216: oos.writeInt(roles.length);
217: for (int i = 0; i < roles.length; i++)
218: oos.writeUTF(roles[i]);
219:
220: oos.flush();
221: } catch (IOException e) {
222: throw new RuntimeException("Error serializing principal", e);
223: }
224:
225: return baos.toByteArray();
226: }
227:
228: private GenericPrincipal deserializeGenericPrincipal(byte[] data) {
229: try {
230: ObjectInputStream ois = new ObjectInputStream(
231: new ByteArrayInputStream(data));
232:
233: String name = ois.readUTF();
234: boolean nonNullPasswd = ois.readBoolean();
235: String passwd = null;
236: if (nonNullPasswd)
237: passwd = ois.readUTF();
238: int numRoles = ois.readInt();
239:
240: List roles = new ArrayList();
241:
242: for (int i = 0; i < numRoles; i++)
243: roles.add(ois.readUTF());
244: return new GenericPrincipal(realm, name, passwd, roles);
245: } catch (IOException ioe) {
246: throw new RuntimeException(
247: "Error deserializing principal: " + ioe);
248: }
249: }
250:
251: public void setValid(boolean isValid) {
252: throw new UnsupportedOperationException();
253: }
254:
255: private static String makeNoteName(String name) {
256: return NOTE + name;
257: }
258:
259: }
|