Subversion Repositories general

Rev

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

package ak.hostadmiral.core.model;

import java.util.*;
import net.sf.hibernate.*;
import net.sf.hibernate.type.Type;
import ak.hostadmiral.util.HibernateUtil;
import ak.hostadmiral.util.ModelException;
import ak.hostadmiral.util.ModelSecurityException;

public class UserManager
        implements UserBeforeDeleteListener
{
        private static UserManager userManager = null;
        private static boolean registered = false;

        public static UserManager getInstance()
        {
                return userManager;
        }

        protected static void register()
        {
                synchronized(MailboxManager.class) {
                        if(registered) return;

                        registered = true;
                        try {
                                HibernateUtil.getConfiguration().addResource(
                                        "ak/hostadmiral/core/model/User.hbm.xml");
                                HibernateUtil.getConfiguration().addResource(
                                        "ak/hostadmiral/core/model/UserLogin.hbm.xml");

                                userManager = new UserManager();
                        }
                        catch(Exception ex) {
                                ex.printStackTrace();
                                throw new RuntimeException(ex.getMessage());
                        }
                }
        }

        static {
                register();
        }

        private Collection beforeDeleteListeners = new ArrayList();
        private Map loggedinUsers = new WeakHashMap();

        private UserManager()
        {
                addBeforeDeleteListener(this);
        }

        public User create(User editor)
                throws ModelException
        {
                if(!allowedToCreate(editor)) throw new ModelSecurityException();

                return new User();
        }

        public boolean allowedToCreate(User editor)
                throws ModelException
        {
                return User.allowedToCreate(this, editor);
        }

        public User get(User editor, Long id)
                throws ModelException
        {
                User user;

                try {
                        user = (User)HibernateUtil.currentSession().load(User.class, id);
                }
                catch(HibernateException ex)
                {
                        throw new ModelException(ex);
                }

                if(!user.viewableBy(editor))
                        throw new ModelSecurityException();

                return user;
        }

        public boolean loginExists(User editor, User user, String login)
                throws ModelException
        {
                try {
                        if(user.getId() == null)
                                return ((Integer)HibernateUtil.currentSession().iterate(
                                        "select count(*) from User u where login = ?",
                                        login, Hibernate.STRING)
                                        .next()).intValue() > 0;
                        else
                                return ((Integer)HibernateUtil.currentSession().iterate(
                                        "select count(*) from User u where login = ? and u != ?",
                                        new Object[] { login, user },
                                        new Type[] { Hibernate.STRING, Hibernate.entity(User.class) } )
                                        .next()).intValue() > 0;
                }
                catch(HibernateException ex)
                {
                        throw new ModelException(ex);
                }
        }

        public User findForLogin(String login)
                throws ModelException
        {
                try {
                        List list = HibernateUtil.currentSession().find(
                                "from User where login = ? and enabled = ?",
                                new Object[] { login, Boolean.TRUE },
                                new Type[] { Hibernate.STRING, Hibernate.BOOLEAN } );

                        if(list.size() == 0)
                                return null;
                        else
                                return (User)list.get(0);
                }
                catch(HibernateException ex)
                {
                        throw new ModelException(ex);
                }
        }

        public void save(User editor, User user)
                throws ModelException
        {
                if(!user.editableBy(editor) && !user.partEditableBy(editor)
                        && !user.mayChangeSuperuser(editor))
                {
                        throw new ModelSecurityException();
        }

                user.setModUser(editor);

                try {
                        HibernateUtil.currentSession().saveOrUpdate(user);
                }
                catch(HibernateException ex)
                {
                        throw new ModelException(ex);
                }

                // update user if he is logged in
                for(Iterator i = loggedinUsers.keySet().iterator(); i.hasNext(); ) {
                        User u = (User)i.next();
                        if(u.equals(user))
                                u.update(user);
                }
        }

    public void addBeforeDeleteListener(UserBeforeDeleteListener listener)
    {
        beforeDeleteListeners.add(listener);
    }

    public void removeBeforeDeleteListener(UserBeforeDeleteListener listener)
    {
        beforeDeleteListeners.remove(listener);
    }

    public Collection beforeDelete(User editor, User user, Collection known)
                throws ModelException
    {
        Collection cascade = new ArrayList();

        for(Iterator i = beforeDeleteListeners.iterator(); i.hasNext(); ) {
                UserBeforeDeleteListener listener = (UserBeforeDeleteListener)i.next();
                        Collection subcascade = listener.userBeforeDelete(editor, user, known);
                if(subcascade != null)
                        cascade.addAll(subcascade);
        }

        return cascade;
    }

        public void delete(User editor, User user)
                throws ModelException
        {
                if(!user.deleteableBy(editor))
                        throw new ModelSecurityException();

                try {
                        HibernateUtil.currentSession().delete(user);
                }
                catch(HibernateException ex)
                {
                        throw new ModelException(ex);
                }
        }

        public Collection listUsers(User editor)
                throws ModelException
        {
                try {
                        if(editor.isSuperuser()) {
                                return HibernateUtil.currentSession().find("from User");
                        }
                        else {
                                return HibernateUtil.currentSession().find(
                                        "from User u where u = ? or u.boss = ?",
                                        new Object[] { editor, editor},
                                        new Type[] { Hibernate.entity(User.class), Hibernate.entity(User.class) } );
                        }
                }
                catch(HibernateException ex)
                {
                        throw new ModelException(ex);
                }
        }

        public boolean areUsersAvailable(User editor)
                throws ModelException
        {
                try {
                        if(editor.isSuperuser()) {
                                return true;
                        }
                        else {
                                return ((Integer)HibernateUtil.currentSession().iterate(
                                        "select count(*) from User u where u = ? or u.boss = ?",
                                        new Object[] { editor, editor},
                                        new Type[] { Hibernate.entity(User.class), Hibernate.entity(User.class) } )
                                        .next()).intValue() > 0;
                        }
                }
                catch(HibernateException ex)
                {
                        throw new ModelException(ex);
                }
        }

        public User loginUser(String login, String password, String ip)
                throws ModelException
        {
                User      user      = (login == null || password == null) ? null : findForLogin(login);
                boolean   success   = (user == null) ? false : user.checkPassword(password);
                UserLogin userLogin = new UserLogin(user, login, new Date(), Boolean.valueOf(success), ip);

                // save login information
                try {
                        HibernateUtil.currentSession().saveOrUpdate(userLogin);
                }
                catch(HibernateException ex)
                {
                        throw new ModelException(ex);
                }

                if(success) {
                        loggedinUsers.put(user, Boolean.TRUE);
                        return user;
                }
                else {
                        return null; // wrong login or password
                }
        }

        public Collection listFailedLogins(User editor)
                throws ModelException
        {
                if(!editor.mayViewAllLogins())
                {
                        throw new ModelSecurityException();
        }

                try {
                        return HibernateUtil.currentSession().find(
                                "from UserLogin where success = ?",
                                Boolean.FALSE, Hibernate.BOOLEAN);
                }
                catch(HibernateException ex)
                {
                        throw new ModelException(ex);
                }
        }

        public Collection userBeforeDelete(User editor, User user, Collection known)
                throws ModelException
        {
        Collection subusers;

                try {
                        subusers = HibernateUtil.currentSession().find(
                                "from User where boss = ?",
                                user, Hibernate.entity(User.class) );
                }
                catch(HibernateException ex)
                {
                        throw new ModelException(ex);
                }

        Collection cascade = new ArrayList();
                for(Iterator i = subusers.iterator(); i.hasNext(); ) {
                        User u = (User)i.next();
            if(u.viewableBy(editor)) {
                                if(u.deleteableBy(editor))
                                        cascade.add(new CascadeDeleteElement(u, CascadeDeleteElement.DELETE,
                                                this.beforeDelete(editor, u, known)));
                                else
                                        cascade.add(new CascadeDeleteElement(u, CascadeDeleteElement.FORBIDDEN, null));
                        }
                        else {
                                cascade.add(new CascadeDeleteElement(User.createLimitedCopy(u),
                                        CascadeDeleteElement.FORBIDDEN, null));
                        }
                }

        return cascade;
        }

        public static final Comparator LOGIN_COMPARATOR = new LoginComparator();
        public static final Comparator LOGINS_TIME_COMPARATOR = new LoginsTimeComparator();

        private static class LoginComparator
                implements Comparator
        {
                public int compare(Object o1, Object o2)
                {
                        if(!(o1 instanceof User) || !(o2 instanceof User))
                                throw new ClassCastException("not a User");

                    User a1 = (User)o1;
                    User a2 = (User)o2;

                    if(a1 == null && a2 == null)
                        return 0;
                    else if(a1 == null && a2 != null)
                        return -1;
                    else if(a1 != null && a2 == null)
                        return 1;
                    else
                        return a1.getLogin().compareToIgnoreCase(a2.getLogin());
                }

                public boolean equals(Object obj)
                {
                        return (obj instanceof LoginComparator);
                }
        }

        private static class LoginsTimeComparator
                implements Comparator
        {
                public int compare(Object o1, Object o2)
                {
                        if(!(o1 instanceof UserLogin) || !(o2 instanceof UserLogin))
                                throw new ClassCastException("not a UserLogin");

                    UserLogin a1 = (UserLogin)o1;
                    UserLogin a2 = (UserLogin)o2;

                    if(a1 == null && a2 == null)
                        return 0;
                    else if(a1 == null && a2 != null)
                        return -1;
                    else if(a1 != null && a2 == null)
                        return 1;
                    else
                        return a1.getLoginTime().compareTo(a2.getLoginTime());
                }

                public boolean equals(Object obj)
                {
                        return (obj instanceof LoginComparator);
                }
        }
}