Subversion Repositories general

Rev

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

package ak.hostadmiral.core.model;

import java.util.Iterator;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Locale;
import java.util.StringTokenizer;

import ak.hostadmiral.util.ModelException;
import ak.hostadmiral.util.ModelSecurityException;

/**
 *
 * @hibernate.class table="users"
 */
public class User
        extends GeneralModelObject
{
        public static final String DEFAULT_PASSWORD_STORE = "MD5";

        private String     login;
        private Collection passwords; // Collection(PasswordStore)
        private User       boss;
        private Boolean    superuser;
        private Locale     locale = Locale.getDefault();
        private Collection loginHistory;
        private User       origin;  // save original object state before any changes

        protected User()
        {
        }

        protected User(User origin)
        {
                super(origin);
                this.login     = origin.login;

                if(origin.passwords == null)
                this.passwords = null;
                else
                this.passwords = new HashSet(origin.passwords);

                this.boss      = origin.boss;
                this.superuser = origin.superuser;
                this.locale    = origin.locale;

                if(origin.loginHistory == null)
                this.loginHistory = null;
                else
                this.loginHistory = new HashSet(origin.loginHistory);
        }

    protected User getOrigin()
    {
        return origin;
    }

    protected void backupMe()
    {
        if(origin == null)
            origin = new User(this);
    }

        /**
         *
         * @hibernate.property
         */
        public String getLogin()
        {
                return login;
        }

        protected void setLogin(String login)
        {
                this.login = login;
        }

        public void setLogin(User editor, String login)
                throws ModelException
        {
                if(!editableBy(editor))
                        throw new ModelSecurityException();

                // FIXME: domain owner is allowed to change user login
                //        with some patern only, e.g. user@domain.com

        backupMe();
                this.login = login;
        }

        protected void addPasswordStore(PasswordStore ps)
        {
                if(passwords == null) passwords = new HashSet();
                passwords.add(ps);
        }

        protected PasswordStore getDefaultPasswordStore()
                throws ModelException
        {
                if(passwords == null)
                        throw new ModelException("No password store");

                for(Iterator i = passwords.iterator(); i.hasNext(); ) {
                        Object o = i.next();
                        if(!(o instanceof PasswordStore))
                                throw new ModelException("It's not a password store");
                        PasswordStore ps = (PasswordStore)o;
                        if(DEFAULT_PASSWORD_STORE.equals(ps.getDigest()))
                                return ps;
                }

                throw new ModelException("No password store for digest " + DEFAULT_PASSWORD_STORE);
        }

        public String getPassword(User editor)
                throws ModelException
    {
                if(!partEditableBy(editor))
                        throw new ModelSecurityException();

        return getDefaultPasswordStore().getPassword();
    }

        public void setPassword(User editor, String password)
                throws ModelException
        {
                if(!partEditableBy(editor))
                        throw new ModelSecurityException();

                if(password == null)
                        throw new NullPointerException("Null password");

        backupMe();

                for(Iterator i = passwords.iterator(); i.hasNext(); ) {
                        Object o = i.next();
                        if(!(o instanceof PasswordStore))
                                throw new ModelException("It's not a password store");
                        ((PasswordStore)o).setNewPassword(password);
                }
        }

        public boolean checkPassword(String password)
                throws ModelException
        {
                if(password == null)
                        throw new NullPointerException("Null password");

                return getDefaultPasswordStore().checkPassword(password);
        }

        /**
         *
         * @hibernate.set                    cascade="all" lazy="true"
         * @hibernate.collection-key         column="obj"
         * @hibernate.collection-one-to-many class="ak.hostadmiral.core.model.PasswordStoreAbstract"
         */
        protected Collection getPasswords()
        {
                return passwords;
        }

        protected void setPasswords(Collection passwords)
        {
                this.passwords = passwords;
        }

        /**
         *
         * @hibernate.many-to-one
         */
        public User getBoss()
        {
                return boss;
        }

        protected void setBoss(User boss)
        {
                this.boss = boss;
        }

        public void setBoss(User editor, User boss)
                throws ModelException
        {
                if(!mayChangeBoss(editor))
                        throw new ModelSecurityException();

        backupMe();
                this.boss = boss;
        }

        /**
         *
         * @hibernate.property
         */
        public Boolean getSuperuser()
        {
                return superuser;
        }

        public boolean isSuperuser()
        {
                return (superuser != null) && superuser.booleanValue();
        }

        protected void setSuperuser(Boolean superuser)
        {
                this.superuser = superuser;
        }

        public void setSuperuser(User editor, Boolean superuser)
                throws ModelException
        {
                if(!mayChangeSuperuser(editor))
                        throw new ModelSecurityException();

        backupMe();
                this.superuser = superuser;
        }

        /**
         *
         * @hibernate.property column="locale"
         */
        protected String getLocaleName()
        {
                return locale.toString();
        }

        protected void setLocaleName(String localeName)
        {
                String language = null;
                String country  = null;

                if(localeName != null) {
                        StringTokenizer t = new StringTokenizer(localeName, "_");
                        if(t.hasMoreTokens()) language = t.nextToken();
                        if(t.hasMoreTokens()) country  = t.nextToken();
                }

                if(language == null)
                        this.locale = Locale.getDefault();
                else if(country == null)
                        this.locale = new Locale(language);
                else
                        this.locale = new Locale(language, country);
        }

        public void setLocaleName(User editor, String localeName)
                throws ModelException
        {
                if(!partEditableBy(editor))
                        throw new ModelSecurityException();

        backupMe();
                setLocaleName(localeName);
        }

        public Locale getLocale()
        {
                return locale;
        }

        public void setLocale(User editor, Locale locale)
                throws ModelException
        {
                if(!partEditableBy(editor))
                        throw new ModelSecurityException();

        backupMe();
                this.locale = locale;
        }

        /**
         *
         * @hibernate.set                    lazy="true"
         * @hibernate.collection-key         column="usr"
         * @hibernate.collection-one-to-many class="ak.hostadmiral.core.model.UserLogin"
         */
        protected Collection getLoginHistory()
        {
                return loginHistory;
        }

        public Collection getLogins()
        {
                return Collections.unmodifiableCollection(loginHistory);
        }

        protected void setLoginHistory(Collection loginHistory)
        {
                this.loginHistory = loginHistory;
        }

        public boolean equals(Object o)
        {
                if(o == null || !(o instanceof User)) return false;

                User u = (User)o;
                return (getId() != null) && (u.getId() != null) && (getId().equals(u.getId()));
        }

        protected void update(User origin)
        {
                this.login     = origin.login;
                this.boss      = origin.boss;
                this.superuser = origin.superuser;
                this.locale    = origin.locale;
        }

        public int hashCode()
        {
                if(getId() == null)
                        return 0;
                else
                        return getId().hashCode();
        }

        public String getTypeKey()
        {
                return ak.hostadmiral.core.CoreResources.TYPE_USER;
        }

        public String getIdentKey()
        {
                return ak.hostadmiral.core.CoreResources.IDENT_USER;
        }

        public Object[] getIdentParams()
        {
                return new Object[] { getLogin() };
        }

        public boolean viewableBy(User user)
        {
                return user.isSuperuser() || user.equals(boss) || user.equals(this);
        }

        public boolean editableBy(User user)
        {
                return user.isSuperuser() || user.equals(boss);
        }

        public boolean deleteableBy(User user)
        {
                return !user.equals(this) && (user.isSuperuser() || user.equals(boss));
        }

        // editor is allowed to change some additional properties
        public boolean partEditableBy(User user)
        {
                return user.isSuperuser() || user.equals(boss) || user.equals(this);
        }

        public boolean mayChangeBoss(User user)
        {
                return user.isSuperuser();
        }

        public boolean mayChangeSuperuser(User user)
        {
                return user.isSuperuser() && !user.equals(this);
        }

        public boolean mayViewAllLogins()
        {
                return isSuperuser();
        }

        protected static boolean allowedToCreate(UserManager manager, User editor)
                throws ModelException
        {
                return editor.isSuperuser()
                        || InetDomainManager.getInstance().areInetDomainsAvailable(editor);
                // FIXME: or allow any user to create "subusers"?
        }

        protected static User createLimitedCopy(User origin)
        {
                User u = new User();
                u.setLogin(origin.getLogin());
                return u;
        }

        public String toString()
        {
                return getClass().getName() + " [" + getId() + "] [" + getLogin() + "]";
        }
}