// This file is part of AceWiki. // Copyright 2008-2013, AceWiki developers. // // AceWiki is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License as published by the Free Software Foundation, either version 3 of // the License, or (at your option) any later version. // // AceWiki is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with AceWiki. If // not, see http://www.gnu.org/licenses/. package ch.uzh.ifi.attempto.acewiki.core; import java.security.MessageDigest; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableSet; /** * This class represents an AceWiki user. * * @author Tobias Kuhn */ public class User { private static final Splitter SPLITTER_RIGHTS = Splitter.on(",").omitEmptyStrings().trimResults(); private final long id; private String name; private String hashedPw; private Map<String, String> userdata; private final UserBase userBase; /** * Creates a new user. * * @param id The user id. * @param name The name of the user. * @param hashedPw The hashed password. * @param userdata The user data map. */ User(long id, String name, String hashedPw, Map<String, String> userdata, UserBase userBase) { this.id = id; this.name = name; this.hashedPw = hashedPw; this.userdata = userdata; this.userBase = userBase; save(); } /** * Creates a new user. * * @param id The user id. * @param name The name of the user. * @param pw The password in plain text. * @param userdata The user data map. * @return The new user object. */ static User createUser(long id, String name, String pw, Map<String, String> userdata, UserBase userBase) { return new User(id, name, getPasswordHash(pw), userdata, userBase); } /** * Returns the id of the user. * * @return The id. */ public long getId() { return id; } /** * Returns the name of the user. * * @return The name of the user. */ public String getName() { return name; } /** * Returns the hashed password. * * @return The hashed password. */ public String getHashedPassword() { return hashedPw; } // The rights can be granted by manually editing the users' file and adding a line a la: // rights:all,some,delete_user,edit_grammar public Set<String> getRights() { return ImmutableSet.copyOf(SPLITTER_RIGHTS.split(getUserData("rights"))); } public boolean hasRight(String right) { Set<String> rights = getRights(); if (rights.contains("all")) return true; return rights.contains(right); } /** * Returns the user data with the given property name. * * @param name The property name. * @return The data for the respective name. */ public String getUserData(String name) { String value = userdata.get(name); if (value == null) return ""; return value; } /** * Sets the user data element with the respective name. * * @param name The name of the user data element. * @param value The value to be set. */ public void setUserData(String name, String value) { userdata.put(name, value); save(); } /** * Changes the password for the user. * * @param oldPw The old password in plain text. * @param newPw The new password in plain text. */ public void changePassword(String oldPw, String newPw) { if (!isCorrectPassword(oldPw)) return; hashedPw = getPasswordHash(newPw); save(); } /** * Adds to a counter in the user data. * * @param name The name of the user data element. * @param c The value by which the counter should be increased. */ public void addToUserDataCounter(String name, int c) { String value = userdata.get(name); if (value == null) { userdata.put(name, c + ""); } else { int v; try { v = new Integer(value); } catch (NumberFormatException ex) { v = 0; } userdata.put(name, (v + c) + ""); } save(); } /** * Checks whether a certain password is the correct password for this user. * * @param pw The password to be checked in plain text. * @return true if the password is correct. */ public boolean isCorrectPassword(String pw) { return getPasswordHash(pw).equals(hashedPw); } /** * Returns a hash value for a given plain-text password using the SHA-256 algorithm. * * @param password The plain-text password for which a hash value should be created. * @return The hash value. */ public static String getPasswordHash(String password) { try { MessageDigest md = MessageDigest.getInstance("SHA-256"); md.update(password.getBytes()); byte[] byteData = md.digest(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < byteData.length; i++) { sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1)); } return sb.toString(); } catch (Exception ex) { ex.printStackTrace(); return null; } } /** * Returns the user base to which this user belongs. * * @return The user base. */ public UserBase getUserBase() { return userBase; } /** * Returns all key of this user's properties in the form of key/value pairs. * * @return All user data keys. */ public List<String> getUserDataKeys() { return new ArrayList<String>(userdata.keySet()); } private void save() { userBase.getStorage().save(this); } }