package fr.openwide.core.wicket.more.application; import java.lang.ref.WeakReference; import java.lang.reflect.InvocationTargetException; import org.apache.wicket.Application; import org.apache.wicket.Session; import org.apache.wicket.WicketRuntimeException; import org.apache.wicket.authorization.IUnauthorizedComponentInstantiationListener; import org.apache.wicket.authorization.strategies.CompoundAuthorizationStrategy; import org.apache.wicket.authroles.authentication.AuthenticatedWebSession; import org.apache.wicket.authroles.authorization.strategies.role.IRoleCheckingStrategy; import org.apache.wicket.authroles.authorization.strategies.role.Roles; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.request.IExceptionMapper; import org.apache.wicket.request.Request; import org.apache.wicket.request.Response; import org.apache.wicket.util.IProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.acls.domain.PermissionFactory; import fr.openwide.core.jpa.security.service.IAuthenticationService; import fr.openwide.core.wicket.more.CoreDefaultExceptionMapper; import fr.openwide.core.wicket.more.link.descriptor.IPageLinkDescriptor; import fr.openwide.core.wicket.more.link.descriptor.builder.LinkDescriptorBuilder; import fr.openwide.core.wicket.more.security.authorization.CoreAuthorizationStrategy; import fr.openwide.core.wicket.more.security.authorization.StandardUnauthorizedComponentInstantiationListener; import fr.openwide.core.wicket.more.security.page.AccessDeniedPage; import fr.openwide.core.wicket.more.security.page.LogoutPage; public abstract class CoreWicketAuthenticatedApplication extends CoreWicketApplication implements IRoleCheckingStrategy { private IProvider<IExceptionMapper> coreExceptionMapperProvider; /** * Subclass of authenticated web session to instantiate */ private final WeakReference<Class<? extends AuthenticatedWebSession>> webSessionClassRef; @Autowired private IAuthenticationService authenticationService; @Autowired private PermissionFactory permissionFactory; public static CoreWicketAuthenticatedApplication get() { final Application application = Application.get(); if (application instanceof CoreWicketAuthenticatedApplication) { return (CoreWicketAuthenticatedApplication) application; } throw new WicketRuntimeException("There is no CoreWicketAuthenticatedApplication attached to current thread " + Thread.currentThread().getName()); } public CoreWicketAuthenticatedApplication() { super(); // Get web session class to instantiate webSessionClassRef = new WeakReference<Class<? extends AuthenticatedWebSession>>(getWebSessionClass()); } @Override public void init() { super.init(); getSecuritySettings().setAuthorizationStrategy(newAuthorizationStrategy()); getSecuritySettings().setUnauthorizedComponentInstantiationListener( newUnauthorizedComponentInstantiationListener()); coreExceptionMapperProvider = new CoreDefaultExceptionMapperProvider(); } @Override protected void mountCommonPages() { super.mountCommonPages(); mountPage("/logout/", LogoutPage.class); mountPage("/access-denied/", AccessDeniedPage.class); } @Override public final boolean hasAnyRole(final Roles roles) { final Roles sessionRoles = AuthenticatedWebSession.get().getRoles(); return sessionRoles != null && sessionRoles.hasAnyRole(roles); } @Override public Session newSession(Request request, Response response) { try { return webSessionClassRef.get().getDeclaredConstructor(Request.class).newInstance(request); // NOSONAR } catch (RuntimeException | InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { throw new WicketRuntimeException("Unable to instantiate web session " + webSessionClassRef.get(), e); } } protected CompoundAuthorizationStrategy newAuthorizationStrategy() { return new CoreAuthorizationStrategy(this, authenticationService, permissionFactory); } protected IUnauthorizedComponentInstantiationListener newUnauthorizedComponentInstantiationListener() { return new StandardUnauthorizedComponentInstantiationListener(); } protected abstract Class<? extends AuthenticatedWebSession> getWebSessionClass(); public abstract Class<? extends WebPage> getSignInPageClass(); public final IPageLinkDescriptor getSignInPageLinkDescriptor() { return LinkDescriptorBuilder.start().page(getSignInPageClass()); } @Override public IProvider<IExceptionMapper> getExceptionMapperProvider() { return coreExceptionMapperProvider; } private static class CoreDefaultExceptionMapperProvider implements IProvider<IExceptionMapper> { @Override public IExceptionMapper get() { return new CoreDefaultExceptionMapper(); } } }