package ru.foror.articles.common.tapestry.common; import java.io.IOException; import org.apache.tapestry5.internal.services.LinkFactory; import org.apache.tapestry5.internal.services.RequestPageCache; import org.apache.tapestry5.internal.structure.Page; import org.apache.tapestry5.model.ComponentModel; import org.apache.tapestry5.services.ApplicationStateManager; import org.apache.tapestry5.services.ComponentEventRequestHandler; import org.apache.tapestry5.services.ComponentEventRequestParameters; import org.apache.tapestry5.services.PageRenderRequestHandler; import org.apache.tapestry5.services.PageRenderRequestParameters; import org.apache.tapestry5.services.Response; import ru.foror.articles.common.domain.LoginAccount; /** * Авторизация страниц. * * @author Alexey Pomogaev foror@mail.com */ public class SecurityHandler implements PageRenderRequestHandler, ComponentEventRequestHandler { private RolePermission rolePerm = new RolePermission(); private IAuthHelper authHelper; private ApplicationStateManager appStateManager; private Response response; private LinkFactory linkFactory; private RequestPageCache cache; private PageRenderRequestHandler pageRenderRequestHandler; private ComponentEventRequestHandler componentEventRequestHandler; /** * Конструктор при прямых запросах к страницам. */ public SecurityHandler(PageRenderRequestHandler delegate, IAuthHelper authHelper, ApplicationStateManager appStateManager, Response response, LinkFactory linkFactory, RequestPageCache cache) { this.authHelper = authHelper; this.appStateManager = appStateManager; this.response = response; this.linkFactory = linkFactory; this.cache = cache; this.pageRenderRequestHandler = delegate; } /** * Конструктор для запросов к страницам вызванных через события Tapestry. */ public SecurityHandler(ComponentEventRequestHandler delegate, IAuthHelper authHelper, ApplicationStateManager appStateManager, Response response, LinkFactory linkFactory, RequestPageCache cache) { this.authHelper = authHelper; this.appStateManager = appStateManager; this.response = response; this.linkFactory = linkFactory; this.cache = cache; this.componentEventRequestHandler = delegate; } /** * Перехват прямого запроса к странице. */ public void handle(PageRenderRequestParameters parameters) throws IOException { if (authorization(cache.get(parameters.getLogicalPageName()))) { pageRenderRequestHandler.handle(parameters); } } /** * Перехват события Tapestry. */ public void handle(ComponentEventRequestParameters parameters) throws IOException { if (parameters.getContainingPageName().equals(parameters.getActivePageName())) { if (authorization(cache.get(parameters.getContainingPageName()))) { componentEventRequestHandler.handle(parameters); } } else { if (authorization(cache.get(parameters.getContainingPageName())) && authorization(cache.get(parameters.getActivePageName()))) { componentEventRequestHandler.handle(parameters); } } } /** * Авторизация пользователя. Подробнее ${@link RolePermission}. * * При провале авторизации произойдёт переадресация, стандартными средствами * сервлетов, на {@link SystemPage#PermissionLow} или {@link SystemPage#PermissionFail}. */ public boolean authorization(Page page) throws IOException { if (!authHelper.isLoginAccount()) { authHelper.loginByCookie(); } ComponentModel model = page.getRootComponent() .getComponentResources() .getComponentModel(); if (rolePerm.isAnonym(model)) { return true; } if (authHelper.isLoginAccount()) { if (!rolePerm.isAnonymOnly(model) && rolePerm.isEnableAccess(appStateManager.get(LoginAccount.class).getRole(), model)) { return true; } response.sendRedirect(linkFactory.createPageLink(SystemPage.PermissionLow.name(), false)); return false; } else if (rolePerm.isAnonymOnly(model)) { return true; } response.sendRedirect(linkFactory.createPageLink(SystemPage.PermissionFail.name(), false)); return false; } }