Subversion Repositories SmartDukaan

Rev

Rev 3390 | Rev 7059 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/**
 * 
 */
package in.shop2020.serving.auth;

import in.shop2020.crm.Agent;
import in.shop2020.crm.CRMService.Client;
import in.shop2020.crm.SearchFilter;
import in.shop2020.thrift.clients.CRMClient;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.thrift.TException;

/**
 * @author mandeep
 * 
 *         This class is realm for fetching authentication and authorization
 *         details for an agent.
 */
public class CRMAuthorizingRealm extends AuthorizingRealm {
    private static final Log   log = LogFactory
                                           .getLog(CRMAuthorizingRealm.class);
    private static Map<Long, Agent>   agentsMapById;
    private static Map<String, Agent> agentsMapByEmailId;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals) {
        // null usernames are invalid
        if (principals == null) {
            throw new AuthorizationException(
                    "PrincipalCollection method argument cannot be null.");
        }

        String username = (String) getAvailablePrincipal(principals);
        List<String> roleNames = null;
        Set<String> permissions = new HashSet<String>();

        try {
            Client crmServiceClient = new CRMClient().getClient();

            // Retrieve roles and permissions from database
            roleNames = crmServiceClient.getRoleNamesForAgent(username);

            for (String roleName : roleNames) {
                permissions.addAll(crmServiceClient
                        .getPermissionsForRoleName(roleName));
            }
        } catch (TException e) {
            throw new AuthorizationException(
                    "Error fetching roles' information", e);
        } catch (Exception e) {
            throw new AuthorizationException("Error creating CRM client", e);
        }

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(
                new HashSet<String>(roleNames));
        info.setStringPermissions(permissions);
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken token) throws AuthenticationException {
        SimpleAuthenticationInfo info = null;

        try {
            UsernamePasswordToken upToken = (UsernamePasswordToken) token;
            String username = upToken.getUsername();

            log.info("Trying to fetch password for " + username);
            Agent agent = getAgent(username);
            if (agent != null) {
                info = new SimpleAuthenticationInfo(username, agent.getPassword().toCharArray(), getName());
            } else {
                throw new UnknownAccountException("No account found for user ["
                        + username + "]");
            }
        } catch (TException e) {
            log.info("Could not create CRM client", e);
        }

        return info;
    }

    public static Agent getAgent(String username) throws TException {
        if (agentsMapByEmailId == null || !agentsMapByEmailId.containsKey(username)) {
            loadAgents();
        }

        return agentsMapByEmailId.get(username);
    }

    public static Agent getAgent(long agentId) throws TException {
        if (agentsMapById == null || !agentsMapById.containsKey(agentId)) {
            loadAgents();
        }

        return agentsMapById.get(agentId);
    }

    private static void loadAgents() throws TException {
        Client crmServiceClient = new CRMClient().getClient();
        List<Agent> agents = crmServiceClient.getAgents(new SearchFilter());
        Map<Long, Agent> agentsMapByIdLocal = new HashMap<Long, Agent>();
        Map<String, Agent> agentsMapByEmailIdLocal = new HashMap<String, Agent>();

        for (Agent agent : agents) {
            agentsMapByIdLocal.put(agent.getId(), agent);
            agentsMapByEmailIdLocal.put(agent.getEmailId(), agent);
        }

        synchronized(CRMAuthorizingRealm.class) {
            agentsMapById = agentsMapByIdLocal;
            agentsMapByEmailId = agentsMapByEmailIdLocal;
        }
    }

    public static List<Agent> getAgents() {
        return new ArrayList<Agent>(agentsMapById.values());
    }
    
    public static void removeAgent(Long id, String emailId) {
        agentsMapById.remove(id);
        agentsMapByEmailId.remove(emailId);
    }
    
    public static void addAgent(Agent agent) {
        agentsMapById.put(agent.getId(), agent);
        agentsMapByEmailId.put(agent.getEmailId(), agent);
    }
    
}