org.ednovo.gooru.security.DoAuthorization.java Source code

Java tutorial

Introduction

Here is the source code for org.ednovo.gooru.security.DoAuthorization.java

Source

/////////////////////////////////////////////////////////////
// DoAuthorization.java
// gooru-api
// Created by Gooru on 2014
// Copyright (c) 2014 Gooru. All rights reserved.
// http://www.goorulearning.org/
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/////////////////////////////////////////////////////////////
package org.ednovo.gooru.security;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.httpclient.HttpStatus;
import org.ednovo.gooru.core.api.model.Application;
import org.ednovo.gooru.core.api.model.GooruAuthenticationToken;
import org.ednovo.gooru.core.api.model.Organization;
import org.ednovo.gooru.core.api.model.User;
import org.ednovo.gooru.core.api.model.UserCredential;
import org.ednovo.gooru.core.api.model.UserToken;
import org.ednovo.gooru.core.application.util.BaseUtil;
import org.ednovo.gooru.core.constant.Constants;
import org.ednovo.gooru.core.security.AuthenticationDo;
import org.ednovo.gooru.domain.service.oauth.OAuthService;
import org.ednovo.gooru.domain.service.redis.RedisService;
import org.ednovo.gooru.domain.service.user.UserService;
import org.ednovo.gooru.infrastructure.persistence.hibernate.OrganizationSettingRepository;
import org.ednovo.gooru.infrastructure.persistence.hibernate.UserTokenRepository;
import org.ednovo.gooru.infrastructure.persistence.hibernate.apikey.ApplicationRepository;
import org.ednovo.gooru.infrastructure.persistence.hibernate.customTable.CustomTableRepository;
import org.ednovo.goorucore.application.serializer.ExcludeNullTransformer;
import org.ednovo.goorucore.application.serializer.JsonDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import flexjson.JSONSerializer;

@Component
public class DoAuthorization {

    @Autowired
    private UserService userService;

    @Autowired
    private OrganizationSettingRepository organizationSettingRepository;

    @Autowired
    private UserTokenRepository userTokenRepository;

    @Autowired
    private RedisService redisService;

    @Autowired
    private OAuthService oAuthService;

    @Autowired
    private ApplicationRepository applicationRepository;

    @Autowired
    private CustomTableRepository customTableRepository;

    private static final String SESSION_TOKEN_KEY = "authenticate_";

    private static final Logger LOGGER = LoggerFactory.getLogger(DoAuthorization.class);

