Source Code Cross Referenced for AclImpl.java in  » Security » acegi-security » org » acegisecurity » acls » domain » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Security » acegi security » org.acegisecurity.acls.domain 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
002:         *
003:         * Licensed under the Apache License, Version 2.0 (the "License");
004:         * you may not use this file except in compliance with the License.
005:         * You may obtain a copy of the License at
006:         *
007:         *     http://www.apache.org/licenses/LICENSE-2.0
008:         *
009:         * Unless required by applicable law or agreed to in writing, software
010:         * distributed under the License is distributed on an "AS IS" BASIS,
011:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012:         * See the License for the specific language governing permissions and
013:         * limitations under the License.
014:         */
015:        package org.acegisecurity.acls.domain;
016:
017:        import org.acegisecurity.acls.AccessControlEntry;
018:        import org.acegisecurity.acls.Acl;
019:        import org.acegisecurity.acls.AuditableAcl;
020:        import org.acegisecurity.acls.MutableAcl;
021:        import org.acegisecurity.acls.NotFoundException;
022:        import org.acegisecurity.acls.OwnershipAcl;
023:        import org.acegisecurity.acls.Permission;
024:        import org.acegisecurity.acls.UnloadedSidException;
025:        import org.acegisecurity.acls.objectidentity.ObjectIdentity;
026:        import org.acegisecurity.acls.sid.Sid;
027:
028:        import org.springframework.util.Assert;
029:
030:        import java.io.Serializable;
031:
032:        import java.util.Iterator;
033:        import java.util.List;
034:        import java.util.Vector;
035:
036:        /**
037:         * Base implementation of <code>Acl</code>.
038:         *
039:         * @author Ben Alex
040:         * @version $Id
041:         */
042:        public class AclImpl implements  Acl, MutableAcl, AuditableAcl,
043:                OwnershipAcl {
044:            //~ Instance fields ================================================================================================
045:
046:            private Acl parentAcl;
047:            private AclAuthorizationStrategy aclAuthorizationStrategy;
048:            private AuditLogger auditLogger;
049:            private List aces = new Vector();
050:            private ObjectIdentity objectIdentity;
051:            private Serializable id;
052:            private Sid owner; // OwnershipAcl
053:            private Sid[] loadedSids = null; // includes all SIDs the WHERE clause covered, even if there was no ACE for a SID
054:            private boolean entriesInheriting = true;
055:
056:            //~ Constructors ===================================================================================================
057:
058:            /**
059:             * Minimal constructor, which should be used {@link
060:             * org.acegisecurity.acls.MutableAclService#createAcl(ObjectIdentity)}.
061:             *
062:             * @param objectIdentity the object identity this ACL relates to (required)
063:             * @param id the primary key assigned to this ACL (required)
064:             * @param aclAuthorizationStrategy authorization strategy (required)
065:             * @param auditLogger audit logger (required)
066:             */
067:            public AclImpl(ObjectIdentity objectIdentity, Serializable id,
068:                    AclAuthorizationStrategy aclAuthorizationStrategy,
069:                    AuditLogger auditLogger) {
070:                Assert.notNull(objectIdentity, "Object Identity required");
071:                Assert.notNull(id, "Id required");
072:                Assert.notNull(aclAuthorizationStrategy,
073:                        "AclAuthorizationStrategy required");
074:                Assert.notNull(auditLogger, "AuditLogger required");
075:                this .objectIdentity = objectIdentity;
076:                this .id = id;
077:                this .aclAuthorizationStrategy = aclAuthorizationStrategy;
078:                this .auditLogger = auditLogger;
079:            }
080:
081:            /**
082:             * Full constructor, which should be used by persistence tools that do not
083:             * provide field-level access features.
084:             *
085:             * @param objectIdentity the object identity this ACL relates to (required)
086:             * @param id the primary key assigned to this ACL (required)
087:             * @param aclAuthorizationStrategy authorization strategy (required)
088:             * @param auditLogger audit logger (required)
089:             * @param parentAcl the parent (may be <code>null</code>)
090:             * @param loadedSids the loaded SIDs if only a subset were loaded (may be
091:             *        <code>null</code>)
092:             * @param entriesInheriting if ACEs from the parent should inherit into
093:             *        this ACL
094:             * @param owner the owner (required)
095:             */
096:            public AclImpl(ObjectIdentity objectIdentity, Serializable id,
097:                    AclAuthorizationStrategy aclAuthorizationStrategy,
098:                    AuditLogger auditLogger, Acl parentAcl, Sid[] loadedSids,
099:                    boolean entriesInheriting, Sid owner) {
100:                Assert.notNull(objectIdentity, "Object Identity required");
101:                Assert.notNull(id, "Id required");
102:                Assert.notNull(aclAuthorizationStrategy,
103:                        "AclAuthorizationStrategy required");
104:                Assert.notNull(owner, "Owner required");
105:                Assert.notNull(auditLogger, "AuditLogger required");
106:                this .objectIdentity = objectIdentity;
107:                this .id = id;
108:                this .aclAuthorizationStrategy = aclAuthorizationStrategy;
109:                this .auditLogger = auditLogger;
110:                this .parentAcl = parentAcl; // may be null
111:                this .loadedSids = loadedSids; // may be null
112:                this .entriesInheriting = entriesInheriting;
113:                this .owner = owner;
114:            }
115:
116:            /**
117:             * Private no-argument constructor for use by reflection-based persistence
118:             * tools along with field-level access.
119:             */
120:            private AclImpl() {
121:            }
122:
123:            //~ Methods ========================================================================================================
124:
125:            public void deleteAce(Serializable aceId) throws NotFoundException {
126:                aclAuthorizationStrategy.securityCheck(this ,
127:                        AclAuthorizationStrategy.CHANGE_GENERAL);
128:
129:                synchronized (aces) {
130:                    int offset = findAceOffset(aceId);
131:
132:                    if (offset == -1) {
133:                        throw new NotFoundException(
134:                                "Requested ACE ID not found");
135:                    }
136:
137:                    this .aces.remove(offset);
138:                }
139:            }
140:
141:            private int findAceOffset(Serializable aceId) {
142:                Assert.notNull(aceId, "ACE ID is required");
143:
144:                synchronized (aces) {
145:                    for (int i = 0; i < aces.size(); i++) {
146:                        AccessControlEntry ace = (AccessControlEntry) aces
147:                                .get(i);
148:
149:                        if (ace.getId().equals(aceId)) {
150:                            return i;
151:                        }
152:                    }
153:                }
154:
155:                return -1;
156:            }
157:
158:            public AccessControlEntry[] getEntries() {
159:                // Can safely return AccessControlEntry directly, as they're immutable outside the ACL package
160:                return (AccessControlEntry[]) aces
161:                        .toArray(new AccessControlEntry[] {});
162:            }
163:
164:            public Serializable getId() {
165:                return this .id;
166:            }
167:
168:            public ObjectIdentity getObjectIdentity() {
169:                return objectIdentity;
170:            }
171:
172:            public Sid getOwner() {
173:                return this .owner;
174:            }
175:
176:            public Acl getParentAcl() {
177:                return parentAcl;
178:            }
179:
180:            public void insertAce(Serializable afterAceId,
181:                    Permission permission, Sid sid, boolean granting)
182:                    throws NotFoundException {
183:                aclAuthorizationStrategy.securityCheck(this ,
184:                        AclAuthorizationStrategy.CHANGE_GENERAL);
185:                Assert.notNull(permission, "Permission required");
186:                Assert.notNull(sid, "Sid required");
187:
188:                AccessControlEntryImpl ace = new AccessControlEntryImpl(null,
189:                        this , sid, permission, granting, false, false);
190:
191:                synchronized (aces) {
192:                    if (afterAceId != null) {
193:                        int offset = findAceOffset(afterAceId);
194:
195:                        if (offset == -1) {
196:                            throw new NotFoundException(
197:                                    "Requested ACE ID not found");
198:                        }
199:
200:                        this .aces.add(offset + 1, ace);
201:                    } else {
202:                        this .aces.add(ace);
203:                    }
204:                }
205:            }
206:
207:            public boolean isEntriesInheriting() {
208:                return entriesInheriting;
209:            }
210:
211:            /**
212:             * Determines authorization.  The order of the <code>permission</code> and <code>sid</code> arguments is
213:             * <em>extremely important</em>! The method will iterate through each of the <code>permission</code>s in the order
214:             * specified. For each iteration, all of the <code>sid</code>s will be considered, again in the order they are
215:             * presented. A search will then be performed for the first {@link AccessControlEntry} object that directly
216:             * matches that <code>permission:sid</code> combination. When the <em>first full match</em> is found (ie an ACE
217:             * that has the SID currently being searched for and the exact permission bit mask being search for), the grant or
218:             * deny flag for that ACE will prevail. If the ACE specifies to grant access, the method will return
219:             * <code>true</code>. If the ACE specifies to deny access, the loop will stop and the next <code>permission</code>
220:             * iteration will be performed. If each permission indicates to deny access, the first deny ACE found will be
221:             * considered the reason for the failure (as it was the first match found, and is therefore the one most logically
222:             * requiring changes - although not always). If absolutely no matching ACE was found at all for any permission,
223:             * the parent ACL will be tried (provided that there is a parent and {@link #isEntriesInheriting()} is
224:             * <code>true</code>. The parent ACL will also scan its parent and so on. If ultimately no matching ACE is found,
225:             * a <code>NotFoundException</code> will be thrown and the caller will need to decide how to handle the permission
226:             * check. Similarly, if any of the SID arguments presented to the method were not loaded by the ACL,
227:             * <code>UnloadedSidException</code> will be thrown.
228:             *
229:             * @param permission the exact permissions to scan for (order is important)
230:             * @param sids the exact SIDs to scan for (order is important)
231:             * @param administrativeMode if <code>true</code> denotes the query is for administrative purposes and no auditing
232:             *        will be undertaken
233:             *
234:             * @return <code>true</code> if one of the permissions has been granted, <code>false</code> if one of the
235:             *         permissions has been specifically revoked
236:             *
237:             * @throws NotFoundException if an exact ACE for one of the permission bit masks and SID combination could not be
238:             *         found
239:             * @throws UnloadedSidException if the passed SIDs are unknown to this ACL because the ACL was only loaded for a
240:             *         subset of SIDs
241:             */
242:            public boolean isGranted(Permission[] permission, Sid[] sids,
243:                    boolean administrativeMode) throws NotFoundException,
244:                    UnloadedSidException {
245:                Assert.notEmpty(permission, "Permissions required");
246:                Assert.notEmpty(sids, "SIDs required");
247:
248:                if (!this .isSidLoaded(sids)) {
249:                    throw new UnloadedSidException(
250:                            "ACL was not loaded for one or more SID");
251:                }
252:
253:                AccessControlEntry firstRejection = null;
254:
255:                for (int i = 0; i < permission.length; i++) {
256:                    for (int x = 0; x < sids.length; x++) {
257:                        // Attempt to find exact match for this permission mask and SID
258:                        Iterator acesIterator = aces.iterator();
259:                        boolean scanNextSid = true;
260:
261:                        while (acesIterator.hasNext()) {
262:                            AccessControlEntry ace = (AccessControlEntry) acesIterator
263:                                    .next();
264:
265:                            if ((ace.getPermission().getMask() == permission[i]
266:                                    .getMask())
267:                                    && ace.getSid().equals(sids[x])) {
268:                                // Found a matching ACE, so its authorization decision will prevail
269:                                if (ace.isGranting()) {
270:                                    // Success
271:                                    if (!administrativeMode) {
272:                                        auditLogger.logIfNeeded(true, ace);
273:                                    }
274:
275:                                    return true;
276:                                } else {
277:                                    // Failure for this permission, so stop search
278:                                    // We will see if they have a different permission
279:                                    // (this permission is 100% rejected for this SID)
280:                                    if (firstRejection == null) {
281:                                        // Store first rejection for auditing reasons
282:                                        firstRejection = ace;
283:                                    }
284:
285:                                    scanNextSid = false; // helps break the loop
286:
287:                                    break; // exit "aceIterator" while loop
288:                                }
289:                            }
290:                        }
291:
292:                        if (!scanNextSid) {
293:                            break; // exit SID for loop (now try next permission)
294:                        }
295:                    }
296:                }
297:
298:                if (firstRejection != null) {
299:                    // We found an ACE to reject the request at this point, as no
300:                    // other ACEs were found that granted a different permission
301:                    if (!administrativeMode) {
302:                        auditLogger.logIfNeeded(false, firstRejection);
303:                    }
304:
305:                    return false;
306:                }
307:
308:                // No matches have been found so far
309:                if (isEntriesInheriting() && (parentAcl != null)) {
310:                    // We have a parent, so let them try to find a matching ACE
311:                    return parentAcl.isGranted(permission, sids, false);
312:                } else {
313:                    // We either have no parent, or we're the uppermost parent
314:                    throw new NotFoundException(
315:                            "Unable to locate a matching ACE for passed permissions and SIDs");
316:                }
317:            }
318:
319:            public boolean isSidLoaded(Sid[] sids) {
320:                // If loadedSides is null, this indicates all SIDs were loaded
321:                // Also return true if the caller didn't specify a SID to find
322:                if ((this .loadedSids == null) || (sids == null)
323:                        || (sids.length == 0)) {
324:                    return true;
325:                }
326:
327:                // This ACL applies to a SID subset only. Iterate to check it applies.
328:                for (int i = 0; i < sids.length; i++) {
329:                    boolean found = false;
330:
331:                    for (int y = 0; y < this .loadedSids.length; y++) {
332:                        if (sids[i].equals(this .loadedSids[y])) {
333:                            // this SID is OK
334:                            found = true;
335:
336:                            break; // out of loadedSids for loop
337:                        }
338:                    }
339:
340:                    if (!found) {
341:                        return false;
342:                    }
343:                }
344:
345:                return true;
346:            }
347:
348:            public void setEntriesInheriting(boolean entriesInheriting) {
349:                aclAuthorizationStrategy.securityCheck(this ,
350:                        AclAuthorizationStrategy.CHANGE_GENERAL);
351:                this .entriesInheriting = entriesInheriting;
352:            }
353:
354:            public void setOwner(Sid newOwner) {
355:                aclAuthorizationStrategy.securityCheck(this ,
356:                        AclAuthorizationStrategy.CHANGE_OWNERSHIP);
357:                Assert.notNull(newOwner, "Owner required");
358:                this .owner = newOwner;
359:            }
360:
361:            public void setParent(Acl newParent) {
362:                aclAuthorizationStrategy.securityCheck(this ,
363:                        AclAuthorizationStrategy.CHANGE_GENERAL);
364:                Assert.notNull(newParent, "New Parent required");
365:                Assert.isTrue(!newParent.equals(this ),
366:                        "Cannot be the parent of yourself");
367:                this .parentAcl = newParent;
368:            }
369:
370:            public String toString() {
371:                StringBuffer sb = new StringBuffer();
372:                sb.append("AclImpl[");
373:                sb.append("id: ").append(this .id).append("; ");
374:                sb.append("objectIdentity: ").append(this .objectIdentity)
375:                        .append("; ");
376:                sb.append("owner: ").append(this .owner).append("; ");
377:
378:                Iterator iterator = this .aces.iterator();
379:                int count = 0;
380:
381:                while (iterator.hasNext()) {
382:                    count++;
383:
384:                    if (count == 1) {
385:                        sb.append("\r\n");
386:                    }
387:
388:                    sb.append(iterator.next().toString()).append("\r\n");
389:                }
390:
391:                if (count == 0) {
392:                    sb.append("no ACEs; ");
393:                }
394:
395:                sb.append("inheriting: ").append(this .entriesInheriting)
396:                        .append("; ");
397:                sb.append("parent: ").append(
398:                        (this .parentAcl == null) ? "Null" : this .parentAcl
399:                                .getObjectIdentity().toString());
400:                sb.append("]");
401:
402:                return sb.toString();
403:            }
404:
405:            public void updateAce(Serializable aceId, Permission permission)
406:                    throws NotFoundException {
407:                aclAuthorizationStrategy.securityCheck(this ,
408:                        AclAuthorizationStrategy.CHANGE_GENERAL);
409:
410:                synchronized (aces) {
411:                    int offset = findAceOffset(aceId);
412:
413:                    if (offset == 1) {
414:                        throw new NotFoundException(
415:                                "Requested ACE ID not found");
416:                    }
417:
418:                    AccessControlEntryImpl ace = (AccessControlEntryImpl) aces
419:                            .get(offset);
420:                    ace.setPermission(permission);
421:                }
422:            }
423:
424:            public void updateAuditing(Serializable aceId,
425:                    boolean auditSuccess, boolean auditFailure) {
426:                aclAuthorizationStrategy.securityCheck(this ,
427:                        AclAuthorizationStrategy.CHANGE_AUDITING);
428:
429:                synchronized (aces) {
430:                    int offset = findAceOffset(aceId);
431:
432:                    if (offset == 1) {
433:                        throw new NotFoundException(
434:                                "Requested ACE ID not found");
435:                    }
436:
437:                    AccessControlEntryImpl ace = (AccessControlEntryImpl) aces
438:                            .get(offset);
439:                    ace.setAuditSuccess(auditSuccess);
440:                    ace.setAuditFailure(auditFailure);
441:                }
442:            }
443:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.