(no commit message)
[utils] / security / usermgt / src / main / java / org / wamblee / security / authentication / User.java
diff --git a/security/usermgt/src/main/java/org/wamblee/security/authentication/User.java b/security/usermgt/src/main/java/org/wamblee/security/authentication/User.java
new file mode 100644 (file)
index 0000000..12db71a
--- /dev/null
@@ -0,0 +1,401 @@
+/*
+ * Copyright 2005-2010 the original author or authors.
+ * 
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 org.wamblee.security.authentication;
+
+import java.io.Serializable;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import javax.persistence.Version;
+
+import org.wamblee.security.authentication.UserMgtException.Reason;
+import org.wamblee.security.encryption.MessageDigester;
+
+/**
+ * Represents a user. The methods for managing the groups of the user have
+ * package scope. Managing the groups of the user should be done through the
+ * {@link org.wamblee.security.authentication.UserAdministration} interface.
+ */
+@Entity
+@Table(name = "SEC_USER")
+@NamedQueries( {
+    @NamedQuery(name = User.QUERY_FIND_BY_NAME, query = "select u from User u where u.name = :" +
+        User.NAME_PARAM),
+    @NamedQuery(name = User.QUERY_FIND_BY_GROUP_NAME, query = "select user from User user join user.groups grp where grp.name = :name"),
+    @NamedQuery(name = User.QUERY_COUNT_USERS, query = "select count(u) from User u"),
+    @NamedQuery(name = User.QUERY_ALL_USERS, query = "select u from User u") })
+public class User implements Serializable, Comparable {
+
+    public static final String QUERY_FIND_BY_NAME = "User.findByName";
+    public static final String QUERY_FIND_BY_GROUP_NAME = "User.findByGroupName";
+    public static final String QUERY_COUNT_USERS = "User.count";
+    public static final String QUERY_ALL_USERS = "User.all";
+    public static final String NAME_PARAM = "name";
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @Version
+    private int version;
+
+    /**
+     * User name.
+     */
+    private String name;
+
+    /**
+     * Password.
+     */
+    private String password;
+
+    /**
+     * Groups the user belongs to.
+     */
+    @ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
+    @JoinTable(name = "SEC_USER_GROUP", joinColumns = { @JoinColumn(name = "USER_ID") }, inverseJoinColumns = { @JoinColumn(name = "GROUP_ID") })
+    private Set<Group> groups;
+
+    /**
+     * Password validator.
+     */
+    @Transient
+    private NameValidator passwordValidator;
+
+    /**
+     * Password encoder.
+     */
+    @Transient
+    private MessageDigester passwordEncoder;
+
+    /**
+     * Constructs the user.
+     * 
+     * @param aName
+     *            User name.
+     * @param aPassword
+     *            Password.
+     */
+    User(String aName, String aPassword, NameValidator aPasswordValidator,
+        MessageDigester aPasswordEncoder) {
+        super();
+        name = aName;
+        aPasswordValidator.validate(aPassword);
+        password = aPasswordEncoder.hash(aPassword);
+        groups = new TreeSet<Group>();
+        passwordValidator = aPasswordValidator;
+        passwordEncoder = aPasswordEncoder;
+    }
+
+    /**
+     * Creates a new User object.
+     * 
+     */
+    public User(User aUser) {
+        id = aUser.id;
+        version = aUser.version;
+        name = aUser.name;
+        password = aUser.password;
+        groups = new TreeSet<Group>();
+
+        for (Group group : aUser.groups) {
+            groups.add(new Group(group));
+        }
+
+        passwordValidator = aUser.passwordValidator;
+        passwordEncoder = aUser.passwordEncoder;
+    }
+
+    /**
+     * Creates a new User object.
+     */
+    User() {
+        super();
+        name = null;
+        password = null;
+        groups = null;
+        passwordValidator = null;
+        passwordEncoder = null;
+    }
+
+    /**
+     * Sets the password validator.
+     * 
+     * @param aPasswordValidator
+     *            Validator.
+     */
+    public void setPasswordValidator(NameValidator aPasswordValidator) {
+        passwordValidator = aPasswordValidator;
+    }
+
+    /**
+     * Sets the password encoder.
+     * 
+     * @param aPasswordEncoder
+     *            Encoder.
+     */
+    public void setPasswordEncoder(MessageDigester aPasswordEncoder) {
+        passwordEncoder = aPasswordEncoder;
+    }
+
+    /**
+     * 
+     * @return Returns the password.
+     */
+    String getPassword() {
+        return password;
+    }
+
+    /**
+     * Checks the password.
+     * 
+     * @param aPassword
+     *            Password to check.
+     * 
+     * @return True iff the password is correct.
+     */
+    public boolean checkPassword(String aPassword) {
+        String encoded = passwordEncoder.hash(aPassword);
+
+        return password.equals(encoded);
+    }
+
+    /**
+     * Changes the password.
+     * 
+     * @param aOldPassword
+     *            Old password.
+     * @param aNewPassword
+     *            New password.
+     * 
+     * @return True iff the password was changed successfully.
+     */
+    public boolean changePassword(String aOldPassword, String aNewPassword) {
+        if (!checkPassword(aOldPassword)) {
+            return false;
+        }
+        passwordValidator.validate(aNewPassword);
+        setPassword(aNewPassword);
+        return true;
+    }
+
+    /**
+     * 
+     * @param aPassword
+     *            The password to set.
+     * 
+     */
+    public void setPassword(String aPassword) {
+        passwordValidator.validate(aPassword);
+        password = passwordEncoder.hash(aPassword);
+    }
+
+    /**
+     * For OR mapping.
+     * 
+     * @return Password.
+     */
+    protected String getPasswordString() {
+        return password;
+    }
+
+    /**
+     * For OR mapping.
+     * 
+     * @param aPassword
+     *            Password.
+     */
+    protected void setPasswordString(String aPassword) {
+        password = aPassword;
+    }
+
+    /**
+     * 
+     * @return Returns the _user.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * 
+     * @param aName
+     *            The username to set.
+     */
+    void setName(String aName) {
+        name = aName;
+    }
+
+    /**
+     * Gets the groups the user belongs to.
+     * 
+     * @return Groups.
+     */
+    public Set<Group> getGroups() {
+        Set<Group> result = new TreeSet<Group>();
+        result.addAll(groups);
+
+        return result;
+    }
+
+    /**
+     * Checks whether the user belongs to the given group.
+     * 
+     * @param aGroup
+     *            Group.
+     * 
+     * @return True if the user belongs to the group.
+     */
+    public boolean isInGroup(Group aGroup) {
+        return groups.contains(aGroup);
+    }
+
+    /**
+     * Checks whether the user belongs to the given group.
+     * 
+     * @param aGroup
+     *            Group.
+     * 
+     * @return True if the user belongs to the group.
+     */
+    public boolean isInGroup(String aGroup) {
+        return groups.contains(new Group(aGroup));
+    }
+
+    /**
+     * Gets the group set. For OR mapping.
+     * 
+     * @return set of groups.
+     */
+    Set<Group> getGroupSet() {
+        return groups;
+    }
+
+    /**
+     * Sets the groups the user belongs to, for OR mapping.
+     * 
+     * @param aGroups
+     *            Groups.
+     */
+    void setGroupSet(Set<Group> aGroups) {
+        groups = aGroups;
+    }
+
+    /**
+     * Adds the user to a group.
+     * 
+     * @param aGroup
+     *            Group to add the user to.
+     * 
+     * @throws UserMgtException
+     *             In case the user already belongs to the group.
+     */
+    void addGroup(Group aGroup) throws UserMgtException {
+        if (groups.contains(aGroup)) {
+            throw new UserMgtException(Reason.USER_ALREADY_IN_GROUP, aGroup);
+        }
+
+        groups.add(aGroup);
+    }
+
+    /**
+     * Removes the user from a group.
+     * 
+     * @param aGroup
+     *            Group.
+     * 
+     * @throws UserMgtException
+     *             In case the user does not belong to the group.
+     */
+    void removeGroup(Group aGroup) {
+        if (!groups.contains(aGroup)) {
+            throw new UserMgtException(Reason.USER_NOT_IN_GROUP, this, aGroup);
+        }
+
+        groups.remove(aGroup);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object aUser) {
+        if (aUser == null) {
+            return false;
+        }
+        if (!(aUser instanceof User)) {
+            return false;
+        }
+
+        User user = (User) aUser;
+
+        return name.equals(user.name);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        String result = "User(name=" + name + ", password=" + password;
+
+        for (Group group : groups) {
+            result += (", group=" + group);
+        }
+
+        return result + ")";
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Comparable#compareTo(T)
+     */
+    public int compareTo(Object aUser) {
+        return name.compareTo(((User) aUser).name);
+    }
+
+    public Long getPrimaryKey() {
+        return id;
+    }
+}