001 // This file is part of AceWiki.
002 // Copyright 2008-2012, AceWiki developers.
003 //
004 // AceWiki is free software: you can redistribute it and/or modify it under the terms of the GNU
005 // Lesser General Public License as published by the Free Software Foundation, either version 3 of
006 // the License, or (at your option) any later version.
007 //
008 // AceWiki is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
009 // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
010 // Lesser General Public License for more details.
011 //
012 // You should have received a copy of the GNU Lesser General Public License along with AceWiki. If
013 // not, see http://www.gnu.org/licenses/.
014
015 package ch.uzh.ifi.attempto.acewiki.core;
016
017 import java.security.MessageDigest;
018 import java.util.ArrayList;
019 import java.util.List;
020 import java.util.Map;
021
022 /**
023 * This class represents an AceWiki user.
024 *
025 * @author Tobias Kuhn
026 */
027 public class User {
028
029 private final long id;
030 private String name;
031 private String hashedPw;
032 private Map<String, String> userdata;
033 private final UserBase userBase;
034
035 /**
036 * Creates a new user.
037 *
038 * @param id The user id.
039 * @param name The name of the user.
040 * @param hashedPw The hashed password.
041 * @param userdata The user data map.
042 */
043 User(long id, String name, String hashedPw, Map<String, String> userdata, UserBase userBase) {
044 this.id = id;
045 this.name = name;
046 this.hashedPw = hashedPw;
047 this.userdata = userdata;
048 this.userBase = userBase;
049 save();
050 }
051
052 /**
053 * Creates a new user.
054 *
055 * @param id The user id.
056 * @param name The name of the user.
057 * @param pw The password in plain text.
058 * @param userdata The user data map.
059 * @return The new user object.
060 */
061 static User createUser(long id, String name, String pw, Map<String, String> userdata, UserBase userBase) {
062 return new User(id, name, getPasswordHash(pw), userdata, userBase);
063 }
064
065 /**
066 * Returns the id of the user.
067 *
068 * @return The id.
069 */
070 public long getId() {
071 return id;
072 }
073
074 /**
075 * Returns the name of the user.
076 *
077 * @return The name of the user.
078 */
079 public String getName() {
080 return name;
081 }
082
083 /**
084 * Returns the hashed password.
085 *
086 * @return The hashed password.
087 */
088 public String getHashedPassword() {
089 return hashedPw;
090 }
091
092 /**
093 * Returns the user data with the given property name.
094 *
095 * @param name The property name.
096 * @return The data for the respective name.
097 */
098 public String getUserData(String name) {
099 String value = userdata.get(name);
100 if (value == null) return "";
101 return value;
102 }
103
104 /**
105 * Sets the user data element with the respective name.
106 *
107 * @param name The name of the user data element.
108 * @param value The value to be set.
109 */
110 public void setUserData(String name, String value) {
111 userdata.put(name, value);
112 save();
113 }
114
115 /**
116 * Changes the password for the user.
117 *
118 * @param oldPw The old password in plain text.
119 * @param newPw The new password in plain text.
120 */
121 public void changePassword(String oldPw, String newPw) {
122 if (!isCorrectPassword(oldPw)) return;
123 hashedPw = getPasswordHash(newPw);
124 save();
125 }
126
127 /**
128 * Adds to a counter in the user data.
129 *
130 * @param name The name of the user data element.
131 * @param c The value by which the counter should be increased.
132 */
133 public void addToUserDataCounter(String name, int c) {
134 String value = userdata.get(name);
135 if (value == null) {
136 userdata.put(name, c + "");
137 } else {
138 int v;
139 try {
140 v = new Integer(value);
141 } catch (NumberFormatException ex) {
142 v = 0;
143 }
144 userdata.put(name, (v + c) + "");
145 }
146 save();
147 }
148
149 /**
150 * Checks whether a certain password is the correct password for this user.
151 *
152 * @param pw The password to be checked in plain text.
153 * @return true if the password is correct.
154 */
155 public boolean isCorrectPassword(String pw) {
156 return getPasswordHash(pw).equals(hashedPw);
157 }
158
159 /**
160 * Returns a hash value for a given plain-text password using the SHA-256 algorithm.
161 *
162 * @param password The plain-text password for which a hash value should be created.
163 * @return The hash value.
164 */
165 public static String getPasswordHash(String password) {
166 try {
167 MessageDigest md = MessageDigest.getInstance("SHA-256");
168 md.update(password.getBytes());
169 byte[] byteData = md.digest();
170 StringBuffer sb = new StringBuffer();
171 for (int i = 0; i < byteData.length; i++) {
172 sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
173 }
174 return sb.toString();
175 } catch (Exception ex) {
176 ex.printStackTrace();
177 return null;
178 }
179 }
180
181 /**
182 * Returns the user base to which this user belongs.
183 *
184 * @return The user base.
185 */
186 public UserBase getUserBase() {
187 return userBase;
188 }
189
190 /**
191 * Returns all key of this user's properties in the form of key/value pairs.
192 *
193 * @return All user data keys.
194 */
195 public List<String> getUserDataKeys() {
196 return new ArrayList<String>(userdata.keySet());
197 }
198
199 private void save() {
200 userBase.getStorage().save(this);
201 }
202
203 }