com.cyclopsgroup.tornado.security.impl.DefaultSecurityService.java Source code

Java tutorial

Introduction

Here is the source code for com.cyclopsgroup.tornado.security.impl.DefaultSecurityService.java

Source

/* ==========================================================================
 * Copyright 2002-2005 Cyclops Group Community
 *
 * Licensed under the COMMON DEVELOPMENT AND DISTRIBUTION LICENSE
 * (CDDL) Version 1.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.opensource.org/licenses/cddl1.txt
 *
 *  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 com.cyclopsgroup.tornado.security.impl;

import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.apache.avalon.framework.activity.Startable;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.commons.lang.ArrayUtils;

import com.cyclopsgroup.tornado.security.CreateUserEvent;
import com.cyclopsgroup.tornado.security.NoSuchUserException;
import com.cyclopsgroup.tornado.security.Permission;
import com.cyclopsgroup.tornado.security.PermissionType;
import com.cyclopsgroup.tornado.security.RuntimeUserAPI;
import com.cyclopsgroup.tornado.security.SecurityListener;
import com.cyclopsgroup.tornado.security.SecurityService;
import com.cyclopsgroup.tornado.security.entity.Group;
import com.cyclopsgroup.tornado.security.entity.Role;
import com.cyclopsgroup.tornado.security.entity.RolePermission;
import com.cyclopsgroup.tornado.security.entity.SecurityEntityManager;
import com.cyclopsgroup.tornado.security.entity.User;

/**
 * @author <a href="mailto:jiaqi.guo@gmail.com">Jiaqi Guo</a>
 *
 */
public class DefaultSecurityService extends AbstractLogEnabled implements SecurityService, Serviceable, Startable {
    private Thread checkTimeoutThread;

    private SecurityEntityManager sem;

    private Vector listeners = new Vector();

    private Hashtable runtimeUsers = new Hashtable();

    private Hashtable userEntries = new Hashtable();

    /**
     * Override method addListener in class DefaultSecurityService
     *
     * @see com.cyclopsgroup.tornado.security.SecurityService#addListener(com.cyclopsgroup.tornado.security.SecurityListener)
     */
    public void addListener(SecurityListener listener) {
        listeners.add(listener);
    }

    private void checkTimeout() {
        for (Iterator i = userEntries.keySet().iterator(); i.hasNext();) {
            String sessionId = (String) i.next();
            UserEntry ue = (UserEntry) userEntries.get(sessionId);
            if (ue.isExpired()) {
                userEntries.remove(sessionId);
            }
        }
    }

    /**
     * @param userName Name of user
     * @return Runtime user instance
     * @throws Exception Throw it out
     */
    protected RuntimeUserAPI doLoadUser(String userName) throws Exception {
        User userModel = sem.findUserByName(userName);
        if (userModel == null) {
            throw new NoSuchUserException(userName);
        }
        DefaultRuntimeUser user = new DefaultRuntimeUser(userModel);

        List userRoles = sem.findRolesByUser(userModel.getId());
        for (Iterator i = userRoles.iterator(); i.hasNext();) {
            user.addRole((Role) i.next());
        }
        user.addRole(sem.findRoleByName(ROLE_GUEST));
        if (!userName.equals(USER_GUEST)) {
            user.addRole(sem.findRoleByName(ROLE_USER));
        }

        for (Iterator i = userModel.getGroups().iterator(); i.hasNext();) {
            Group group = (Group) i.next();
            List groupRoles = sem.findRolesByGroup(group.getId());
            for (Iterator j = groupRoles.iterator(); j.hasNext();) {
                user.addRole((Role) j.next());
            }
            if (group.getName().equals(GROUP_ADMINS)) {
                user.addRole(sem.findRoleByName(ROLE_ADMIN));
            }
        }
        String[] roleIdArray = (String[]) user.getRoleIds().toArray(ArrayUtils.EMPTY_STRING_ARRAY);
        List rps = sem.findRolePermissionsByRoles(roleIdArray);
        for (Iterator i = rps.iterator(); i.hasNext();) {
            RolePermission rp = (RolePermission) i.next();
            try {
                PermissionType pt = (PermissionType) Class.forName(rp.getPermissionType()).newInstance();
                Permission p = pt.createPermission(rp.getPermission());
                user.addPermission(pt, p);
            } catch (Exception e) {
                getLogger().warn("Permission is not valid " + rp.getPermissionType() + "|" + rp.getPermission());
            }
        }

        return user;
    }

