001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket.authroles.authorization.strategies.role.annotations; 018 019import org.apache.wicket.Component; 020import org.apache.wicket.authorization.Action; 021import org.apache.wicket.authroles.authorization.strategies.role.AbstractRoleAuthorizationStrategy; 022import org.apache.wicket.authroles.authorization.strategies.role.IRoleCheckingStrategy; 023import org.apache.wicket.authroles.authorization.strategies.role.Roles; 024import org.apache.wicket.request.component.IRequestableComponent; 025import org.apache.wicket.request.mapper.parameter.PageParameters; 026import org.apache.wicket.request.resource.IResource; 027 028 029/** 030 * Strategy that checks the {@link AuthorizeInstantiation} annotation. 031 * 032 * @author Eelco Hillenius 033 */ 034public class AnnotationsRoleAuthorizationStrategy extends AbstractRoleAuthorizationStrategy 035{ 036 /** 037 * Construct. 038 * 039 * @param roleCheckingStrategy 040 * the authorizer delegate 041 */ 042 public AnnotationsRoleAuthorizationStrategy(final IRoleCheckingStrategy roleCheckingStrategy) 043 { 044 super(roleCheckingStrategy); 045 } 046 047 /** 048 * @see org.apache.wicket.authorization.IAuthorizationStrategy#isInstantiationAuthorized(java.lang.Class) 049 */ 050 @Override 051 public <T extends IRequestableComponent> boolean isInstantiationAuthorized( 052 final Class<T> componentClass) 053 { 054 // We are authorized unless we are found not to be 055 boolean authorized = true; 056 057 // Check class annotation first because it is more specific than package annotation 058 final AuthorizeInstantiation classAnnotation = componentClass.getAnnotation(AuthorizeInstantiation.class); 059 if (classAnnotation != null) 060 { 061 authorized = check(classAnnotation); 062 } 063 else 064 { 065 // Check package annotation if there is no one on the the class 066 final Package componentPackage = componentClass.getPackage(); 067 if (componentPackage != null) 068 { 069 final AuthorizeInstantiation packageAnnotation = componentPackage.getAnnotation(AuthorizeInstantiation.class); 070 if (packageAnnotation != null) 071 { 072 authorized = check(packageAnnotation); 073 } 074 } 075 } 076 077 // Check for multiple instantiations 078 final AuthorizeInstantiations authorizeInstantiationsAnnotation = componentClass 079 .getAnnotation(AuthorizeInstantiations.class); 080 if (authorizeInstantiationsAnnotation != null) 081 { 082 for (final AuthorizeInstantiation authorizeInstantiationAnnotation : authorizeInstantiationsAnnotation 083 .ruleset()) 084 { 085 if (!check(authorizeInstantiationAnnotation)) 086 { 087 authorized = false; 088 } 089 } 090 } 091 092 return authorized; 093 } 094 095 /** 096 * Check if annotated instantiation is allowed. 097 * 098 * @param authorizeInstantiationAnnotation 099 * The annotations information 100 * @return False if the instantiation is not authorized 101 */ 102 private <T extends IRequestableComponent> boolean check( 103 final AuthorizeInstantiation authorizeInstantiationAnnotation) 104 { 105 // We are authorized unless we are found not to be 106 boolean authorized = true; 107 108 // Check class annotation first because it is more specific than package annotation 109 if (authorizeInstantiationAnnotation != null) 110 { 111 authorized = hasAny(new Roles(authorizeInstantiationAnnotation.value())); 112 } 113 114 return authorized; 115 } 116 117 /** 118 * @see org.apache.wicket.authorization.IAuthorizationStrategy#isActionAuthorized(org.apache.wicket.Component, 119 * org.apache.wicket.authorization.Action) 120 */ 121 @Override 122 public boolean isActionAuthorized(final Component component, final Action action) 123 { 124 // Get component's class 125 final Class<?> componentClass = component.getClass(); 126 127 return isActionAuthorized(componentClass, action); 128 } 129 130 protected boolean isActionAuthorized(final Class<?> componentClass, final Action action) 131 { 132 // Check for a single action 133 if (!check(action, componentClass.getAnnotation(AuthorizeAction.class))) 134 { 135 return false; 136 } 137 138 // Check for multiple actions 139 final AuthorizeActions authorizeActionsAnnotation = componentClass.getAnnotation(AuthorizeActions.class); 140 if (authorizeActionsAnnotation != null) 141 { 142 for (final AuthorizeAction authorizeActionAnnotation : authorizeActionsAnnotation.actions()) 143 { 144 if (!check(action, authorizeActionAnnotation)) 145 { 146 return false; 147 } 148 } 149 } 150 151 return true; 152 } 153 154 /** 155 * @param action 156 * The action to check 157 * @param authorizeActionAnnotation 158 * The annotations information 159 * @return False if the action is not authorized 160 */ 161 private boolean check(final Action action, final AuthorizeAction authorizeActionAnnotation) 162 { 163 if (authorizeActionAnnotation != null) 164 { 165 if (action.getName().equals(authorizeActionAnnotation.action())) 166 { 167 Roles deniedRoles = new Roles(authorizeActionAnnotation.deny()); 168 if (isEmpty(deniedRoles) == false && hasAny(deniedRoles)) 169 { 170 return false; 171 } 172 173 Roles acceptedRoles = new Roles(authorizeActionAnnotation.roles()); 174 if (!hasAny(acceptedRoles)) 175 { 176 return false; 177 } 178 } 179 } 180 return true; 181 } 182 183 @Override 184 public boolean isResourceAuthorized(IResource resource, PageParameters pageParameters) 185 { 186 Class<? extends IResource> resourceClass = resource.getClass(); 187 boolean allowedByResourceItself = isResourceAnnotationSatisfied( 188 resourceClass.getAnnotation(AuthorizeResource.class)); 189 boolean allowedByPackage = isResourceAnnotationSatisfied( 190 resourceClass.getPackage().getAnnotation(AuthorizeResource.class)); 191 return allowedByResourceItself && allowedByPackage; 192 } 193 194 private boolean isResourceAnnotationSatisfied(AuthorizeResource annotation) 195 { 196 if (annotation != null) 197 { 198 // we have an annotation => we must check for the required roles 199 return hasAny(new Roles(annotation.value())); 200 } 201 else 202 { 203 // no annotation => no required roles => this resource can be accessed 204 return true; 205 } 206 } 207}