001 /****************************************************************
002 * Licensed to the Apache Software Foundation (ASF) under one *
003 * or more contributor license agreements. See the NOTICE file *
004 * distributed with this work for additional information *
005 * regarding copyright ownership. The ASF licenses this file *
006 * to you under the Apache License, Version 2.0 (the *
007 * "License"); you may not use this file except in compliance *
008 * with the License. You may obtain a copy of the License at *
009 * *
010 * http://www.apache.org/licenses/LICENSE-2.0 *
011 * *
012 * Unless required by applicable law or agreed to in writing, *
013 * software distributed under the License is distributed on an *
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
015 * KIND, either express or implied. See the License for the *
016 * specific language governing permissions and limitations *
017 * under the License. *
018 ****************************************************************/
019
020 package org.apache.james.user.jpa.model;
021
022 import javax.persistence.Basic;
023 import javax.persistence.Column;
024 import javax.persistence.Entity;
025 import javax.persistence.Id;
026 import javax.persistence.NamedQueries;
027 import javax.persistence.NamedQuery;
028 import javax.persistence.Table;
029 import javax.persistence.Version;
030
031 import org.apache.commons.codec.digest.DigestUtils;
032 import org.apache.james.user.api.model.User;
033
034 @Entity(name = "JamesUser")
035 @Table(name = "JAMES_USER")
036 @NamedQueries({
037 @NamedQuery(name = "findUserByName", query = "SELECT user FROM JamesUser user WHERE user.name=:name"),
038 @NamedQuery(name = "deleteUserByName", query = "DELETE FROM JamesUser user WHERE user.name=:name"),
039 @NamedQuery(name = "containsUser", query = "SELECT COUNT(user) FROM JamesUser user WHERE user.name=:name"),
040 @NamedQuery(name = "countUsers", query = "SELECT COUNT(user) FROM JamesUser user"),
041 @NamedQuery(name = "listUserNames", query = "SELECT user.name FROM JamesUser user") })
042 public class JPAUser implements User {
043
044 /**
045 * Hash password.
046 *
047 * @param username
048 * not null
049 * @param password
050 * not null
051 * @return not null
052 */
053 private static String hashPassword(String username, String password, String alg) {
054 String newPass;
055 if (alg == null || alg.equals("MD5")) {
056 newPass = DigestUtils.md5Hex(password);
057 } else if (alg.equals("NONE")) {
058 newPass = "password";
059 } else if (alg.equals("SHA-256")) {
060 newPass = DigestUtils.sha256Hex(password);
061 } else if (alg.equals("SHA-512")) {
062 newPass = DigestUtils.sha512Hex(password);
063 } else {
064 newPass = DigestUtils.shaHex(password);
065 }
066 return newPass;
067 }
068
069 /** Prevents concurrent modification */
070 @SuppressWarnings("unused")
071 @Version
072 private int version;
073
074 /** Key by user name */
075 @Id
076 @Column(name = "USER_NAME", nullable = false, length = 100)
077 private String name;
078
079 /** Hashed password */
080 @Basic
081 @Column(name = "PASSWORD", nullable = false, length = 100)
082 private String password;
083
084 @Basic
085 @Column(name = "PASSWORD_HASH_ALGORITHM", nullable = false, length = 100)
086 private String alg;
087
088 protected JPAUser() {
089 }
090
091 public JPAUser(final String userName, String password, String alg) {
092 super();
093 this.name = userName;
094 this.alg = alg;
095 this.password = hashPassword(userName, password, alg);
096 }
097
098 /**
099 * @see org.apache.james.user.api.model.User#getUserName()
100 */
101 public String getUserName() {
102 return name;
103 }
104
105 /**
106 * @see org.apache.james.user.api.model.User#setPassword(java.lang.String)
107 */
108 public boolean setPassword(String newPass) {
109 final boolean result;
110 if (newPass == null) {
111 result = false;
112 } else {
113 password = hashPassword(name, newPass, alg);
114 result = true;
115 }
116 return result;
117 }
118
119 /**
120 * @see org.apache.james.user.api.model.User#verifyPassword(java.lang.String)
121 */
122 public boolean verifyPassword(String pass) {
123 final boolean result;
124 if (pass == null) {
125 result = password == null;
126 } else if (password == null) {
127 result = false;
128 } else {
129 result = password.equals(hashPassword(name, pass, alg));
130 }
131 return result;
132 }
133
134 @Override
135 public int hashCode() {
136 final int PRIME = 31;
137 int result = 1;
138 result = PRIME * result + ((name == null) ? 0 : name.hashCode());
139 return result;
140 }
141
142 @Override
143 public boolean equals(Object obj) {
144 if (this == obj)
145 return true;
146 if (obj == null)
147 return false;
148 if (getClass() != obj.getClass())
149 return false;
150 final JPAUser other = (JPAUser) obj;
151 if (name == null) {
152 if (other.name != null)
153 return false;
154 } else if (!name.equals(other.name))
155 return false;
156 return true;
157 }
158
159 @Override
160 public String toString() {
161 return "[User " + name + "]";
162 }
163
164 }