001: /*
002: * Copyright 2001-2006 C:1 Financial Services GmbH
003: *
004: * This software is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License Version 2.1, as published by the Free Software Foundation.
007: *
008: * This software is distributed in the hope that it will be useful,
009: * but WITHOUT ANY WARRANTY; without even the implied warranty of
010: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
011: * Lesser General Public License for more details.
012: *
013: * You should have received a copy of the GNU Lesser General Public
014: * License along with this library; if not, write to the Free Software
015: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
016: */
017:
018: package de.finix.contelligent.core.security;
019:
020: import java.security.acl.Permission;
021:
022: import de.finix.contelligent.CallData;
023: import de.finix.contelligent.logging.LoggingService;
024:
025: /**
026: * The class <code>ComponentAccess</code> holds
027: * <p>
028: * There are four possible states of a Permission:
029: * <UL>
030: * <LI> not set at all
031: * <LI> (+) set
032: * <LI> (-) unset
033: * <LI> ( ) explicitly reset
034: * </UL>
035: * What does this mean?
036: */
037: public class ComponentAccess implements AclEntry {
038: final static org.apache.log4j.Logger log = LoggingService
039: .getLogger(ComponentAccess.class);
040:
041: final static public EntryMode RESET = new EntryMode(0, "RESET");
042:
043: final static public EntryMode ALLOW = new EntryMode(+1, "ALLOW");
044:
045: final static public EntryMode DENY = new EntryMode(-1, "DENY");
046:
047: static public class EntryMode implements AclEntry.Mode {
048: final private int mode;
049:
050: final private String modeString;
051:
052: final private int hashCode;
053:
054: EntryMode(int mode, String modeString) {
055: this .mode = mode;
056: this .modeString = modeString;
057: this .hashCode = toString().hashCode();
058: }
059:
060: // public int value() { return mode; }
061:
062: public String toString() {
063: return modeString;
064: }
065:
066: public int hashCode() {
067: return hashCode;
068: }
069:
070: public boolean equals(Object anObject) {
071: if (this == anObject) {
072: return true;
073: }
074: if (anObject instanceof EntryMode) {
075: EntryMode anotherEntryMode = (EntryMode) anObject;
076: return (this .mode == anotherEntryMode.mode);
077: }
078: return false;
079: }
080: }// class EntryMode
081:
082: /**
083: * The {@link ContelligentPrincipal} for whom this AclEntry is for.
084: */
085: final private ContelligentPrincipal principal;
086:
087: final private Permission permission;
088:
089: final private int hashCode;
090:
091: private AclEntry.Mode mode;
092:
093: private boolean isInherited = false;
094:
095: final private long validFrom;
096:
097: final private long validTo;
098:
099: final private long period;
100:
101: final private long duration;
102:
103: public ComponentAccess(ContelligentPrincipal principal,
104: AclEntry.Mode mode, Permission permission, long validFrom,
105: long validTo, long period, long duration) {
106: this .principal = principal;
107: this .mode = mode;
108: this .permission = permission;
109: this .validFrom = validFrom;
110: this .validTo = validTo;
111: this .period = period;
112: this .duration = duration;
113: hashCode = (principal.toString() + permission.toString())
114: .hashCode();
115: }
116:
117: public ComponentAccess(ContelligentPrincipal principal,
118: Permission permission, long validFrom, long validTo,
119: long period, long duration) {
120: this (principal, ALLOW, permission, validFrom, validTo, period,
121: duration);
122: }
123:
124: public static AclEntry.Mode getEntryModeByName(String mode) {
125: mode = mode.toUpperCase();
126: if (mode.equals("DENY")) {
127: return DENY;
128: }
129: if (mode.equals("ALLOW")) {
130: return ALLOW;
131: }
132: return RESET;
133: }
134:
135: // ============================================================================
136: // methods of interface AclEntry
137: // ============================================================================
138:
139: /**
140: * Implementation of {@link AclEntry#getPrincipal}. Returns the principal
141: * for which permissions are granted or denied by this ACL entry. Returns
142: * null if there is no principal set for this entry yet.
143: *
144: * @return the principal associated with this entry.
145: * @see AclEntry#getPrincipal
146: */
147: public ContelligentPrincipal getPrincipal() {
148: return principal;
149: }
150:
151: /**
152: * Checks if the specified permission is part of the permission set in this
153: * entry.
154: *
155: * @param permission
156: * the permission to be checked for.
157: *
158: * @return true if the permission is part of the permission set in this
159: * entry, false otherwise.
160: */
161: public boolean checkPermission(Permission permission) {
162: return permission.equals(permission);
163: }
164:
165: /**
166: * Returns a string representation of the contents of this ACL entry.
167: *
168: * @return a string representation of the contents.
169: */
170: public String toString() {
171: return ("ComponentAccess[" + mode + " principal '" + principal
172: + "' " + permission.toString() + "]");
173: }
174:
175: /**
176: * Clones this ACL entry.
177: *
178: * @return a clone of this ACL entry.
179: */
180: public Object clone() {
181: ComponentAccess clone = new ComponentAccess(principal, mode,
182: permission, validFrom, validTo, period, duration);
183: clone.isInherited = this .isInherited;
184: return clone;
185: }
186:
187: public int hashCode() {
188: return hashCode;
189: }
190:
191: /**
192: * Describe <code>equals</code> method here.
193: *
194: * @param anObject
195: * an <code>Object</code> value
196: * @return a <code>boolean</code> value
197: */
198: public boolean equals(Object anObject) {
199: if (this == anObject) {
200: return true;
201: }
202: if (anObject instanceof AclEntry) {
203: AclEntry anotherAclEntry = (AclEntry) anObject;
204: if (log.isDebugEnabled()) {
205: log.debug("equals() - comparing aclEntries '" + this
206: + "' and '" + anotherAclEntry + "' ...");
207: boolean result = (this .getPrincipal().equals(
208: anotherAclEntry.getPrincipal()) && this
209: .getPermission().equals(
210: anotherAclEntry.getPermission()));
211: log.debug("equals() - result is: " + result);
212: return result;
213: } else {
214: return (this .getPrincipal().equals(
215: anotherAclEntry.getPrincipal()) && this
216: .getPermission().equals(
217: anotherAclEntry.getPermission()));
218: }
219: }
220: return false;
221: }
222:
223: public Permission getPermission() {
224: return permission;
225: }
226:
227: public void setMode(AclEntry.Mode mode) {
228: this .mode = mode;
229: }
230:
231: public AclEntry.Mode getMode() {
232: return mode;
233: }
234:
235: /**
236: * See {@link AclEntry#isInherited} for a description.
237: *
238: * @return a <code>boolean</code> value
239: */
240: public boolean isInherited() {
241: return isInherited;
242: }
243:
244: /**
245: * See {@link AclEntry#setIsInherited} for a description.
246: *
247: * @param isInherited
248: * a <code>boolean</code> value
249: */
250: public void setIsInherited(boolean isInherited) {
251: this .isInherited = isInherited;
252: }
253:
254: public long getValidFrom() {
255: return validFrom;
256: }
257:
258: public long getValidTo() {
259: return validTo;
260: }
261:
262: public long getPeriod() {
263: return period;
264: }
265:
266: public long getDuration() {
267: return duration;
268: }
269:
270: /**
271: * Determines whether this ACL entry should be applied, considering the
272: * effective timestamp of the request.
273: */
274: public boolean isValid(CallData callData) {
275: if ((validFrom == -1) && (validTo == -1) && (period == -1)
276: && (duration == -1)) {
277: return true;
278: }
279: if (callData == null) {
280: return false;
281: }
282: long timeStamp = callData.getRequestTimeStamp();
283: if (!(((timeStamp >= validFrom) || (validFrom == -1)) && ((timeStamp <= validTo) || (validTo == -1)))) {
284: return false;
285: }
286: if (period != -1) {
287: if (validFrom == -1) {
288: log
289: .warn("Invalid ACL combination; period specified but no start time available.");
290: return false;
291: }
292: long currentOffset = (timeStamp - validFrom) % period;
293: if (currentOffset > duration) {
294: return false;
295: }
296: }
297: // All checks went through; apply this ACL entry
298: return true;
299: }
300:
301: }
|