001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019 package org.apache.shiro.authz.aop;
020
021 /**
022 * Checks to see if a @{@link org.apache.shiro.authz.annotation.RequiresPermissions RequiresPermissions} annotation is declared, and if so, performs
023 * a permission check to see if the calling <code>Subject</code> is allowed to call the method.
024 * @author Les Hazlewood
025 * @since 0.9
026 */
027 public class PermissionAnnotationMethodInterceptor extends AuthorizingAnnotationMethodInterceptor {
028
029 /*
030 * The character to look for that closes a permission definition.
031 **/
032 //private static final char ARRAY_CLOSE_CHAR = ']';
033
034 /**
035 * Default no-argument constructor that ensures this interceptor looks for
036 * {@link org.apache.shiro.authz.annotation.RequiresPermissions RequiresPermissions} annotations in a method declaration.
037 */
038 public PermissionAnnotationMethodInterceptor() {
039 super( new PermissionAnnotationHandler() );
040 }
041
042 /*
043 * Infers the permission from the specified name path in the annotation.
044 * @param methodArgs the <code>MethodInvocation</code> method arguments.
045 * @param namePath the Annotation 'name' value, which is a string-based permission definition.
046 * @return the String permission representation.
047 * @throws Exception if there is an error infering the target.
048 *
049 protected String inferTargetFromPath(Object[] methodArgs, String namePath) throws Exception {
050 int propertyStartIndex = -1;
051
052 char[] chars = namePath.toCharArray();
053 StringBuilder buf = new StringBuilder();
054 //init iteration at index 1 (instead of 0). This is because the first
055 //character must be the ARRAY_OPEN_CHAR (eliminates unnecessary iteration)
056 for (int i = 1; i < chars.length; i++) {
057 if (chars[i] == ARRAY_CLOSE_CHAR) {
058 // skip the delimiting period after the ARRAY_CLOSE_CHAR. The resulting
059 // index is the init of the property path that we'll use with
060 // BeanUtils.getProperty:
061 propertyStartIndex = i + 2;
062 break;
063 } else {
064 buf.append(chars[i]);
065 }
066 }
067
068 Integer methodArgIndex = Integer.parseInt(buf.toString());
069 String beanUtilsPath = new String(chars, propertyStartIndex,
070 chars.length - propertyStartIndex);
071 Object targetValue = PropertyUtils.getProperty(methodArgs[methodArgIndex], beanUtilsPath);
072 return targetValue.toString();
073 }
074
075 /*
076 * Returns the <code>MethodInvocation</code>'s arguments, or <code>null</code> if there were none.
077 * @param invocation the methodInvocation to inspect.
078 * @return the method invocation's method arguments, or <code>null</code> if there were none.
079 *
080 protected Object[] getMethodArguments(MethodInvocation invocation) {
081 if (invocation != null) {
082 return invocation.getArguments();
083 } else {
084 return null;
085 }
086 }
087
088 /*
089 * Returns the annotation {@link RequiresPermissions#value value}, from which the Permission will be constructed.
090 *
091 * @param invocation the method being invoked.
092 * @return the method annotation's <code>value</code>, from which the Permission will be constructed.
093 *
094 protected String getAnnotationValue(MethodInvocation invocation) {
095 RequiresPermissions prAnnotation = (RequiresPermissions) getAnnotation(invocation);
096 return prAnnotation.value();
097 } */
098 }