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 }