    public User doFilter(String sessionToken, String pinToken, final String apiKeyToken,
            final HttpServletRequest request, final HttpServletResponse response, final Authentication auth,
            final String oAuthToken) {
        if (pinToken != null) {
            sessionToken = pinToken;
        }
        User user = null;
        // boolean isSussess = true;
        AuthenticationDo authentication = null;
        UserToken userToken = null;
        String key = null;
        String data = null;
        final String skipCache = request.getParameter("skipCache");

        if (oAuthToken != null) {
            try {
                key = SESSION_TOKEN_KEY + oAuthToken;
                data = getRedisService().getValue(key);
                if (data != null && (skipCache == null || skipCache.equals("0"))) {
                    authentication = JsonDeserializer.deserialize(data, AuthenticationDo.class);
                }
            } catch (Exception e) {
                LOGGER.error("Failed to  get  value from redis server");
            }
            if (authentication == null || authentication.getUserToken() == null) {
                try {
                    user = oAuthService.getUserByOAuthAccessToken(BaseUtil.extractToken(oAuthToken));
                } catch (Exception e) {
                    LOGGER.error("OAuth Authentication failed --- " + e);
                }
                userToken = userToken == null ? new UserToken() : userToken;
                userToken.setUser(user);
            } else {
                userToken = authentication.getUserToken();
            }
            if (userToken == null) {
                throw new AccessDeniedException("Invalid oauth access token : " + oAuthToken);
            } else {
                user = userToken.getUser();
            }
            request.setAttribute(Constants.OAUTH_ACCESS_TOKEN, oAuthToken);
        } else if (sessionToken != null) {
            try {
                key = SESSION_TOKEN_KEY + sessionToken;
                data = getRedisService().get(key);
                if (data != null && (skipCache == null || skipCache.equals("0"))) {
                    authentication = JsonDeserializer.deserialize(data, AuthenticationDo.class);
                }
            } catch (Exception e) {
                LOGGER.error("Failed to  get  value from redis server");
            }
            if (authentication == null || authentication.getUserToken() == null) {
                userToken = userTokenRepository.findByToken(sessionToken);
            } else {
                userToken = authentication.getUserToken();
            }
            if (userToken == null) {
                throw new AccessDeniedException("Invalid session token : " + sessionToken);
            } else {
                user = userToken.getUser();
            }

            String token = redisService.getValue(sessionToken);
            if (token == null && userToken.getScope().equalsIgnoreCase("expired")) {
                response.setStatus(HttpStatus.SC_FORBIDDEN);
                throw new AccessDeniedException("error:Session is Expired.");
            } else if (sessionToken != null) {
                Organization organization = null;
                if (userToken.getApplication() != null) {
                    organization = userToken.getApplication().getOrganization();
                }
                redisService.addSessionEntry(sessionToken, organization);
            }
        } else if (apiKeyToken != null) {
            if (authentication == null) {
                final Application application = this.getApplicationRepository().getApplication(apiKeyToken);
                if (application == null) {
                    throw new AccessDeniedException("Invalid ApiKey : " + apiKeyToken);
                } else {
                    String anonymousUid = organizationSettingRepository.getOrganizationSetting(Constants.ANONYMOUS,
                            application.getOrganization().getPartyUid());
                    user = userService.findByGooruId(anonymousUid);
                    userToken = userToken == null ? new UserToken() : userToken;
                    userToken.setUser(user);
                }
            }
        } else {
            throw new AccessDeniedException("Session token or api key is mandatory.");
        }
        if (authentication == null) {
            authentication = new AuthenticationDo();
            authentication.setUserToken(userToken);
        }
        if (authentication.getUserToken().getUser() == null) {
            throw new AccessDeniedException("Invalid session token : " + sessionToken);
        }
        // check token expires
        if (authentication.getUserToken().getUser() != null
                && (auth == null || hasRoleChanged(auth, authentication.getUserToken().getUser()))) {
            doAuthentication(request, response, authentication.getUserToken().getUser(),
                    authentication.getUserToken().getToken(), skipCache, authentication, key);
        }

        // set to request so that controllers can read it.
        request.setAttribute(Constants.USER, authentication.getUserToken().getUser());
        if (authentication.getUserToken().getApplication() != null) {
            request.getSession().setAttribute(Constants.APPLICATION_KEY,
                    authentication.getUserToken().getApplication().getKey());
        }
        request.getSession().setAttribute(Constants.SESSION_TOKEN, authentication.getUserToken().getToken());
        return authentication.getUserToken().getUser();
    }

    private Authentication doAuthentication(HttpServletRequest request, HttpServletResponse response, User user,
            String sessionToken, String skipCache, AuthenticationDo authentication, String key) {
        Authentication auth = null;
        if (user != null) {
            UserCredential userCredential = null;
            if (authentication.getUserCredential() == null || !(skipCache == null || skipCache.equals("0"))) {
                userCredential = userService.getUserCredential(user, sessionToken, skipCache,
                        request.getParameter("sharedSecretKey"));
                authentication.setUserCredential(userCredential);
            } else {
                userCredential = authentication.getUserCredential();
            }
            try {
                if (key != null) {
                    getRedisService().put(key, new JSONSerializer()
                            .transform(new ExcludeNullTransformer(), void.class)
                            .include(new String[] { "*.operationAuthorities", "*.userRoleSet", "*.partyOperations",
                                    "*.subOrganizationUids", "*.orgPermits", "*.partyPermits", "*.customFields",
                                    "*.identities", "*.partyPermissions.*" })
                            .exclude(new String[] { "*.class", "*.school", "*.schoolDistrict", "*.status",
                                    "*.meta" })
                            .serialize(authentication), Constants.AUTHENTICATION_CACHE_EXPIRY_TIME_IN_SEC);
                }
            } catch (Exception e) {
                if (LOGGER.isErrorEnabled()) {
                    LOGGER.error("Failed to  put  value from redis server {} ", e);
                }
            }
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Authorize User: First Name-" + user.getFirstName() + "; Last Name-"
                        + user.getLastName() + "; Email-" + user.getUserId());
            }
            auth = new GooruAuthenticationToken(user.getPartyUid(), null, userCredential);
            SecurityContextHolder.getContext().setAuthentication(auth);

        }
        return auth;
    }

    private boolean hasRoleChanged(Authentication auth, User user) {
        boolean hasRoleChanged = false;
        if (!user.getPartyUid().equals((String) auth.getPrincipal())) {
            hasRoleChanged = true;
        }
        return hasRoleChanged;
    }

    public RedisService getRedisService() {
        return redisService;
    }

    public ApplicationRepository getApplicationRepository() {
        return applicationRepository;
    }

    public CustomTableRepository getCustomTableRepository() {
        return customTableRepository;
    }
}