package org.sigmah.client.security; /* * #%L * Sigmah * %% * Copyright (C) 2010 - 2016 URD * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import java.util.Date; import org.sigmah.client.ui.presenter.LoginPresenter; import org.sigmah.client.util.ClientUtils; import org.sigmah.shared.Language; import org.sigmah.shared.command.result.Authentication; import com.google.gwt.user.client.Cookies; import com.google.inject.Provider; import com.google.inject.Singleton; /** * Provides the {@link Authentication}. * * @author Denis Colliot (dcolliot@ideia.fr) */ @Singleton public class AuthenticationProvider implements Provider<Authentication> { /** * <p> * The cached authenticated user data. * This data is updated at each page access ; see {@link org.sigmah.client.event.EventBus EventBus}. * </p> * <p> * <em>Should never be {@code null}.</em> * </p> */ private Authentication authentication; /** * Returns the current authentication. * If no user is currently authenticated, the method returns an empty {@link Authentication} instance (with * {@code null} token). * * @return The current authentication or empty authentication (never returns {@code null}). */ @Override public Authentication get() { if (isAnonymous()) { clearAuthentication(); } return authentication; } /** * Returns the authentication token. * <p> * When anonymous, <code>null</code> is returned. * </p> * * @return The authentication token or <code>null</code> if anonymous. */ public String getAuthenticationToken() { return Cookies.getCookie(org.sigmah.shared.Cookies.AUTH_TOKEN_COOKIE); } /** * <p> * Logins the given {@code authentication} by setting cookies and updating cached data. * </p> * <p> * <em>Should be called <b>exclusively</b> by {@link LoginPresenter}.</em> * </p> * * @param authentication * The authentication. Its {@code authenticationToken} <b>must</b> be set. */ public void login(final Authentication authentication) { if (authentication == null) { clearAuthentication(); return; } // Cookies properties. final String path = org.sigmah.shared.Cookies.COOKIE_PATH; final String domain = org.sigmah.shared.Cookies.COOKIE_DOMAIN; final boolean secure = org.sigmah.shared.Cookies.COOKIE_SECURED; // Sets the cookies. Cookies.setCookie(org.sigmah.shared.Cookies.AUTH_TOKEN_COOKIE, authentication.getAuthenticationToken(), oneDayLater(), domain, path, secure); Cookies.setCookie(org.sigmah.shared.Cookies.LANGUAGE_COOKIE, authentication.getLanguage().getLocale(), oneDayLater(), domain, path, secure); // Caches the authentication data. this.authentication = authentication; } /** * <p> * Updates the cached {@link Authentication} instance. * </p> * <p> * <em>Should be called <b>exclusively</b> by {@link org.sigmah.client.event.EventBus}.</em> * </p> * * @param authentication * The authentication. Its {@code authenticationToken} is automatically updated with the one set in cookie. */ public void updateCache(final Authentication authentication) { if (authentication == null) { clearAuthentication(); return; } // Caches the authentication data. authentication.setAuthenticationToken(Cookies.getCookie(org.sigmah.shared.Cookies.AUTH_TOKEN_COOKIE)); this.authentication = authentication; } /** * <p> * Clears the current authentication (cookies + cached authentication data). * </p> * <p> * Maintains the {@link Language} previously set. * </p> * * @return {@code true} if the authentication has been successfully cleared. */ public boolean clearAuthentication() { Cookies.removeCookie(org.sigmah.shared.Cookies.AUTH_TOKEN_COOKIE, org.sigmah.shared.Cookies.COOKIE_PATH); // TODO Also clear GXT theme cookie? authentication = new Authentication(authentication.getLanguage()); return true; } /** * Checks if no user is currently authenticated. * * @return {@code true} if no user is currently authenticated, {@code false} otherwise. */ public boolean isAnonymous() { if (authentication == null) { authentication = new Authentication(); authentication.setAuthenticationToken(getAuthenticationToken()); } final boolean anonymous = ClientUtils.isBlank(authentication.getAuthenticationToken()) && !authentication.isAuthorized(); if (anonymous) { // Just to be sure that all cookies are properly cleared. clearAuthentication(); } return anonymous; } /** * Returns a date corresponding to present time plus a full day (24h). * * @return a date corresponding to present time plus a full day (24h). */ private static Date oneDayLater() { return new Date(new Date().getTime() + 1000 * 60 * 60 * 24); } }