001: /*
002: * Copyright 2007 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.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/ecl1.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: package edu.yale.its.tp.cas.ticket;
017:
018: import java.security.SecureRandom;
019: import java.util.Collections;
020: import java.util.HashMap;
021: import java.util.Map;
022:
023: /**
024: * Represents a generic cache of granting tickets. Can be used as a store for TGCs or PGTs.
025: */
026: public class GrantorCache extends ActiveTicketCache {
027:
028: // *********************************************************************
029: // KFSConstants
030:
031: /** Length of random ticket identifiers. */
032: private static final int TICKET_ID_LENGTH = 50;
033:
034: // *********************************************************************
035: // Private state
036:
037: /** The actual cache of tickets (ticketId -> Ticket map) */
038: private Map ticketCache;
039:
040: /** The specific type of tickets the cache stores. */
041: private Class ticketType;
042:
043: /** Monotonically increasing serial number for tickets. */
044: private static int serial = 0;
045:
046: // *********************************************************************
047: // Constructor
048:
049: /**
050: * Constructs a new GrantorCache that is intended to store cookies of the given specific ticket type.
051: */
052: public GrantorCache(Class ticketType, int tolerance) {
053: super (tolerance);
054: if (!TicketGrantingTicket.class.isAssignableFrom(ticketType))
055: throw new IllegalArgumentException(
056: "GrantorCache may only store granting tickets");
057: this .ticketType = ticketType;
058: this .ticketCache = Collections.synchronizedMap(new HashMap());
059: }
060:
061: // *********************************************************************
062: // Cache-management logic
063:
064: /** Generates and returns a new, unique ticket ID */
065: protected String newTicketId() {
066: // determine appropriate ticketId prefix
067: String prefix;
068: if (ticketType == TicketGrantingTicket.class)
069: prefix = "TGC";
070: else if (ticketType == ProxyGrantingTicket.class)
071: prefix = "PGT";
072: else
073: prefix = "UNK";
074:
075: // produce the random identifier
076: byte[] b = new byte[TICKET_ID_LENGTH];
077: SecureRandom sr = new SecureRandom();
078: sr.nextBytes(b);
079: String ticketId = prefix + "-" + (serial++) + "-"
080: + Util.toPrintable(b);
081:
082: // make sure the identifier isn't already used
083: if (ticketCache.get(ticketId) != null)
084: return newTicketId(); // tail-recurse
085: else
086: return ticketId;
087: }
088:
089: /** Stores the given ticket, associating it with the given identifier. */
090: protected void storeTicket(String ticketId, Ticket t)
091: throws TicketException {
092: // make sure the ticket is valid and new
093: if (ticketCache.get(ticketId) != null)
094: throw new DuplicateTicketException();
095: if (!t.getClass().equals(ticketType))
096: throw new InvalidTicketException("got " + t.getClass()
097: + "; needed " + ticketType);
098:
099: // if it's okay, then store it
100: ticketCache.put(ticketId, t);
101: }
102:
103: /** Retrieves the ticket with the given identifier. */
104: protected Ticket retrieveTicket(String ticketId) {
105: Object o = ticketCache.get(ticketId);
106: if (o == null || ((TicketGrantingTicket) o).isExpired())
107: return null;
108: else
109: return (Ticket) o;
110: }
111:
112: /** Removes the ticket from the cache, and expires the ticket itself. */
113: public void deleteTicket(String ticketId) {
114: Object o = ticketCache.remove(ticketId);
115: if (o == null)
116: return;
117: TicketGrantingTicket t = (TicketGrantingTicket) o;
118: t.expire();
119: }
120:
121: /** Returns the number of grantors in the grantor cache. */
122: public int getCacheSize() {
123: return ticketCache.size();
124: }
125: }
|