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: */
017: package org.apache.wicket.authorization.strategies.role.metadata;
018:
019: import org.apache.wicket.Application;
020: import org.apache.wicket.Component;
021: import org.apache.wicket.MetaDataKey;
022: import org.apache.wicket.authorization.Action;
023: import org.apache.wicket.authorization.strategies.role.AbstractRoleAuthorizationStrategy;
024: import org.apache.wicket.authorization.strategies.role.IRoleCheckingStrategy;
025: import org.apache.wicket.authorization.strategies.role.Roles;
026:
027: /**
028: * Strategy that uses the Wicket metadata facility to check authorization. The
029: * static <code>authorize</code> methods are for authorizing component actions
030: * and component instantiation by role. This class is is the main entry point
031: * for users wanting to use the roles-based authorization of the
032: * wicket-auth-roles package based on wicket metadata.
033: *
034: * For instance, use like:
035: *
036: * <pre>
037: * MetaDataRoleAuthorizationStrategy.authorize(myPanel, RENDER, "ADMIN");
038: * </pre>
039: *
040: * for actions on component instances, or:
041: *
042: * <pre>
043: * MetaDataRoleAuthorizationStrategy.authorize(AdminBookmarkablePage.class, "ADMIN");
044: * </pre>
045: *
046: * for doing role based authorization for component instantation.
047: *
048: * @see org.apache.wicket.MetaDataKey
049: *
050: * @author Eelco Hillenius
051: * @author Jonathan Locke
052: */
053: public class MetaDataRoleAuthorizationStrategy extends
054: AbstractRoleAuthorizationStrategy {
055: /**
056: * Component meta data key for ations/ roles information. Typically, you do
057: * not need to use this meta data key directly, but instead use one of the
058: * bind methods of this class.
059: */
060: public static final MetaDataKey ACTION_PERMISSIONS = new MetaDataKey(
061: ActionPermissions.class) {
062: private static final long serialVersionUID = 1L;
063: };
064:
065: /**
066: * Application meta data key for ations/ roles information. Typically, you
067: * do not need to use this meta data key directly, but instead use one of
068: * the bind methods of this class.
069: */
070: public static final MetaDataKey INSTANTIATION_PERMISSIONS = new MetaDataKey(
071: InstantiationPermissions.class) {
072: private static final long serialVersionUID = 1L;
073: };
074:
075: /** Special role string for denying access to all */
076: public static final String NO_ROLE = "wicket:NO_ROLE";
077:
078: /**
079: * Authorizes the given role to create component instances of type
080: * componentClass. This authorization is added to any previously authorized
081: * roles.
082: *
083: * @param componentClass
084: * The component type that is subject for the authorization
085: * @param roles
086: * The comma separated roles that are authorized to create
087: * component instances of type componentClass
088: */
089: public static final void authorize(
090: final Class<? extends Component> componentClass,
091: final String roles) {
092: final Application application = Application.get();
093: InstantiationPermissions permissions = (InstantiationPermissions) application
094: .getMetaData(INSTANTIATION_PERMISSIONS);
095: if (permissions == null) {
096: permissions = new InstantiationPermissions();
097: application.setMetaData(INSTANTIATION_PERMISSIONS,
098: permissions);
099: }
100: permissions.authorize(componentClass, new Roles(roles));
101: }
102:
103: /**
104: * Authorizes the given role to perform the given action on the given
105: * component.
106: *
107: * @param component
108: * The component that is subject to the authorization
109: * @param action
110: * The action to authorize
111: * @param roles
112: * The comma separated roles to authorize
113: */
114: public static final void authorize(final Component component,
115: final Action action, final String roles) {
116: ActionPermissions permissions = (ActionPermissions) component
117: .getMetaData(ACTION_PERMISSIONS);
118: if (permissions == null) {
119: permissions = new ActionPermissions();
120: component.setMetaData(ACTION_PERMISSIONS, permissions);
121: }
122: permissions.authorize(action, new Roles(roles));
123: }
124:
125: /**
126: * Grants permission to all roles to create instances of the given component
127: * class.
128: *
129: * @param componentClass
130: * The component class
131: */
132: public static final void authorizeAll(
133: final Class<? extends Component> componentClass) {
134: Application application = Application.get();
135: InstantiationPermissions authorizedRoles = (InstantiationPermissions) application
136: .getMetaData(INSTANTIATION_PERMISSIONS);
137: if (authorizedRoles != null) {
138: authorizedRoles.authorizeAll(componentClass);
139: }
140: }
141:
142: /**
143: * Grants permission to all roles to perform the given action on the given
144: * component.
145: *
146: * @param component
147: * The component that is subject to the authorization
148: * @param action
149: * The action to authorize
150: */
151: public static final void authorizeAll(final Component component,
152: final Action action) {
153: ActionPermissions permissions = (ActionPermissions) component
154: .getMetaData(ACTION_PERMISSIONS);
155: if (permissions != null) {
156: permissions.authorizeAll(action);
157: }
158: }
159:
160: /**
161: * Removes permission for the given roles to create instances of the given
162: * component class. There is no danger in removing authorization by calling
163: * this method. If the last authorization grant is removed for a given
164: * componentClass, the internal role NO_ROLE will automatically be added,
165: * effectively denying access to all roles (if this was not done, all roles
166: * would suddenly have access since no authorization is equivalent to full
167: * access).
168: *
169: * @param componentClass
170: * The component type
171: * @param roles
172: * The comma separated list of roles that are no longer to be
173: * authorized to create instances of type componentClass
174: */
175: public static final void unauthorize(
176: final Class<? extends Component> componentClass,
177: final String roles) {
178: final InstantiationPermissions permissions = (InstantiationPermissions) Application
179: .get().getMetaData(INSTANTIATION_PERMISSIONS);
180: if (permissions != null) {
181: permissions.unauthorize(componentClass, new Roles(roles));
182: }
183: }
184:
185: /**
186: * Removes permission for the given role to perform the given action on the
187: * given component. There is no danger in removing authorization by calling
188: * this method. If the last authorization grant is removed for a given
189: * action, the internal role NO_ROLE will automatically be added,
190: * effectively denying access to all roles (if this was not done, all roles
191: * would suddenly have access since no authorization is equivalent to full
192: * access).
193: *
194: * @param component
195: * The component
196: * @param action
197: * The action
198: * @param roles
199: * The comma separated list of roles that are no longer allowed
200: * to perform the given action
201: */
202: public static final void unauthorize(final Component component,
203: final Action action, final String roles) {
204: final ActionPermissions permissions = (ActionPermissions) component
205: .getMetaData(ACTION_PERMISSIONS);
206: if (permissions != null) {
207: permissions.unauthorize(action, new Roles(roles));
208: }
209: }
210:
211: /**
212: * Grants authorization to instantiate the given class to just the role
213: * NO_ROLE, effectively denying all other roles.
214: *
215: * @param componentClass
216: * The component class
217: */
218: public static final void unauthorizeAll(
219: Class<? extends Component> componentClass) {
220: authorizeAll(componentClass);
221: authorize(componentClass, NO_ROLE);
222: }
223:
224: /**
225: * Grants authorization to perform the given action to just the role
226: * NO_ROLE, effectively denying all other roles.
227: *
228: * @param component
229: * the component that is subject to the authorization
230: * @param action
231: * the action to authorize
232: */
233: public static final void unauthorizeAll(final Component component,
234: final Action action) {
235: authorizeAll(component, action);
236: authorize(component, action, NO_ROLE);
237: }
238:
239: /**
240: * Construct.
241: *
242: * @param roleCheckingStrategy
243: * the authorizer object
244: */
245: public MetaDataRoleAuthorizationStrategy(
246: final IRoleCheckingStrategy roleCheckingStrategy) {
247: super (roleCheckingStrategy);
248: }
249:
250: /**
251: * Uses component level meta data to match roles for component action
252: * execution.
253: *
254: * @see org.apache.wicket.authorization.IAuthorizationStrategy#isActionAuthorized(org.apache.wicket.Component,
255: * org.apache.wicket.authorization.Action)
256: */
257: public boolean isActionAuthorized(final Component component,
258: final Action action) {
259: if (component == null) {
260: throw new IllegalArgumentException(
261: "argument component has to be not null");
262: }
263: if (action == null) {
264: throw new IllegalArgumentException(
265: "argument action has to be not null");
266: }
267:
268: final Roles roles = rolesAuthorizedToPerformAction(component,
269: action);
270: if (roles != null) {
271: return hasAny(roles);
272: }
273: return true;
274: }
275:
276: /**
277: * Uses application level meta data to match roles for component
278: * instantiation.
279: *
280: * @see org.apache.wicket.authorization.IAuthorizationStrategy#isInstantiationAuthorized(java.lang.Class)
281: */
282: @SuppressWarnings("unchecked")
283: public boolean isInstantiationAuthorized(final Class componentClass) {
284: if (componentClass == null) {
285: throw new IllegalArgumentException(
286: "argument componentClass cannot be null");
287: }
288:
289: // as long as the interface does not use generics, we should check this
290: if (!Component.class.isAssignableFrom(componentClass)) {
291: throw new IllegalArgumentException(
292: "argument componentClass must be of type "
293: + Component.class.getName());
294: }
295:
296: final Roles roles = rolesAuthorizedToInstantiate(componentClass);
297: if (roles != null) {
298: return hasAny(roles);
299: }
300: return true;
301: }
302:
303: /**
304: * Gets the roles for creation of the given component class, or null if none
305: * were registered.
306: *
307: * @param componentClass
308: * the component class
309: * @return the roles that are authorized for creation of the componentClass,
310: * or null if no specific authorization was configured
311: */
312: private static Roles rolesAuthorizedToInstantiate(
313: final Class<? extends Component> componentClass) {
314: final InstantiationPermissions permissions = (InstantiationPermissions) Application
315: .get().getMetaData(INSTANTIATION_PERMISSIONS);
316: if (permissions != null) {
317: return permissions.authorizedRoles(componentClass);
318: }
319: return null;
320: }
321:
322: /**
323: * Gets the roles for the given action/ component combination.
324: *
325: * @param component
326: * the component
327: * @param action
328: * the action
329: * @return the roles for the action as defined with the given component
330: */
331: private static Roles rolesAuthorizedToPerformAction(
332: final Component component, final Action action) {
333: final ActionPermissions permissions = (ActionPermissions) component
334: .getMetaData(ACTION_PERMISSIONS);
335: if (permissions != null) {
336: return permissions.rolesFor(action);
337: }
338: return null;
339: }
340: }
|