001: /*
002: * Lucane - a collaborative platform
003: * Copyright (C) 2004 Vincent Fiack <vfiack@mail15.com>
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019: package org.lucane.server.acl;
020:
021: import java.sql.*;
022: import java.util.ArrayList;
023: import java.util.Iterator;
024:
025: import org.lucane.common.acl.AclInfo;
026: import org.lucane.common.concepts.*;
027: import org.lucane.server.store.*;
028: import org.lucane.server.Server;
029: import org.lucane.server.database.DatabaseAbstractionLayer;
030:
031: public class DefaultAccessController extends AccessController {
032: private static final String TABLENAME = "AccessControl";
033: private DatabaseAbstractionLayer layer;
034:
035: protected DefaultAccessController() throws Exception {
036: this .layer = Server.getInstance().getDBLayer();
037:
038: if (!layer.hasTable(TABLENAME)) {
039: String dbDescription = "jar:file:///"
040: + Server.getInstance().getWorkingDirectory()
041: + "lib/lucane-server-" + Server.VERSION + ".jar!/"
042: + "db-access-control.xml";
043:
044: layer.getTableCreator().createFromXml(dbDescription);
045: }
046: }
047:
048: /**
049: * Write an acl in database
050: */
051: private void writeAcl(String appName, String item, String access,
052: boolean allow, String groupName, String userName)
053: throws Exception {
054: Connection connection = layer.getConnection();
055: PreparedStatement insert = connection
056: .prepareStatement("INSERT INTO " + TABLENAME
057: + " VALUES(?, ?, ?, ?, ?, ?)");
058:
059: insert.setString(1, appName);
060: insert.setString(2, item);
061: insert.setString(3, access);
062: insert.setInt(4, allow ? 1 : 0);
063: if (groupName == null)
064: insert.setNull(5, Types.VARCHAR);
065: else
066: insert.setString(5, groupName);
067: if (userName == null)
068: insert.setNull(6, Types.VARCHAR);
069: else
070: insert.setString(6, userName);
071:
072: insert.execute();
073: insert.close();
074: connection.close();
075: }
076:
077: //-- interface : add ACL
078:
079: /**
080: * Allow access to an item for a user
081: */
082: public void allowUser(String appName, String item, String access,
083: String userName) throws Exception {
084: removeAclForUser(appName, item, access, userName);
085: writeAcl(appName, item, access, true, null, userName);
086: }
087:
088: /**
089: * Allow access to an item for a group
090: */
091: public void allowGroup(String appName, String item, String access,
092: String groupName) throws Exception {
093: removeAclForGroup(appName, item, access, groupName);
094: writeAcl(appName, item, access, true, groupName, null);
095: }
096:
097: /**
098: * Deny access to an item for a user
099: */
100: public void denyUser(String appName, String item, String access,
101: String userName) throws Exception {
102: removeAclForUser(appName, item, access, userName);
103: writeAcl(appName, item, access, false, null, userName);
104: }
105:
106: /**
107: * Deny access to an item for a group
108: */
109: public void denyGroup(String appName, String item, String access,
110: String groupName) throws Exception {
111: removeAclForGroup(appName, item, access, groupName);
112: writeAcl(appName, item, access, false, groupName, null);
113: }
114:
115: //-- interface : remove ACL
116:
117: /**
118: * Remove access information for a user on an item
119: */
120: public void removeAclForUser(String appName, String item,
121: String access, String userName) throws Exception {
122: Connection connection = layer.getConnection();
123: PreparedStatement delete = connection
124: .prepareStatement("DELETE FROM "
125: + TABLENAME
126: + " WHERE appName=? AND item=? AND access=? AND userName=?");
127:
128: delete.setString(1, appName);
129: delete.setString(2, item);
130: delete.setString(3, access);
131: delete.setString(4, userName);
132: delete.execute();
133:
134: delete.close();
135: connection.close();
136: }
137:
138: /**
139: * Remove access information for a group on an item
140: */
141: public void removeAclForGroup(String appName, String item,
142: String access, String groupName) throws Exception {
143: Connection connection = layer.getConnection();
144: PreparedStatement delete = connection
145: .prepareStatement("DELETE FROM "
146: + TABLENAME
147: + " WHERE appName=? AND item=? AND access=? AND groupName=?");
148:
149: delete.setString(1, appName);
150: delete.setString(2, item);
151: delete.setString(3, access);
152: delete.setString(4, groupName);
153: delete.execute();
154:
155: delete.close();
156: connection.close();
157: }
158:
159: //-- interface : read ACL
160:
161: /**
162: * Get all ACLS for a specific item
163: */
164: public AclInfo[] getAcls(String appName, String item)
165: throws Exception {
166: Connection connection = layer.getConnection();
167: PreparedStatement select = connection
168: .prepareStatement("SELECT access, allow, groupName, userName FROM "
169: + TABLENAME + " WHERE appName=? AND item=?");
170:
171: select.setString(1, appName);
172: select.setString(2, item);
173: ResultSet rs = select.executeQuery();
174:
175: ArrayList acls = new ArrayList();
176: while (rs.next()) {
177: String access = rs.getString(1);
178: int allow = rs.getInt(2);
179: String groupName = rs.getString(3);
180: String userName = rs.getString(4);
181:
182: AclInfo info = new AclInfo(access, allow == 1, groupName,
183: userName);
184: acls.add(info);
185: }
186:
187: rs.close();
188: select.close();
189: connection.close();
190:
191: AclInfo[] infos = new AclInfo[acls.size()];
192: for (int i = 0; i < acls.size(); i++)
193: infos[i] = (AclInfo) acls.get(i);
194:
195: return infos;
196: }
197:
198: /**
199: * Check if a userName is in a groupName
200: */
201: private boolean userNameIsInGroup(String userName, String groupName)
202: throws Exception {
203: UserStore userNameStore = Server.getInstance().getStore()
204: .getUserStore();
205: UserConcept concept = userNameStore.getUser(userName);
206: Iterator groups = userNameStore.getAllUserGroups(concept);
207:
208: while (groups.hasNext()) {
209: GroupConcept group = (GroupConcept) groups.next();
210: if (group.getName().equals(groupName))
211: return true;
212: }
213:
214: return false;
215: }
216:
217: /**
218: * Get all accesses for a user on an item
219: */
220: public String[] getAccesses(String appName, String item,
221: String userName) throws Exception {
222: AclInfo[] infos = getAcls(appName, item);
223: ArrayList allow = new ArrayList();
224: ArrayList deny = new ArrayList();
225:
226: //separate acl in allow and deny
227: //discard those that don't have anything to do with this userName
228: for (int i = 0; i < infos.length; i++) {
229: AclInfo info = infos[i];
230:
231: boolean userNameIsConcerned = (info.getUser() != null && info
232: .getUser().equals(userName));
233: if (!userNameIsConcerned)
234: userNameIsConcerned = (info.getGroup() != null && userNameIsInGroup(
235: userName, info.getGroup()));
236:
237: if (userNameIsConcerned && info.isAllow())
238: allow.add(info.getAccess());
239: else if (userNameIsConcerned && info.isDeny())
240: deny.add(info.getAccess());
241: }
242:
243: //deny is prioritary, so we remove denied accesses
244: allow.removeAll(deny);
245:
246: String[] accesses = new String[allow.size()];
247: for (int i = 0; i < allow.size(); i++)
248: accesses[i] = (String) allow.get(i);
249:
250: return accesses;
251: }
252:
253: /**
254: * Check if a userName has a specific access on an item
255: */
256: public boolean hasAccess(String appName, String item,
257: String access, String userName) throws Exception {
258: String[] accesses = getAccesses(appName, item, userName);
259: for (int i = 0; i < accesses.length; i++) {
260: if (accesses[i].equals(access))
261: return true;
262: }
263:
264: return false;
265: }
266:
267: //-- interface : remove ACL elements
268:
269: /**
270: * Remove an item and all linked ACLs
271: */
272: public void removeItem(String appName, String item)
273: throws Exception {
274: Connection connection = layer.getConnection();
275: PreparedStatement delete = connection
276: .prepareStatement("DELETE FROM " + TABLENAME
277: + " WHERE appName=? AND item=?");
278:
279: delete.setString(1, appName);
280: delete.setString(2, item);
281: delete.execute();
282:
283: delete.close();
284: connection.close();
285: }
286:
287: /**
288: * Remove an user and all linked ACLs
289: */
290: public void removeUser(String userName) throws Exception {
291: Connection connection = layer.getConnection();
292: PreparedStatement delete = connection
293: .prepareStatement("DELETE FROM " + TABLENAME
294: + " WHERE userName=?");
295:
296: delete.setString(1, userName);
297: delete.execute();
298:
299: delete.close();
300: connection.close();
301: }
302:
303: /**
304: * Remove an application and all linked ACLs
305: */
306: public void removeApplication(String appName) throws Exception {
307: Connection connection = layer.getConnection();
308: PreparedStatement delete = connection
309: .prepareStatement("DELETE FROM " + TABLENAME
310: + " WHERE appName=?");
311:
312: delete.setString(1, appName);
313: delete.execute();
314:
315: delete.close();
316: connection.close();
317: }
318:
319: /**
320: * Remove a group and all linked ACLs
321: */
322: public void removeGroup(String groupName) throws Exception {
323: Connection connection = layer.getConnection();
324: PreparedStatement delete = connection
325: .prepareStatement("DELETE FROM " + TABLENAME
326: + " WHERE groupName=?");
327:
328: delete.setString(1, groupName);
329: delete.execute();
330:
331: delete.close();
332: connection.close();
333: }
334: }
|