    /**
     * Override method getGuest in class DefaultSecurityService
     *
     * @see com.cyclopsgroup.tornado.security.SecurityService#getGuestUser()
     */
    public RuntimeUserAPI getGuestUser() throws Exception {
        return getUser(USER_GUEST);
    }

    /**
     * Override method getUser in class DefaultSecurityService
     *
     * @see com.cyclopsgroup.tornado.security.SecurityService#getUser(java.lang.String)
     */
    public synchronized RuntimeUserAPI getUser(String userName) throws Exception {
        RuntimeUserAPI user = (RuntimeUserAPI) runtimeUsers.get(userName);
        if (user == null) {
            user = doLoadUser(userName);
            handleEvent(new CreateUserEvent(user));
            runtimeUsers.put(userName, user);
        }
        return user;
    }

    /**
     * Override method getUserBySessionId in class DefaultSecurityService
     *
     * @see com.cyclopsgroup.tornado.security.SecurityService#getUserBySessionId(java.lang.String)
     */
    public RuntimeUserAPI getUserBySessionId(String sessionId) throws Exception {
        UserEntry ue = (UserEntry) userEntries.get(sessionId);
        if (ue == null) {
            return getGuestUser();
        }
        ue.update();
        return getUser(ue.getUserName());
    }

    /**
     * Override method handleEvent in class DefaultSecurityService
     *
     * @see com.cyclopsgroup.tornado.security.SecurityService#handleEvent(java.lang.Object)
     */
    public void handleEvent(Object event) {
        if (event == null) {
            return;
        }
        for (Iterator i = listeners.iterator(); i.hasNext();) {
            SecurityListener listener = (SecurityListener) i.next();
            try {
                listener.performAction(event);
            } catch (Exception e) {
                getLogger().warn("Event handling error", e);
            }
        }
    }

    /**
     * Override method login in class DefaultSecurityService
     *
     * @see com.cyclopsgroup.tornado.security.SecurityService#login(java.lang.String, java.lang.String, long)
     */
    public RuntimeUserAPI login(String userName, String sessionId, long timeout) throws Exception {
        UserEntry ue = new UserEntry(userName, timeout);
        userEntries.put(sessionId, ue);
        return getUser(userName);
    }

    /**
     * Override method logout in class DefaultSecurityService
     *
     * @see com.cyclopsgroup.tornado.security.SecurityService#logout(java.lang.String)
     */
    public void logout(String sessionId) {
        UserEntry ue = (UserEntry) userEntries.remove(sessionId);
        if (ue.getUserName().equals(USER_GUEST)) {
            return;
        }
        boolean hasUser = false;
        for (Iterator i = userEntries.values().iterator(); i.hasNext();) {
            UserEntry u = (UserEntry) i.next();
            if (u.getUserName().equals(ue.getUserName())) {
                hasUser = true;
                break;
            }
        }
        if (!hasUser) {
            runtimeUsers.remove(ue.getUserName());
        }
    }

    /**
     * Override method refreshUser in class DefaultSecurityService
     *
     * @see com.cyclopsgroup.tornado.security.SecurityService#refreshUser(java.lang.String)
     */
    public void refreshUser(String userName) {
        runtimeUsers.remove(userName);
    }

    /**
     * Override method service in class DefaultSecurityService
     *
     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
     */
    public void service(ServiceManager serviceManager) throws ServiceException {
        sem = (SecurityEntityManager) serviceManager.lookup(SecurityEntityManager.ROLE);
    }

    /**
     * Override method start in class DefaultSecurityService
     *
     * @see org.apache.avalon.framework.activity.Startable#start()
     */
    public void start() throws Exception {
        checkTimeoutThread = new Thread() {
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(10000);
                        checkTimeout();
                    } catch (InterruptedException e) {
                        break;
                    }
                }
            }
        };
        checkTimeoutThread.setDaemon(true);
        checkTimeoutThread.setPriority(Thread.MIN_PRIORITY);
        checkTimeoutThread.start();
    }

    /**
     * Override method stop in class DefaultSecurityService
     *
     * @see org.apache.avalon.framework.activity.Startable#stop()
     */
    public void stop() throws Exception {
        checkTimeoutThread.interrupt();
        checkTimeoutThread = null;
    }
}