All Downloads are FREE. Search and download functionalities are using the official Maven repository.

utils.AuthN Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2015 Groupon.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package utils;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Lists;
import com.google.inject.Singleton;
import com.typesafe.config.Config;
import models.Authentication;
import models.Owner;
import models.UserMembership;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import play.Application;
import play.mvc.Http;
import play.mvc.Result;
import play.mvc.Security;

import java.util.List;
import javax.inject.Inject;
import javax.persistence.PersistenceException;

/**
 * Authenticates users with session cookie or github enterprise's OAuth2 provider.
 *
 * @author Brandon Arp (barp at groupon dot com)
 */
@Singleton
public class AuthN extends Security.Authenticator {
    /**
     * Public constructor.
     *
     * @param application the running application
     * @param configuration application configuration
     */
    @Inject
    public AuthN(final Application application, final Config configuration) {
        _application = application;
        _configuration = configuration;
    }

    @Override
    public String getUsername(final Http.Context ctx) {
        final boolean useDefaultLogin = _application.isDev() && _configuration.getBoolean("auth.useDefaultLogin");
        if (ctx.session().containsKey("auth-id")) {
            LOGGER.debug("Found auth id in session cookie");
            final String authId = ctx.session().get("auth-id");
            if (TOKEN_CACHE.getIfPresent(authId) != null) {
                return authId;
            } else {
                final Authentication authentication = Authentication.findByUserName(authId);
                if (authentication != null) {
                    TOKEN_CACHE.put(authId, authentication.getToken());
                    return authId;
                } else if (useDefaultLogin) {
                    // Dev mode, we dont need a token for the user
                    // If the user has an existing group, then we can assume the database wasn't just reset
                    if (getOrganizations(authId).size() == 0) {
                        LOGGER.debug(String.format("Did not find orgs for user=%s, storing the defaults", authId));
                        initializeAuthenticatedSession(ctx, authId, _configuration.getStringList("dev.defaultGroups"));
                    }
                    return authId;
                } else {
                    LOGGER.debug("Did not find authentication in database, sending user through auth flow");
                }
            }
        } else if (useDefaultLogin) {
            LOGGER.debug("Did not find auth id in sesion cookie, using defaults");
            final String userName = _configuration.getString("dev.defaultUser");
            initializeAuthenticatedSession(ctx, userName, _configuration.getStringList("dev.defaultGroups"));
            return userName;
        }

        return null;
    }

    @Override
    public Result onUnauthorized(final Http.Context ctx) {
        return redirect(controllers.routes.Authentication.auth(ctx.request().uri()));
    }

    /**
     * Starts a session and sets the session cookies.
     *
     * @param ctx play request context
     * @param userName the user name
     * @param organizations the list of organizations the user is a part of
     */
    public static void initializeAuthenticatedSession(final Http.Context ctx, final String userName, final List organizations) {
        final List orgList = Lists.newArrayList();
        for (final String organization : organizations) {
            Owner org = Owner.getByName(organization);
            try {
                if (org == null) {
                    org = new Owner();
                    org.setOrgName(organization);
                    org.save();
                }
            } catch (final PersistenceException e) {
                LOGGER.warn("Unable to create organization", e);
                org = Owner.getByName(organization);
            }
            orgList.add(org);

            try {
                UserMembership membership = UserMembership.getByUserAndOrg(userName, organization);
                if (membership == null) {
                    membership = new UserMembership();
                    membership.setOrg(org);
                    membership.setUserName(userName);
                    membership.save();
                }
            } catch (final PersistenceException e) {
                LOGGER.warn("Unable to create membership", e);
            }
        }
        USER_ORGS.put(userName, orgList);
        ctx.session().put("auth-id", userName);
        LOGGER.info("added user " + userName + " to session.");
    }

    /**
     * Gets a list of organizations for a user.
     *
     * @param userName the user name
     * @return a list of organizations the user is an owner in
     */
    public static List getOrganizations(final String userName) {
        final List owners = USER_ORGS.getIfPresent(userName);
        if (owners != null) {
            return owners;
        } else {
            final List ownerList = UserMembership.getOrgsForUser(userName);
            USER_ORGS.put(userName, ownerList);
            return ownerList;
        }
    }

    /**
     * Log out the user.
     *
     * @param ctx the play request context
     */
    public static void logout(final Http.Context ctx) {
        ctx.session().clear();
    }

    /**
     * Saves an oAuth token for a user.
     *
     * @param userName the user name
     * @param token the user's token
     */
    public static void storeToken(final String userName, final String token) {
        try {
            Authentication auth = Authentication.findByUserName(userName);
            if (auth == null) {
                auth = new Authentication();
                auth.setUserName(userName);
            }
            auth.setToken(token);
            auth.save();
        } catch (final PersistenceException e) {
            LOGGER.warn("Unable to save token", e);
        }
        TOKEN_CACHE.put(userName, token);
    }

    private final Application _application;
    private final Config _configuration;

    private static final Cache TOKEN_CACHE = CacheBuilder.newBuilder().build();
    private static final Cache> USER_ORGS = CacheBuilder.newBuilder().build();
    private static final Logger LOGGER = LoggerFactory.getLogger(AuthN.class);
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy