001: package com.technoetic.xplanner.security.auth;
002:
003: import java.util.ArrayList;
004: import java.util.Collection;
005: import java.util.HashMap;
006: import java.util.Iterator;
007: import java.util.List;
008: import java.util.Map;
009:
010: import org.apache.commons.beanutils.PropertyUtils;
011: import org.springframework.dao.DataAccessException;
012:
013: import com.technoetic.xplanner.domain.Feature;
014: import com.technoetic.xplanner.domain.Integration;
015: import com.technoetic.xplanner.domain.Iteration;
016: import com.technoetic.xplanner.domain.Note;
017: import com.technoetic.xplanner.domain.Person;
018: import com.technoetic.xplanner.domain.Project;
019: import com.technoetic.xplanner.domain.Task;
020: import com.technoetic.xplanner.domain.TimeEntry;
021: import com.technoetic.xplanner.domain.UserStory;
022: import com.technoetic.xplanner.forms.FeatureEditorForm;
023: import com.technoetic.xplanner.forms.IterationEditorForm;
024: import com.technoetic.xplanner.forms.PersonEditorForm;
025: import com.technoetic.xplanner.forms.ProjectEditorForm;
026: import com.technoetic.xplanner.forms.TaskEditorForm;
027: import com.technoetic.xplanner.forms.UserStoryEditorForm;
028: import com.technoetic.xplanner.security.AuthenticationException;
029:
030: public class AuthorizerImpl implements Authorizer {
031: private HashMap resourceTypes = new HashMap();
032: public static final Integer ANY_PROJECT = new Integer(0);
033: private AuthorizerQueryHelper authorizerQueryHelper;
034: private PrincipalSpecificPermissionHelper principalSpecificPermissionHelper;
035:
036: public AuthorizerImpl() {
037: //TODO: Extract these constants
038: //DEBT(METADATA) Move these to the DomainMetaDataRepository
039: resourceTypes.put(Project.class, "system.project");
040: resourceTypes.put(Iteration.class, "system.project.iteration");
041: resourceTypes.put(UserStory.class,
042: "system.project.iteration.story");
043: resourceTypes.put(Task.class,
044: "system.project.iteration.story.task");
045: resourceTypes.put(Feature.class,
046: "system.project.iteration.story.feature");
047: resourceTypes.put(TimeEntry.class,
048: "system.project.iteration.story.task.time_entry");
049: resourceTypes.put(Integration.class,
050: "system.project.integration");
051: resourceTypes.put(Person.class, "system.person");
052: resourceTypes.put(Note.class, "system.note");
053: resourceTypes.put(ProjectEditorForm.class, "system.project");
054: resourceTypes.put(IterationEditorForm.class,
055: "system.project.iteration");
056: resourceTypes.put(UserStoryEditorForm.class,
057: "system.project.iteration.story");
058: resourceTypes.put(TaskEditorForm.class,
059: "system.project.iteration.story.task");
060: resourceTypes.put(FeatureEditorForm.class,
061: "system.project.iteration.story.feature");
062: resourceTypes.put(PersonEditorForm.class, "system.person");
063: }
064:
065: //TODO resource should be a DomainObject
066: public boolean hasPermission(int projectId, int personId,
067: Object resource, String permission)
068: throws AuthenticationException {
069: int id;
070: try {
071: id = ((Integer) PropertyUtils.getProperty(resource, "id"))
072: .intValue();
073: } catch (Exception e) {
074: throw new AuthenticationException(e);
075: }
076: return hasPermission(projectId, personId,
077: getTypeOfResource(resource), id, permission);
078: }
079:
080: public boolean hasPermission(int projectId, int personId,
081: String resourceType, int resourceId, String permissionName)
082: throws AuthenticationException {
083: try {
084: Map permissionsByProjectMap = principalSpecificPermissionHelper
085: .getPermissionsForPrincipal(personId);
086: return permissionMatches(permissionName, resourceType,
087: resourceId, (List) permissionsByProjectMap
088: .get(new Integer(projectId)))
089: ||
090: // For 0.7 only sysadmins have any project permissions
091: permissionMatches(permissionName, resourceType,
092: resourceId, (List) permissionsByProjectMap
093: .get(ANY_PROJECT));
094: } catch (Exception e) {
095: throw new AuthenticationException(e);
096: }
097: }
098:
099: public Collection getPeopleWithPermissionOnProject(List allPeople,
100: int projectId) throws AuthenticationException {
101: Collection people = new ArrayList();
102: for (int i = 0; i < allPeople.size(); i++) {
103: Person person = (Person) allPeople.get(i);
104: if (hasPermission(projectId, person.getId(),
105: "system.project", projectId, "edit")) {
106: people.add(person);
107: }
108: }
109: return people;
110: }
111:
112: public Collection getRolesForPrincipalOnProject(int principalId,
113: int projectId, boolean includeWildcardProject)
114: throws AuthenticationException {
115: try {
116: return authorizerQueryHelper.getRolesForPrincipalOnProject(
117: principalId, projectId, includeWildcardProject);
118: } catch (DataAccessException e) {
119: throw new AuthenticationException(e);
120: }
121: }
122:
123: public boolean hasPermissionForSomeProject(int personId,
124: String resourceType, int resourceId, String permission)
125: throws AuthenticationException {
126: try {
127: List projects = authorizerQueryHelper
128: .getAllUnhidenProjects();
129: return hasPermissionForSomeProject(projects, personId,
130: resourceType, resourceId, permission);
131: } catch (AuthenticationException e) {
132: throw e;
133: } catch (Exception e) {
134: throw new AuthenticationException(e);
135: }
136: }
137:
138: public boolean hasPermissionForSomeProject(Collection projects,
139: int personId, String resourceType, int resourceId,
140: String permission) throws AuthenticationException {
141: for (Iterator iterator = projects.iterator(); iterator
142: .hasNext();) {
143: Project project = (Project) iterator.next();
144: if (hasPermission(project.getId(), personId, resourceType,
145: resourceId, permission)) {
146: return true;
147: }
148: }
149: return false;
150: }
151:
152: public String getTypeOfResource(Object resource) {
153: return (String) resourceTypes.get(resource.getClass());
154: }
155:
156: public void setPrincipalSpecificPermissionHelper(
157: PrincipalSpecificPermissionHelper principalSpecificPermissionHelper) {
158: this .principalSpecificPermissionHelper = principalSpecificPermissionHelper;
159: }
160:
161: public void setAuthorizerQueryHelper(
162: AuthorizerQueryHelper authorizerQueryHelper) {
163: this .authorizerQueryHelper = authorizerQueryHelper;
164: }
165:
166: private boolean isMatching(String pattern, String string) {
167: return pattern.endsWith("%") ? string.startsWith(pattern
168: .substring(0, pattern.length() - 1)) : string
169: .equals(pattern);
170: }
171:
172: private boolean permissionMatches(String permissionName,
173: String resourceType, int resourceId,
174: List permissionsForProject) {
175: boolean hasNegativePermission = false;
176: boolean hasPositivePermission = false;
177: if (permissionsForProject != null) {
178: for (int i = 0; i < permissionsForProject.size(); i++) {
179: Permission permission = (Permission) permissionsForProject
180: .get(i);
181: if (isMatching(permission.getResourceType(),
182: resourceType)
183: && (permission.getResourceId() == 0 || permission
184: .getResourceId() == resourceId)) {
185: if (isMatching(permission.getName(), permissionName)) {
186: if (permission.isPositive()) {
187: hasPositivePermission = true;
188: } else {
189: hasNegativePermission = true;
190: }
191: }
192: }
193: }
194: }
195: return hasPositivePermission && !hasNegativePermission;
196: }
197: }
|