001: /*
002: * (C) Copyright 2000 - 2006 Nabh Information Systems, Inc.
003: *
004: * This program is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU General Public License
006: * as published by the Free Software Foundation; either version 2
007: * of the License, or (at your option) any later version.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with this program; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: *
018: */
019: package com.nabhinc.portal.model;
020:
021: import java.io.Serializable;
022: import java.util.ArrayList;
023: import java.util.HashMap;
024: import java.util.List;
025:
026: import javax.servlet.ServletConfig;
027: import javax.servlet.ServletException;
028: import javax.servlet.http.HttpServletRequest;
029: import javax.xml.bind.annotation.XmlElement;
030: import javax.xml.bind.annotation.XmlRootElement;
031: import javax.xml.bind.annotation.XmlTransient;
032:
033: import com.nabhinc.condition.AccessControlEntry;
034: import com.nabhinc.condition.Condition;
035: import com.nabhinc.portal.core.PortletConfigInfo;
036: import com.nabhinc.util.StringUtil;
037:
038: /**
039: *
040: *
041: * @author Padmanabh Dabke
042: * (c) 2006 Nabh Information Systems, Inc. All Rights Reserved.
043: */
044: @XmlRootElement(name="portlet-access-controller")
045: public class PortletAccessController implements Serializable {
046: private static final long serialVersionUID = -3230319762085109553L;
047: private static PortletAccessController pacSelf = null;
048:
049: public PortletAccessController() {
050: PortletAccessController.pacSelf = this ;
051: }
052:
053: public static PortletAccessController getInstance() {
054: return PortletAccessController.pacSelf;
055: }
056:
057: @XmlTransient
058: private List<AccessControlEntry> pacEntries = new ArrayList<AccessControlEntry>();
059: private transient HashMap<String, Condition> pacACL = new HashMap<String, Condition>();
060:
061: @XmlElement(name="ac-entry")
062: public List<AccessControlEntry> getEntries() {
063: return this .pacEntries;
064: }
065:
066: public void setEntries(List<AccessControlEntry> entries) {
067: this .pacEntries = entries;
068: }
069:
070: /**
071: * Initialize this object from an XML Element.
072: * @param config XML element specifying initialization properties
073: * @exception java.lang.Exception Implementation specific exception
074: */
075: public void init(ServletConfig config) throws ServletException {
076:
077: for (int i = 0; i < pacEntries.size(); i++) {
078: AccessControlEntry entry = pacEntries.get(i);
079: if (StringUtil.isNullOrEmpty(entry.items))
080: throw new ServletException(
081: "Invalid or unspecified portlets in access control entry.");
082: if (entry.condition == null)
083: throw new ServletException(
084: "Missing access control condition.");
085:
086: String[] pArray = StringUtil.split(entry.items, ",");
087: String[] actionArray = null;
088: if (StringUtil.isNotNullOrEmpty(entry.actions))
089: actionArray = StringUtil.split(entry.actions, ",");
090: cachePermissionEntry(pArray, actionArray, entry.condition);
091:
092: }
093: }
094:
095: private void cachePermissionEntry(String[] pArray,
096: String[] actionArray, Condition precon) {
097: if (actionArray == null || actionArray.length == 0) {
098: for (int j = 0; j < pArray.length; j++) {
099: pacACL.put(pArray[j], precon);
100: }
101: } else {
102: for (int j = 0; j < actionArray.length; j++) {
103: actionArray[j] = actionArray[j].toLowerCase();
104: }
105: for (int j = 0; j < actionArray.length; j++) {
106: for (int k = 0; k < pArray.length; k++) {
107: pacACL.put(pArray[k] + "\n" + actionArray[j],
108: precon);
109: }
110: }
111: }
112:
113: }
114:
115: private void uncachePermissionEntry(String portlets, String actions) {
116: String[] pArray = StringUtil.split(portlets, ",");
117: String[] actionArray = null;
118: if (actions != null) {
119: actionArray = StringUtil.split(actions, ",");
120: }
121: if (actionArray == null) {
122: for (int j = 0; j < pArray.length; j++) {
123: pacACL.remove(pArray[j]);
124: }
125: } else {
126: for (int j = 0; j < actionArray.length; j++) {
127: actionArray[j] = actionArray[j].toLowerCase();
128: }
129: for (int j = 0; j < actionArray.length; j++) {
130: for (int k = 0; k < pArray.length; k++) {
131: pacACL.remove(pArray[k] + "\n" + actionArray[j]);
132: }
133: }
134: }
135:
136: }
137:
138: public boolean addPermissionEntry(String[] pArray,
139: String[] actionArray, Condition precon) {
140: if (isConflict(pArray, actionArray))
141: return false;
142: cachePermissionEntry(pArray, actionArray, precon);
143:
144: AccessControlEntry entry = new AccessControlEntry();
145: entry.items = StringUtil.join(pArray, ",");
146: entry.condition = precon;
147: if (actionArray != null && actionArray.length > 0) {
148: entry.actions = StringUtil.join(actionArray, ",");
149: }
150: this .pacEntries.add(entry);
151:
152: return true;
153: }
154:
155: public void removePermissionEntry(int index) {
156: if (index < 0 || index >= pacEntries.size())
157: return;
158:
159: AccessControlEntry entry = pacEntries.get(index);
160: uncachePermissionEntry(entry.items, entry.actions);
161: pacEntries.remove(index);
162: }
163:
164: public boolean replacePermissionEntry(int index, String[] pArray,
165: String[] actionArray, Condition precon) {
166: if (index < 0 || index >= pacEntries.size())
167: return false;
168: AccessControlEntry entry = pacEntries.get(index);
169: uncachePermissionEntry(entry.items, entry.actions);
170: if (isConflict(pArray, actionArray)) {
171: cachePermissionEntry(StringUtil.split(entry.items, ","),
172: StringUtil.split(entry.actions, ","),
173: entry.condition);
174: return false;
175: }
176: entry.items = StringUtil.join(pArray, ",");
177: entry.condition = precon;
178: if (actionArray != null && actionArray.length > 0) {
179: entry.actions = StringUtil.join(actionArray, ",");
180: }
181: cachePermissionEntry(pArray, actionArray, precon);
182: return true;
183: }
184:
185: /**
186: * Returns true if the given portlet can be accessed by the current
187: * request.
188: */
189: public boolean isAccessible(HttpServletRequest req,
190: PortletConfigInfo p, String portletMode)
191: throws ServletException {
192: Condition pre = (Condition) pacACL.get(p.name);
193: if (pre == null)
194: pre = (Condition) pacACL.get(p.name + "\n"
195: + portletMode.toLowerCase());
196:
197: if (pre == null)
198: return true;
199: else
200: return pre.isSatisfied(req, p.portlet);
201: }
202:
203: public boolean isConflict(String[] portlets, String[] actions) {
204:
205: for (int i = 0; i < portlets.length; i++) {
206: if (pacACL.get(portlets[i]) != null) {
207: return true;
208: }
209: }
210:
211: if (actions != null && actions.length > 0) {
212: for (int j = 0; j < actions.length; j++) {
213: for (int i = 0; i < portlets.length; i++) {
214: if (pacACL.get(portlets[i] + "\n" + actions[j]) != null) {
215: return true;
216: }
217: }
218:
219: }
220:
221: }
222:
223: return false;
224: }
225:
226: public boolean isAccessible(HttpServletRequest req, String name,
227: int type, String pMode) throws Exception {
228: Condition pre = (Condition) pacACL.get(name);
229: if (pre == null)
230: pre = (Condition) pacACL.get(name + "\n"
231: + pMode.toLowerCase());
232:
233: if (pre == null)
234: return true;
235: else
236: return pre.isSatisfied(req, name);
237: }
238:
239: }
|