View Javadoc

1   /**
2    * Copyright 2005-2012 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kim.api.permission;
17  
18  import org.kuali.rice.core.api.criteria.QueryByCriteria;
19  import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
20  import org.kuali.rice.core.api.exception.RiceIllegalStateException;
21  import org.kuali.rice.core.api.util.jaxb.MapStringStringAdapter;
22  import org.kuali.rice.kim.api.KimConstants;
23  import org.kuali.rice.kim.api.common.assignee.Assignee;
24  import org.kuali.rice.kim.api.common.template.Template;
25  import org.kuali.rice.kim.api.common.template.TemplateQueryResults;
26  import org.springframework.cache.annotation.CacheEvict;
27  import org.springframework.cache.annotation.Cacheable;
28  
29  import javax.jws.WebMethod;
30  import javax.jws.WebParam;
31  import javax.jws.WebResult;
32  import javax.jws.WebService;
33  import javax.jws.soap.SOAPBinding;
34  import javax.xml.bind.annotation.XmlElement;
35  import javax.xml.bind.annotation.XmlElementWrapper;
36  import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
37  import java.util.List;
38  import java.util.Map;
39  
40  /**
41   * This service provides operations for evaluating permissions and querying for permission data.
42   * 
43   * <p>A permission is the ability to perform an action.  All permissions have a permission template.
44   * Both permissions and permission templates are uniquely identified by a namespace code plus a name.
45   * The permission template defines the course-grained permission and specifies what additional
46   * permission details need to be collected on permissions that use that template.  For example, a
47   * permission template might have a name of "Initiate Document" which requires a permission detail
48   * specifying the document type that can be initiated.  A permission created from the "Initiate Document"
49   * template would define the name of the specific Document Type that can be initiated as a permission
50   * detail.
51   * 
52   * <p>The isAuthorized and isAuthorizedByTemplateName operations
53   * on this service are used to execute authorization checks for a principal against a
54   * permission.  Permissions are always assigned to roles (never directly to a principal or
55   * group).  A particular principal will be authorized for a given permission if the permission
56   * evaluates to true (according to the permission evaluation logic and based on any supplied
57   * permission details) and that principal is assigned to a role which has been granted the permission.
58   * 
59   * <p>The actual logic for how permission evaluation logic is defined and executed is dependent upon
60   * the permission service implementation.  However, it will typically be associated with the permission
61   * template used on the permission.
62   * 
63   * @author Kuali Rice Team (rice.collab@kuali.org)
64   */
65  @WebService(name = "permissionService", targetNamespace = KimConstants.Namespaces.KIM_NAMESPACE_2_0)
66  @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL, parameterStyle = SOAPBinding.ParameterStyle.WRAPPED)
67  public interface PermissionService {
68  
69      /**
70       * This will create a {@link Permission} exactly like the permission passed in.
71       *
72       * @param permission the permission to create
73       * @return the id of the newly created object.  will never be null.
74       * @throws IllegalArgumentException if the permission is null
75       * @throws IllegalStateException if the permission is already existing in the system
76       */
77      @WebMethod(operationName="createPermission")
78      @WebResult(name = "permission")
79      @CacheEvict(value={Permission.Cache.NAME, Template.Cache.NAME + "{Permission}"}, allEntries = true)
80      Permission createPermission(@WebParam(name = "permission") Permission permission)
81              throws RiceIllegalArgumentException, RiceIllegalStateException;
82  
83      /**
84       * This will update a {@link Permission}.
85       *
86       * @param permission the permission to update
87       * @throws IllegalArgumentException if the permission is null
88       * @throws IllegalStateException if the permission does not exist in the system
89       */
90      @WebMethod(operationName="updatePermission")
91      @WebResult(name = "permission")
92      @CacheEvict(value={Permission.Cache.NAME, Template.Cache.NAME + "{Permission}"}, allEntries = true)
93      Permission updatePermission(@WebParam(name = "permission") Permission permission)
94              throws RiceIllegalArgumentException, RiceIllegalStateException;
95  
96      // --------------------
97      // Authorization Checks
98      // --------------------
99  	
100     /**
101      * Checks whether the principal has been granted a permission matching the given details
102      * without taking role qualifiers into account.
103      * 
104 	 * This method should not be used for true authorization checks since a principal
105 	 * may only have this permission within a given context.  It could be used to
106 	 * identify that the user would have some permissions within a certain area.
107 	 * Later checks would identify exactly what permissions were granted.
108 	 * 
109 	 * It can also be used when the client application KNOWS that this is a role which
110 	 * is never qualified.
111      */
112     @WebMethod(operationName = "hasPermission")
113     @WebResult(name = "hasPermission")
114     boolean hasPermission( @WebParam(name="principalId") String principalId,
115     					   @WebParam(name="namespaceCode") String namespaceCode,
116     					   @WebParam(name="permissionName") String permissionName,
117     					   @XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
118                            @WebParam(name="permissionDetails") Map<String, String> permissionDetails ) throws RiceIllegalArgumentException;
119 
120 
121     /**
122      * Checks whether the given qualified permission is granted to the principal given
123      * the passed roleQualification.  If no roleQualification is passed (null or empty)
124      * then this method behaves the same as {@link #hasPermission(String, String, String, Map<String, String>)}.
125      * 
126      * Each role assigned to the principal is checked for qualifications.  If a qualifier 
127      * exists on the principal's membership in that role, that is checked first through
128      * the role's type service.  Once it is determined that the principal has the role
129      * in the given context (qualification), the permissions are examined.
130      * 
131      * Each permission is checked against the permissionDetails.  The PermissionTypeService
132      * is called for each permission with the given permissionName to see if the 
133      * permissionDetails matches its details.
134      */
135     @WebMethod(operationName = "isAuthorized")
136     @WebResult(name = "isAuthorized")
137     boolean isAuthorized( @WebParam(name="principalId") String principalId,
138     					  @WebParam(name="namespaceCode") String namespaceCode,
139     					  @WebParam(name="permissionName") String permissionName,
140                           @XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
141     					  @WebParam(name="permissionDetails") Map<String, String> permissionDetails,
142                           @XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
143     					  @WebParam(name="qualification") Map<String, String> qualification  ) throws RiceIllegalArgumentException;
144 
145     /**
146      * Checks whether the principal has been granted a permission matching the given details
147      * without taking role qualifiers into account.
148      * 
149 	 * This method should not be used for true authorization checks since a principal
150 	 * may only have this permission within a given context.  It could be used to
151 	 * identify that the user would have some permissions within a certain area.
152 	 * Later checks would identify exactly what permissions were granted.
153 	 * 
154 	 * It can also be used when the client application KNOWS that this is a role which
155 	 * is never qualified.
156      */
157     @WebMethod(operationName = "hasPermissionByTemplateName")
158     @WebResult(name = "hasPermission")
159     boolean hasPermissionByTemplateName( @WebParam(name="principalId") String principalId,
160     									 @WebParam(name="namespaceCode") String namespaceCode,
161     									 @WebParam(name="permissionTemplateName") String permissionTemplateName,
162                                          @XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
163     									 @WebParam(name="permissionDetails") Map<String, String> permissionDetails ) throws RiceIllegalArgumentException;
164     
165     /**
166      * Checks whether the given qualified permission is granted to the principal given
167      * the passed roleQualification.  If no roleQualification is passed (null or empty)
168      * then this method behaves the same as {@link #hasPermission(String, String, String, Map<String, String>)}.
169      * 
170      * Each role assigned to the principal is checked for qualifications.  If a qualifier 
171      * exists on the principal's membership in that role, that is checked first through
172      * the role's type service.  Once it is determined that the principal has the role
173      * in the given context (qualification), the permissions are examined.
174      * 
175      * Each permission is checked against the permissionDetails.  The PermissionTypeService
176      * is called for each permission with the given permissionName to see if the 
177      * permissionDetails matches its details.
178      */
179     @WebMethod(operationName = "isAuthorizedByTemplateName")
180     @WebResult(name = "isAuthorized")
181     boolean isAuthorizedByTemplateName( @WebParam(name="principalId") String principalId,
182     									@WebParam(name="namespaceCode") String namespaceCode,
183     									@WebParam(name="permissionTemplateName") String permissionTemplateName,
184                                         @XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
185     									@WebParam(name="permissionDetails") Map<String, String> permissionDetails,
186                                         @XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
187     									@WebParam(name="qualification") Map<String, String> qualification  ) throws RiceIllegalArgumentException;
188     
189     
190     /**
191      * Get the list of principals/groups who have a given permission.  This also returns delegates
192      * for the given principals/groups who also have this permission given the context in the
193      * qualification parameter.
194      * 
195      * Each role assigned to the principal is checked for qualifications.  If a qualifier 
196      * exists on the principal's membership in that role, that is checked first through
197      * the role's type service.  Once it is determined that the principal has the role
198      * in the given context (qualification), the permissions are examined.
199      * 
200      */
201 	@WebMethod(operationName = "getPermissionAssignees")
202     @XmlElementWrapper(name = "assignees", required = true)
203     @XmlElement(name = "assignee", required = false)
204     @WebResult(name = "assignees")
205     List<Assignee> getPermissionAssignees( @WebParam(name="namespaceCode") String namespaceCode,
206     													 @WebParam(name="permissionName") String permissionName,
207                                                          @XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
208     													 @WebParam(name="permissionDetails") Map<String, String> permissionDetails,
209                                                          @XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
210     													 @WebParam(name="qualification") Map<String, String> qualification ) throws RiceIllegalArgumentException;
211 
212     /**
213      * Get the list of principals/groups who have a given permission that match the given 
214      * permission template and permission details.  This also returns delegates
215      * for the given principals/groups who also have this permission given the context in the
216      * qualification parameter.
217      * 
218      * Each role assigned to the principal is checked for qualifications.  If a qualifier 
219      * exists on the principal's membership in that role, that is checked first through
220      * the role's type service.  Once it is determined that the principal has the role
221      * in the given context (qualification), the permissions are examined.
222      * 
223      */
224 	@WebMethod(operationName = "getPermissionAssigneesByTemplateName")
225     @XmlElementWrapper(name = "assignees", required = true)
226     @XmlElement(name = "assignee", required = false)
227     @WebResult(name = "assignees")
228     List<Assignee> getPermissionAssigneesByTemplateName(@WebParam(name = "namespaceCode") String namespaceCode,
229             @WebParam(name = "permissionTemplateName") String permissionTemplateName,
230             @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) @WebParam(
231                     name = "permissionDetails") Map<String, String> permissionDetails,
232             @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) @WebParam(
233                     name = "qualification") Map<String, String> qualification) throws RiceIllegalArgumentException;
234     
235     /**
236      * Returns true if the given permission is defined on any Roles.
237      */
238     @WebMethod(operationName = "isPermissionDefined")
239     @WebResult(name = "isPermissionDefined")
240     boolean isPermissionDefined( @WebParam(name="namespaceCode") String namespaceCode,
241     							 @WebParam(name="permissionName") String permissionName,
242                                  @XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
243     							 @WebParam(name="permissionDetails") Map<String, String> permissionDetails ) throws RiceIllegalArgumentException;
244     
245     /**
246      * Returns true if the given permission template is defined on any Roles.
247      */
248     @WebMethod(operationName = "isPermissionDefinedByTemplateName")
249     @WebResult(name = "isPermissionDefinedByTemplateName")
250     boolean isPermissionDefinedByTemplateName(@WebParam(name = "namespaceCode") String namespaceCode,
251             @WebParam(name = "permissionTemplateName") String permissionTemplateName,
252             @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) @WebParam(
253                     name = "permissionDetails") Map<String, String> permissionDetails) throws RiceIllegalArgumentException;
254     
255     /**
256      * Returns permissions (with their details) that are granted to the principal given
257      * the passed qualification.  If no qualification is passed (null or empty)
258      * then this method does not check any qualifications on the roles.
259      * 
260      * All permissions with the given name are checked against the permissionDetails.  
261      * The PermissionTypeService is called for each permission to see if the 
262      * permissionDetails matches its details.
263      * 
264      * An asterisk (*) as a value in any permissionDetails key-value pair will match any value.
265      * This forms a way to provide a wildcard to obtain multiple permissions in one call.
266      * 
267      * After the permissions are determined, the roles that hold those permissions are determined.
268      * Each role that matches between the principal and the permission objects is checked for 
269      * qualifications.  If a qualifier 
270      * exists on the principal's membership in that role, that is checked through
271      * the role's type service. 
272      * 
273      */
274 	@WebMethod(operationName = "getAuthorizedPermissions")
275     @XmlElementWrapper(name = "permissions", required = true)
276     @XmlElement(name = "permission", required = false)
277     @WebResult(name = "permissions")
278     List<Permission> getAuthorizedPermissions( @WebParam(name="principalId") String principalId,
279     												  @WebParam(name="namespaceCode") String namespaceCode,
280     												  @WebParam(name="permissionName") String permissionName,
281                                                       @XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
282     												  @WebParam(name="permissionDetails") Map<String, String> permissionDetails,
283                                                       @XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
284     												  @WebParam(name="qualification") Map<String, String> qualification ) throws RiceIllegalArgumentException;
285 
286     /**
287      * Returns permissions (with their details) that are granted to the principal given
288      * the passed qualification.  If no qualification is passed (null or empty)
289      * then this method does not check any qualifications on the roles.
290      * 
291      * All permissions with the given name are checked against the permissionDetails.  
292      * The PermissionTypeService is called for each permission to see if the 
293      * permissionDetails matches its details.
294      * 
295      * An asterisk (*) as a value in any permissionDetails key-value pair will match any value.
296      * This forms a way to provide a wildcard to obtain multiple permissions in one call.
297      * 
298      * After the permissions are determined, the roles that hold those permissions are determined.
299      * Each role that matches between the principal and the permission objects is checked for 
300      * qualifications.  If a qualifier 
301      * exists on the principal's membership in that role, that is checked through
302      * the role's type service. 
303      * 
304      */
305 	@WebMethod(operationName = "getAuthorizedPermissionsByTemplateName")
306     @XmlElementWrapper(name = "permissions", required = true)
307     @XmlElement(name = "permission", required = false)
308     @WebResult(name = "permissions")
309     List<Permission> getAuthorizedPermissionsByTemplateName( @WebParam(name="principalId") String principalId,
310     																@WebParam(name="namespaceCode") String namespaceCode,
311     																@WebParam(name="permissionTemplateName") String permissionTemplateName,
312                                                                     @XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
313     																@WebParam(name="permissionDetails") Map<String, String> permissionDetails,
314                                                                     @XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
315     																@WebParam(name="qualification") Map<String, String> qualification ) throws RiceIllegalArgumentException;
316 
317     // --------------------
318     // Permission Data
319     // --------------------
320 
321     /**
322      * Get the permission object with the given ID.
323      */
324 	@WebMethod(operationName = "getPermission")
325     @WebResult(name = "permission")
326     @Cacheable(value=Permission.Cache.NAME, key="'id=' + #p0")
327     Permission getPermission( @WebParam(name="id") String id );
328 	
329 	/** Get the Permission object with the unique combination of namespace and permission name.
330      *
331      * If any parameter is blank, this method returns <code>null</code>.
332      */
333     @WebMethod(operationName = "findPermByNamespaceCodeAndName")
334     @WebResult(name = "permission")
335     @Cacheable(value=Permission.Cache.NAME, key="'namespaceCode=' + #p0 + '|' + 'name=' + #p1")
336     Permission findPermByNamespaceCodeAndName(@WebParam(name = "namespaceCode") String namespaceCode,
337             @WebParam(name = "name") String name) throws RiceIllegalArgumentException;
338    
339 	/** 
340 	 * Return the permission object for the given unique combination of namespace,
341 	 * component and permission template name.
342 	 */
343 	@WebMethod(operationName = "findPermsByNamespaceCodeTemplateName")
344     @WebResult(name = "permission")
345     @Cacheable(value=Permission.Cache.NAME, key="'namespaceCode=' + #p1 + '|' + 'templateName=' + #p2")
346     List<Permission> findPermsByNamespaceCodeTemplateName(@WebParam(name = "namespaceCode") String namespaceCode,
347             @WebParam(name = "templateName") String templateName) throws RiceIllegalArgumentException;
348 
349 	/**
350 	 * 
351 	 * Return the Permission Template given the Template ID.
352 	 * 
353 	 * @param id
354 	 * @return PermissionTemplate
355 	 */
356 	@WebMethod(operationName = "getPermissionTemplate")
357     @WebResult(name = "id")
358     @Cacheable(value=Template.Cache.NAME + "{Permission}", key="'id=' + #p0")
359     Template getPermissionTemplate( @WebParam(name="id") String id ) throws RiceIllegalArgumentException;
360 
361 	/**
362 	 * 
363 	 * Return the Permission Template given the Template Name and Namespace Code.
364 	 * 
365 	 * @param namespaceCode, permissionTemplateName
366 	 * @return PermissionTemplate
367 	 */
368 	@WebMethod(operationName = "findPermTemplateByNamespaceCodeAndName")
369     @WebResult(name = "permissionTemplate")
370     @Cacheable(value=Template.Cache.NAME + "{Permission}", key="'namespaceCode=' + #p0 + '|' + 'name=' + #p1")
371     Template findPermTemplateByNamespaceCodeAndName(@WebParam(name = "namespaceCode") String namespaceCode,
372             @WebParam(name = "name") String name) throws RiceIllegalArgumentException;
373 
374 	/**
375 	 * 
376 	 * Return all Permission Templates.
377 	 *
378 	 * @return PermissionTemplate
379 	 */
380 	@WebMethod(operationName = "getAllTemplates")
381     @XmlElementWrapper(name = "templates", required = true)
382     @XmlElement(name = "template", required = false)
383     @WebResult(name = "templates")
384     @Cacheable(value=Template.Cache.NAME + "{Permission}", key="'all'")
385     List<Template> getAllTemplates();
386     
387     /**
388      * Get the role IDs for the given permission.
389      */
390 	@WebMethod(operationName = "getRoleIdsForPermission")
391     @XmlElementWrapper(name = "roleIds", required = true)
392     @XmlElement(name = "roleId", required = false)
393     @WebResult(name = "roleIds")
394     List<String> getRoleIdsForPermission( @WebParam(name="namespaceCode") String namespaceCode,
395     									  @WebParam(name="permissionName") String permissionName,
396                                           @XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
397     									  @WebParam(name="permissionDetails") Map<String, String> permissionDetails) throws RiceIllegalArgumentException;
398 
399     /**
400      * This method find Permissions based on a query criteria.  The criteria cannot be null.
401      *
402      * @param queryByCriteria the criteria.  Cannot be null.
403      * @return query results.  will never return null.
404      * @throws IllegalArgumentException if the queryByCriteria is null
405      */
406     @WebMethod(operationName = "findPermissions")
407     @WebResult(name = "results")
408     PermissionQueryResults findPermissions(@WebParam(name = "query") QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException;
409 
410 
411     /**
412      * This method find Permission Templates based on a query criteria.  The criteria cannot be null.
413      *
414      * @param queryByCriteria the criteria.  Cannot be null.
415      * @return query results.  will never return null.
416      * @throws IllegalArgumentException if the queryByCriteria is null
417      */
418     @WebMethod(operationName = "findPermissionTemplates")
419     @WebResult(name = "results")
420     TemplateQueryResults findPermissionTemplates(@WebParam(name = "query") QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException;
421 }