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 isAuthorizedByTemplate 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 org.kuali.rice.kim.api.permission.Permission} exactly like the permission passed in. 71 * 72 * @param permission the permission to create 73 * @return 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 * @return the updated object. will never be null 88 * @throws IllegalArgumentException if the permission is null 89 * @throws IllegalStateException if the permission does not exist in the system 90 */ 91 @WebMethod(operationName="updatePermission") 92 @WebResult(name = "permission") 93 @CacheEvict(value={Permission.Cache.NAME, Template.Cache.NAME + "{Permission}"}, allEntries = true) 94 Permission updatePermission(@WebParam(name = "permission") Permission permission) 95 throws RiceIllegalArgumentException, RiceIllegalStateException; 96 97 // -------------------- 98 // Authorization Checks 99 // -------------------- 100 101 /** 102 * Checks in a given principal id has a permission using the passed in permission information. 103 * This method should not be used for true authorization checks since a principal 104 * may only have this permission within a given context. It could be used to 105 * identify that the user would have some permissions within a certain area. 106 * Later checks would identify exactly what permissions were granted. 107 * 108 * It can also be used when the client application KNOWS that this is a role which 109 * is never qualified. 110 * 111 * @param principalId the principal id to check. cannot be null or blank. 112 * @param namespaceCode the namespace code. cannot be null or blank. 113 * @param permissionName the permission name. cannot be null or blank. 114 * @return true is principal has permission 115 * @throws IllegalArgumentException if the principalId, namespaceCode, permissionName is null or blank 116 */ 117 @WebMethod(operationName = "hasPermission") 118 @WebResult(name = "hasPermission") 119 boolean hasPermission( @WebParam(name="principalId") String principalId, 120 @WebParam(name="namespaceCode") String namespaceCode, 121 @WebParam(name="permissionName") String permissionName) throws RiceIllegalArgumentException; 122 123 124 125 /** 126 * Checks whether the given qualified permission is granted to the principal given 127 * the passed roleQualification. If no roleQualification is passed (null or empty) 128 * then this method behaves the same as {@link #hasPermission(String, String, String)}. 129 * 130 * Each role assigned to the principal is checked for qualifications. If a qualifier 131 * exists on the principal's membership in that role, that is checked first through 132 * the role's type service. Once it is determined that the principal has the role 133 * in the given context (qualification), the permissions are examined. 134 * 135 * 136 * @param principalId the principal id to check. cannot be null or blank. 137 * @param namespaceCode the namespace code. cannot be null or blank. 138 * @param permissionName the permission name. cannot be null or blank. 139 * @param qualification the qualifications to test against. 140 * @return true is principal has permission 141 * @throws IllegalArgumentException if the principalId, namespaceCode, permissionName is null or blank 142 */ 143 @WebMethod(operationName = "isAuthorized") 144 @WebResult(name = "isAuthorized") 145 boolean isAuthorized( @WebParam(name="principalId") String principalId, 146 @WebParam(name="namespaceCode") String namespaceCode, 147 @WebParam(name="permissionName") String permissionName, 148 @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) 149 @WebParam(name="qualification") Map<String, String> qualification ) throws RiceIllegalArgumentException; 150 151 /** 152 * Checks whether the principal has been granted a permission matching the given details 153 * without taking role qualifiers into account. 154 * 155 * This method should not be used for true authorization checks since a principal 156 * may only have this permission within a given context. It could be used to 157 * identify that the user would have some permissions within a certain area. 158 * Later checks would identify exactly what permissions were granted. 159 * 160 * It can also be used when the client application KNOWS that this is a role which 161 * is never qualified. 162 * 163 * @param principalId the principal id to check. cannot be null or blank. 164 * @param namespaceCode the namespace code. cannot be null or blank. 165 * @param permissionTemplateName the permission name. cannot be null or blank. 166 * @param permissionDetails the permission details 167 * @return true is principal has permission 168 * @throws IllegalArgumentException if the principalId, namespaceCode, permissionName is null or blank 169 */ 170 @WebMethod(operationName = "hasPermissionByTemplate") 171 @WebResult(name = "hasPermission") 172 boolean hasPermissionByTemplate(@WebParam(name = "principalId") String principalId, 173 @WebParam(name = "namespaceCode") String namespaceCode, 174 @WebParam(name = "permissionTemplateName") String permissionTemplateName, 175 @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) @WebParam( 176 name = "permissionDetails") Map<String, String> permissionDetails) throws RiceIllegalArgumentException; 177 178 179 /** 180 * Checks whether the given qualified permission is granted to the principal given 181 * the passed roleQualification. If no roleQualification is passed (null or empty) 182 * then this method behaves the same as {@link #hasPermission(String, String, String)}. 183 * 184 * Each role assigned to the principal is checked for qualifications. If a qualifier 185 * exists on the principal's membership in that role, that is checked first through 186 * the role's type service. Once it is determined that the principal has the role 187 * in the given context (qualification), the permissions are examined. 188 * 189 * Each permission is checked against the permissionDetails. The PermissionTypeService 190 * is called for each permission with the given permissionName to see if the 191 * permissionDetails matches its details. 192 * 193 * @param principalId the principal id to check. cannot be null or blank. 194 * @param namespaceCode the namespace code. cannot be null or blank. 195 * @param permissionTemplateName the permission name. cannot be null or blank. 196 * @param permissionDetails the permission details 197 * @param qualification the permission qualifications 198 * @return true is principal has permission 199 * @throws IllegalArgumentException if the principalId, namespaceCode, permissionName is null or blank 200 */ 201 @WebMethod(operationName = "isAuthorizedByTemplate") 202 @WebResult(name = "isAuthorized") 203 boolean isAuthorizedByTemplate(@WebParam(name = "principalId") String principalId, 204 @WebParam(name = "namespaceCode") String namespaceCode, 205 @WebParam(name = "permissionTemplateName") String permissionTemplateName, 206 @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) 207 @WebParam(name = "permissionDetails") Map<String, String> permissionDetails, 208 @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) 209 @WebParam(name = "qualification") Map<String, String> qualification) 210 throws RiceIllegalArgumentException; 211 212 213 /** 214 * Get the list of principals/groups who have a given permission. 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 * @param namespaceCode the namespace code. cannot be null or blank. 224 * @param permissionName the permission name. cannot be null or blank. 225 * @param qualification the permission qualifications 226 * @return list of assignees that have been assigned the permissions 227 * @throws IllegalArgumentException if the principalId, namespaceCode, permissionName is null or blank 228 */ 229 @WebMethod(operationName = "getPermissionAssignees") 230 @XmlElementWrapper(name = "assignees", required = true) 231 @XmlElement(name = "assignee", required = false) 232 @WebResult(name = "assignees") 233 List<Assignee> getPermissionAssignees( @WebParam(name="namespaceCode") String namespaceCode, 234 @WebParam(name="permissionName") String permissionName, 235 @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) 236 @WebParam(name="qualification") Map<String, String> qualification ) 237 throws RiceIllegalArgumentException; 238 239 /** 240 * Get the list of principals/groups who have a given permission that match the given 241 * permission template and permission details. This also returns delegates 242 * for the given principals/groups who also have this permission given the context in the 243 * qualification parameter. 244 * 245 * Each role assigned to the principal is checked for qualifications. If a qualifier 246 * exists on the principal's membership in that role, that is checked first through 247 * the role's type service. Once it is determined that the principal has the role 248 * in the given context (qualification), the permissions are examined. 249 * 250 * @param namespaceCode the namespace code. cannot be null or blank. 251 * @param permissionTemplateName the permission name. cannot be null or blank. 252 * @param permissionDetails the permission details. 253 * @param qualification the permission qualifications 254 * @return list of assignees that have been assigned the permissions by template 255 * @throws IllegalArgumentException if the principalId, namespaceCode, permissionName is null or blank 256 */ 257 @WebMethod(operationName = "getPermissionAssigneesByTemplate") 258 @XmlElementWrapper(name = "assignees", required = true) 259 @XmlElement(name = "assignee", required = false) 260 @WebResult(name = "assignees") 261 List<Assignee> getPermissionAssigneesByTemplate(@WebParam(name = "namespaceCode") String namespaceCode, 262 @WebParam(name = "permissionTemplateName") String permissionTemplateName, 263 @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) @WebParam( 264 name = "permissionDetails") Map<String, String> permissionDetails, 265 @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) @WebParam( 266 name = "qualification") Map<String, String> qualification) throws RiceIllegalArgumentException; 267 268 /** 269 * Returns true if the given permission is defined on any Roles. 270 * 271 * @param namespaceCode the namespace code. cannot be null or blank. 272 * @param permissionName the permission name. cannot be null or blank. 273 * @return true if given permission is defined on any Roles 274 * @throws IllegalArgumentException if the namespaceCode or permissionName is null or blank 275 */ 276 @WebMethod(operationName = "isPermissionDefined") 277 @WebResult(name = "isPermissionDefined") 278 boolean isPermissionDefined( @WebParam(name="namespaceCode") String namespaceCode, 279 @WebParam(name="permissionName") String permissionName) 280 throws RiceIllegalArgumentException; 281 282 /** 283 * Returns true if the given permission template is defined on any Roles. 284 * 285 * @param namespaceCode the namespace code. cannot be null or blank. 286 * @param permissionTemplateName the permission name. cannot be null or blank. 287 * @param permissionDetails the permission template details 288 * @return true if given permission template is defined on any Roles 289 * @throws IllegalArgumentException if the namespaceCode or permissionName is null or blank 290 */ 291 @WebMethod(operationName = "isPermissionDefinedByTemplate") 292 @WebResult(name = "isPermissionDefinedByTemplate") 293 boolean isPermissionDefinedByTemplate(@WebParam(name = "namespaceCode") 294 String namespaceCode, 295 @WebParam(name = "permissionTemplateName") 296 String permissionTemplateName, 297 @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) 298 @WebParam(name = "permissionDetails") 299 Map<String, String> permissionDetails) 300 throws RiceIllegalArgumentException; 301 302 /** 303 * Returns permissions (with their details) that are granted to the principal given 304 * the passed qualification. If no qualification is passed (null or empty) 305 * then this method does not check any qualifications on the roles. 306 * 307 * After the permissions are determined, the roles that hold those permissions are determined. 308 * Each role that matches between the principal and the permission objects is checked for 309 * qualifications. If a qualifier 310 * exists on the principal's membership in that role, that is checked through 311 * the role's type service. 312 * 313 * @param principalId the principal Id. cannot be null or blank. 314 * @param namespaceCode the namespace code. cannot be null or blank. 315 * @param permissionName the permission name. cannot be null or blank. 316 * @param qualification the permission qualifications 317 * @return list of permissions that are authorized with the given parameters 318 * @throws IllegalArgumentException if the principalId, namespaceCode or permissionName is null or blank 319 */ 320 @WebMethod(operationName = "getAuthorizedPermissions") 321 @XmlElementWrapper(name = "permissions", required = true) 322 @XmlElement(name = "permission", required = false) 323 @WebResult(name = "permissions") 324 List<Permission> getAuthorizedPermissions( @WebParam(name="principalId") String principalId, 325 @WebParam(name="namespaceCode") String namespaceCode, 326 @WebParam(name="permissionName") String permissionName, 327 @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) 328 @WebParam(name="qualification") Map<String, String> qualification ) 329 throws RiceIllegalArgumentException; 330 331 /** 332 * Returns permissions (with their details) that are granted to the principal given 333 * the passed qualification. If no qualification is passed (null or empty) 334 * then this method does not check any qualifications on the roles. 335 * 336 * All permissions with the given name are checked against the permissionDetails. 337 * The PermissionTypeService is called for each permission to see if the 338 * permissionDetails matches its details. 339 * 340 * An asterisk (*) as a value in any permissionDetails key-value pair will match any value. 341 * This forms a way to provide a wildcard to obtain multiple permissions in one call. 342 * 343 * After the permissions are determined, the roles that hold those permissions are determined. 344 * Each role that matches between the principal and the permission objects is checked for 345 * qualifications. If a qualifier 346 * exists on the principal's membership in that role, that is checked through 347 * the role's type service. 348 * 349 * @param principalId the principal Id. cannot be null or blank. 350 * @param namespaceCode the namespace code. cannot be null or blank. 351 * @param permissionTemplateName the permission name. cannot be null or blank. 352 * @param permissionDetails the permission template details. 353 * @param qualification the permission qualifications 354 * @return list of permissions that are authorized with the given parameters 355 * @throws IllegalArgumentException if the principalId, namespaceCode or permissionTemplateName is null or blank 356 */ 357 @WebMethod(operationName = "getAuthorizedPermissionsByTemplate") 358 @XmlElementWrapper(name = "permissions", required = true) 359 @XmlElement(name = "permission", required = false) 360 @WebResult(name = "permissions") 361 List<Permission> getAuthorizedPermissionsByTemplate(@WebParam(name = "principalId") String principalId, 362 @WebParam(name = "namespaceCode") String namespaceCode, 363 @WebParam(name = "permissionTemplateName") String permissionTemplateName, 364 @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) @WebParam( 365 name = "permissionDetails") Map<String, String> permissionDetails, 366 @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) @WebParam( 367 name = "qualification") Map<String, String> qualification) throws RiceIllegalArgumentException; 368 369 // -------------------- 370 // Permission Data 371 // -------------------- 372 373 /** 374 * Gets a {@link org.kuali.rice.kim.api.permission.Permission} from an id. 375 * 376 * <p> 377 * This method will return null if the permission does not exist. 378 * </p> 379 * 380 * @param id the unique id to retrieve the permission by. cannot be null or blank. 381 * @return a {@link org.kuali.rice.kim.api.permission.Permission} or null 382 * @throws IllegalArgumentException if the id is null or blank 383 */ 384 @WebMethod(operationName = "getPermission") 385 @WebResult(name = "permission") 386 @Cacheable(value=Permission.Cache.NAME, key="'id=' + #p0") 387 Permission getPermission( @WebParam(name="id") String id ); 388 389 /** 390 * Gets a {@link org.kuali.rice.kim.api.permission.Permission} with the unique combination of namespace and name. 391 * 392 * <p> 393 * This method will return null if the permission does not exist. 394 * </p> 395 * 396 * @param namespaceCode namespace code for permission. cannot be null or blank. 397 * @param name name of permission. cannot be null or blank. 398 * @return a {@link org.kuali.rice.kim.api.permission.Permission} or null 399 * @throws IllegalArgumentException if the namespaceCode or name is null or blank 400 */ 401 @WebMethod(operationName = "findPermByNamespaceCodeAndName") 402 @WebResult(name = "permission") 403 @Cacheable(value=Permission.Cache.NAME, key="'namespaceCode=' + #p0 + '|' + 'name=' + #p1") 404 Permission findPermByNamespaceCodeAndName( 405 @WebParam(name = "namespaceCode") String namespaceCode, 406 @WebParam(name = "name") String name) 407 throws RiceIllegalArgumentException; 408 409 /** 410 * Return the permissions for the given unique combination of namespace, 411 * component and permission template name. 412 * 413 * @param namespaceCode namespace code for permission. cannot be null or blank. 414 * @param templateName name of permission template. cannot be null or blank. 415 * @return a list of {@link org.kuali.rice.kim.api.permission.Permission} or null 416 * @throws IllegalArgumentException if the namespaceCode or name is null or blank 417 */ 418 @WebMethod(operationName = "findPermissionsByTemplate") 419 @XmlElementWrapper(name = "permissions", required = true) 420 @XmlElement(name = "permission", required = false) 421 @WebResult(name = "permissions") 422 @Cacheable(value=Permission.Cache.NAME, key="'namespaceCode=' + #p1 + '|' + 'templateName=' + #p2") 423 List<Permission> findPermissionsByTemplate( 424 @WebParam(name = "namespaceCode") String namespaceCode, 425 @WebParam(name = "templateName") String templateName) 426 throws RiceIllegalArgumentException; 427 428 /** 429 * Gets a {@link Template} from an id. 430 * 431 * <p> 432 * This method will return null if the template does not exist. 433 * </p> 434 * 435 * @param id the unique id to retrieve the template by. cannot be null or blank. 436 * @return a {@link Template} or null 437 * @throws IllegalArgumentException if the id is null or blank 438 */ 439 @WebMethod(operationName = "getPermissionTemplate") 440 @WebResult(name = "id") 441 @Cacheable(value=Template.Cache.NAME + "{Permission}", key="'id=' + #p0") 442 Template getPermissionTemplate( @WebParam(name="id") String id ) throws RiceIllegalArgumentException; 443 444 /** 445 * Finds a {@link Template} for namespaceCode and name. 446 * 447 * @param namespaceCode the namespace code. cannot be null or blank. 448 * @param name the template name. cannot be null or blank. 449 * @return a {@link Template} or null 450 * @throws IllegalArgumentException if the id or namespaceCode is null or blank 451 */ 452 @WebMethod(operationName = "findPermTemplateByNamespaceCodeAndName") 453 @WebResult(name = "permissionTemplate") 454 @Cacheable(value=Template.Cache.NAME + "{Permission}", key="'namespaceCode=' + #p0 + '|' + 'name=' + #p1") 455 Template findPermTemplateByNamespaceCodeAndName( 456 @WebParam(name = "namespaceCode") String namespaceCode, 457 @WebParam(name = "name") String name) throws RiceIllegalArgumentException; 458 459 460 /** 461 * Finds a {@link Template} for namespaceCode and name. 462 * 463 * @return a list of {@link Template} or an empty list if none found 464 */ 465 @WebMethod(operationName = "getAllTemplates") 466 @XmlElementWrapper(name = "templates", required = true) 467 @XmlElement(name = "template", required = false) 468 @WebResult(name = "templates") 469 @Cacheable(value=Template.Cache.NAME + "{Permission}", key="'all'") 470 List<Template> getAllTemplates(); 471 472 /** 473 * Get the role IDs for the given permission. 474 * 475 * @param namespaceCode the permission namespace code. cannot be null or blank. 476 * @param permissionName the permission name. cannot be null or blank. 477 * @return a list of role Ids, or an empty list if none found 478 * @throws IllegalArgumentException if the namespaceCode or permissionName is null or blank 479 */ 480 @WebMethod(operationName = "getRoleIdsForPermission") 481 @XmlElementWrapper(name = "roleIds", required = true) 482 @XmlElement(name = "roleId", required = false) 483 @WebResult(name = "roleIds") 484 List<String> getRoleIdsForPermission( @WebParam(name="namespaceCode") String namespaceCode, 485 @WebParam(name="permissionName") String permissionName) throws RiceIllegalArgumentException; 486 487 /** 488 * This method find Permissions based on a query criteria. The criteria cannot be null. 489 * 490 * @param queryByCriteria the criteria. Cannot be null. 491 * @return query results. will never return null. 492 * @throws IllegalArgumentException if the queryByCriteria is null 493 */ 494 @WebMethod(operationName = "findPermissions") 495 @WebResult(name = "results") 496 PermissionQueryResults findPermissions(@WebParam(name = "query") QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException; 497 498 499 /** 500 * This method find Permission Templates based on a query criteria. The criteria cannot be null. 501 * 502 * @param queryByCriteria the criteria. Cannot be null. 503 * @return query results. will never return null. 504 * @throws IllegalArgumentException if the queryByCriteria is null 505 */ 506 @WebMethod(operationName = "findPermissionTemplates") 507 @WebResult(name = "results") 508 TemplateQueryResults findPermissionTemplates(@WebParam(name = "query") QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException; 509 }