X-Git-Url: http://wamblee.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=security%2Fimpl%2Fsrc%2Fmain%2Fjava%2Forg%2Fwamblee%2Fsecurity%2Fauthentication%2FUser.java;fp=security%2Fimpl%2Fsrc%2Fmain%2Fjava%2Forg%2Fwamblee%2Fsecurity%2Fauthentication%2FUser.java;h=03c15eea9297c6296b0a21f8bd2fae93fec9bded;hb=0adf8fb6e00f08a022379cff5edb43fcde30184c;hp=0000000000000000000000000000000000000000;hpb=225f5d67c047f25de6bd53ae24f120fbc7fee620;p=utils diff --git a/security/impl/src/main/java/org/wamblee/security/authentication/User.java b/security/impl/src/main/java/org/wamblee/security/authentication/User.java new file mode 100644 index 00000000..03c15eea --- /dev/null +++ b/security/impl/src/main/java/org/wamblee/security/authentication/User.java @@ -0,0 +1,409 @@ +/* + * 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.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 primaryKey; + + @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) + private Set groups; + + /** + * Password validator. + */ + @Transient + private NameValidator passwordValidator; + + /** + * Password encoder. + */ + @Transient + private MessageDigester passwordEncoder; + + /** + * Constructs the user. + * + * @param aName + * User name. + * @param aPassword + * Password. + * @param aGroup + * Group the user belongs to. + */ + User(String aName, String aPassword, Group aGroup, + NameValidator aPasswordValidator, MessageDigester aPasswordEncoder) + throws UserMgtException { + super(); + name = aName; + aPasswordValidator.validate(aPassword); + password = aPasswordEncoder.hash(aPassword); + groups = new TreeSet(); + groups.add(aGroup); + passwordValidator = aPasswordValidator; + passwordEncoder = aPasswordEncoder; + } + + /** + * Creates a new User object. + * + */ + public User(User aUser) { + primaryKey = aUser.primaryKey; + version = aUser.version; + name = aUser.name; + password = aUser.password; + groups = new TreeSet(); + + 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. + * + * @throws UserMgtException + * In case the password is incorrect. + */ + public void checkPassword(String aPassword) throws UserMgtException { + String encoded = passwordEncoder.hash(aPassword); + + if (!password.equals(encoded)) { + throw new UserMgtException(Reason.INVALID_PASSWORD, this); + } + } + + /** + * Changes the password. + * + * @param aOldPassword + * Old password. + * @param aNewPassword + * New password. + * + * @throws UserMgtException + * In case the old password is incorrect. + */ + public void changePassword(String aOldPassword, String aNewPassword) + throws UserMgtException { + checkPassword(aOldPassword); + passwordValidator.validate(aNewPassword); + setPassword(aNewPassword); + } + + /** + * + * @param aPassword + * The password to set. + * + */ + public void setPassword(String aPassword) throws UserMgtException { + 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 getGroups() { + Set result = new TreeSet(); + 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 getGroupSet() { + return groups; + } + + /** + * Sets the groups the user belongs to, for OR mapping. + * + * @param aGroups + * Groups. + */ + void setGroupSet(Set 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) throws UserMgtException { + if (!groups.contains(aGroup)) { + throw new UserMgtException(Reason.USER_NOT_IN_GROUP, this, aGroup); + } + + if (groups.size() == 1) { + throw new UserMgtException(Reason.USER_MUST_BE_IN_A_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 primaryKey; + } +}