/* * Copyright (c) JForum Team. All rights reserved. * * The software in this package is published under the terms of the LGPL * license a copy of which has been included with this distribution in the * license.txt file. * * The JForum Project * http://www.jforum.net */ package net.jforum.actions.interceptors; import javax.servlet.http.HttpServletRequest; import net.jforum.controllers.MessageController; import net.jforum.controllers.UserController; import net.jforum.core.Role; import net.jforum.core.SecurityConstraint; import net.jforum.entities.UserSession; import net.jforum.security.AccessRule; import net.jforum.security.EmptyRule; import br.com.caelum.vraptor.InterceptionException; import br.com.caelum.vraptor.Result; import br.com.caelum.vraptor.core.InterceptorStack; import br.com.caelum.vraptor.interceptor.Interceptor; import br.com.caelum.vraptor.ioc.Container; import br.com.caelum.vraptor.resource.ResourceMethod; /** * Handles the {@link SecurityConstraint} annotation, looking for AccessRules * @author Rafael Steil */ public abstract class SecurityInterceptor implements Interceptor { private final HttpServletRequest request; private final Result result; private final UserSession userSession; private final Container container; public SecurityInterceptor(HttpServletRequest request, Result result, UserSession userSession, Container container) { this.request = request; this.result = result; this.userSession = userSession; this.container = container; } @Override public void intercept(InterceptorStack stack, ResourceMethod method, Object resourceInstance) throws InterceptionException { SecurityConstraint annotation = this.getAnnotation(method); Class<? extends AccessRule> accessRuleClass = annotation.value(); boolean shouldProceed = true; boolean displayLogin = true; if (!accessRuleClass.equals(EmptyRule.class)) { AccessRule accessRule = this.findAccessRule(annotation.value()); shouldProceed = accessRule.shouldProceed(userSession, request); displayLogin = annotation.displayLogin(); } else { Role[] multiRoles = annotation.multiRoles(); if (multiRoles.length == 0) { throw new IllegalStateException("@SecurityConstraint does not have an access rule nor multi roles. Cannot continue"); } else { for (Role role : multiRoles) { AccessRule accessRule = this.findAccessRule(role.value()); if (!accessRule.shouldProceed(userSession, request)) { shouldProceed = false; displayLogin = role.displayLogin(); break; } } } } if (shouldProceed) { stack.next(method, resourceInstance); } else { if (displayLogin) { this.result.redirectTo(UserController.class).login(null, false); } else { this.result.redirectTo(MessageController.class).accessDenied(); } } } private AccessRule findAccessRule(Class<? extends AccessRule> klass) { AccessRule accessRule = container.instanceFor(klass); if (accessRule == null) { throw new NullPointerException( String.format("Could not find the rule %s. Have you registered it in the configuration file?", klass.getName())); } return accessRule; } protected abstract SecurityConstraint getAnnotation(ResourceMethod method); protected abstract boolean isAnnotationPresent(ResourceMethod method); @Override public boolean accepts(ResourceMethod method) { return this.isAnnotationPresent(method); } }