Java tutorial
/* * Copyright 2014 Conseil7. * * 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 octavio.server.db.managers; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Iterator; import octavio.server.db.entities.User; import octavio.server.exception.CommandException; import octavio.server.util.Configuration; import octavio.server.util.Logger; import org.apache.commons.codec.binary.Hex; /** * Gestionnaire des objets utilisateur. Enregistre, rcupre et supprime les * utilisateurs de la base de donnes. Permet galement l'identification d'un * utilisaeur via son nom et son mot de passe hash. Peut vrifier la * disponibilit d'un nom d'utilisateur. * * @author Lzard */ public class UserManager extends Manager { /** * Requte pour rcuprer un utilisateur. */ private static final String QUERY_USER = "SELECT `id`, `name` FROM `user` WHERE `id` = ?"; /** * Requte pour rcuprer un utilisateur avec son nom et son mot de passe. */ private static final String QUERY_USER_BY_LOGIN = "SELECT `id`, `name` FROM `user` WHERE `name` = ? AND `password` = ? LIMIT 1"; /** * Requte pour vrifier qu'un pseudo n'est pas utilis. */ private static final String QUERY_NAME_AVAILABLE = "SELECT 1 FROM `user` WHERE `name` = ? LIMIT 1"; /** * Requte pour les paramtres d'un utilisateur. */ private static final String QUERY_USER_PARAMETERS = "SELECT `parameter`, `value` FROM `user_parameters` WHERE `user_id` = ?"; /** * Requte pour rcuprer les droits d'un utilisateur. */ private static final String QUERY_USER_RIGHTS = "SELECT `right`, `value` FROM `user_rights` WHERE `user_id` = ?"; /** * Requte pour ajouter un utilisateur. */ private static final String INSERT_USER = "INSERT INTO `user` (`name`, `password`) VALUES(?, ?)"; /** * Requte pour modifier les paramtre d'un utilisateur. */ private static final String INSERT_USER_PARAMETERS = "INSERT INTO `user_parameters` (`user_id`, `parameter`, `value`) VALUES(?, ?, ?)"; /** * Requte pour modifier les droits d'un utilisateur. */ private static final String INSERT_USER_RIGHTS = "INSERT INTO `user_rights` (`user_id`, `right`, `value`) VALUES(?, ?, ?)"; /** * Requte pour modifier un utilisateur. */ private static final String UPDATE_USER_NAME = "UPDATE `user` SET `name` = ? WHERE `id` = ?"; /** * Requte pour modifier un utilisateur. */ private static final String UPDATE_USER_PASSWORD = "UPDATE `user` SET `password` = ? WHERE `id` = ?"; /** * Requte pour supprimer un utilisateur. */ private static final String DELETE_USER = "DELETE FROM `user` WHERE `id` = ?"; /** * Requte pour supprimer les paramtres d'un utilisateur. */ private static final String DELETE_USER_PARAMETERS = "DELETE FROM `user_parameters` WHERE `user_id` = ?"; /** * Requte pour supprimer les droits d'un utilisateur. */ private static final String DELETE_USER_RIGHTS = "DELETE FROM `user_rights` WHERE `user_id` = ?"; /** * Retourne la chaine de caractres fournie en paramtre hashe avec * l'algorithme configur. * * @param password Mot de passe hasher * * @return Mot de passe hash ou chane vide si algorithme indisponible */ public static String hashPassword(String password) { try { MessageDigest digest = MessageDigest.getInstance(Configuration.get("hash_algorithm", "SHA-1")); digest.reset(); digest.update(password.getBytes()); return new String(Hex.encodeHex(digest.digest())); } catch (NoSuchAlgorithmException exception) { Logger.printError(exception); return password; } } /** * Initialise la connexion la base de donnes. Appel le constructeur de la * classe Manager pour rcuprer la connexion la base de donnes. * * @param connection Connexion la base de donnes */ public UserManager(Connection connection) { super(connection); } /** * Rcupre un utilisateur via son nom et son mot de passe hash. * * @param id Identifiant de l'utilisateur * * @return Instance d'User correspondant * * @throws CommandException Erreur de login * @throws SQLException Erreur SQL */ public User getUser(int id) throws CommandException, SQLException { // Prparation et excution de la requte PreparedStatement statement = this.query(UserManager.QUERY_USER); statement.setInt(1, id); ResultSet set = statement.executeQuery(); // Retourne l'utilisateur trouv if (set.first()) { User user = new User(set.getInt("id"), set.getString("name")); return user; } else { CommandException exception = new CommandException("Unknown username", "unknown_user"); exception.setArgument("id", String.valueOf(id)); throw exception; } } /** * Rcupre un utilisateur via son nom et son mot de passe hash. * * @param name Nom de l'utilisateur * @param password Mot de passe hash de l'utilisateur * * @return Instance d'User correspondant l'utilisateur trouv ou null * * @throws CommandException Erreur de login * @throws SQLException Erreur SQL */ public User getUser(String name, String password) throws CommandException, SQLException { // Prparation et excution de la requte PreparedStatement statement = this.query(UserManager.QUERY_USER_BY_LOGIN); statement.setString(1, name); statement.setString(2, password); ResultSet set = statement.executeQuery(); // Retourne l'utilisateur si le nom existe if (set.first()) { User user = new User(set.getInt("id"), set.getString("name")); statement = this.query(UserManager.QUERY_USER_PARAMETERS); statement.setInt(1, user.getId()); set = statement.executeQuery(); while (set.next()) { user.setParameter(set.getString("parameter"), set.getString("value")); } statement = this.query(UserManager.QUERY_USER_RIGHTS); statement.setInt(1, user.getId()); set = statement.executeQuery(); while (set.next()) { user.setRight(set.getString("right"), set.getString("value")); } return user; } else { CommandException exception = new CommandException("Wrong username or password", "log_error"); exception.setArgument("name", name); throw exception; } } /** * Indique si un nom d'utilisateur est disponible. * * @param name Nom vrifier * * @return Disponibilit du nom * * @throws SQLException Erreur SQL */ public boolean getNameAvailability(String name) throws SQLException { // Prparation et excution de la requte PreparedStatement statement = this.query(UserManager.QUERY_NAME_AVAILABLE); statement.setString(1, name); ResultSet set = statement.executeQuery(); // Vrai si le rsultat est vide return !set.first(); } /** * Insre un nouvel utilisateur dans la base de donnes. * * @param name Nom de l'utilisateur * @param password Mot de passe clair de l'utilisateur * * @throws SQLException Erreur SQL */ public void insertUser(String name, String password) throws SQLException { PreparedStatement statement = this.query(UserManager.INSERT_USER); statement.setString(1, name); statement.setString(2, UserManager.hashPassword(password)); statement.executeUpdate(); } /** * Sauvegarde d'un utilisateur dans la base de donnes. Si l'utilisateur n'a * pas d'identifiant attribu, une nouvelle entre lui est cre dans la * table et un nouvel identifiant lui est attribu. Sinon, la ligne de * l'utilisateur est mise jour. * * @param user Utilisateur sauvegarder * * @throws SQLException Erreur SQL */ public void updateUserName(User user) throws SQLException { PreparedStatement statement = this.query(UserManager.UPDATE_USER_NAME); statement.setString(1, user.getName()); statement.setInt(2, user.getId()); statement.executeUpdate(); } /** * Modifie le mot de passe d'un utilisateur. * * @param user Utilisateur * @param password Nouveau mot de passe clair * * @throws SQLException Erreur SQL */ public void updateUserPassword(User user, String password) throws SQLException { PreparedStatement statement = this.query(UserManager.UPDATE_USER_PASSWORD); statement.setString(1, UserManager.hashPassword(password)); statement.setInt(2, user.getId()); statement.executeUpdate(); } /** * Modifie les paramtres de l'utilisateur. * * @param user Utilisateur mettre jour * * @throws SQLException Erreur SQL */ public void updateUserParameters(User user) throws SQLException { PreparedStatement statement = this.query(UserManager.DELETE_USER_PARAMETERS); statement.setInt(1, user.getId()); statement.executeUpdate(); for (String parameter : user.getParameters().stringPropertyNames()) { statement = this.query(UserManager.INSERT_USER_PARAMETERS); statement.setString(1, parameter); statement.setString(2, user.getParameter(parameter, "")); statement.setInt(3, user.getId()); } } /** * Modifie les droits de l'utilisateur. * * @param user Utilisateur mettre jour * * @throws SQLException Erreur SQL */ public void updateUserRights(User user) throws SQLException { PreparedStatement statement = this.query(UserManager.DELETE_USER_RIGHTS); statement.setInt(1, user.getId()); statement.executeUpdate(); for (String right : user.getRights().stringPropertyNames()) { statement = this.query(UserManager.INSERT_USER_RIGHTS); statement.setString(1, right); statement.setString(2, user.getRight(right, "")); statement.setInt(3, user.getId()); } } /** * Supprime un utilisateur de la base de donnes. * * @param user Utilisateur supprimer * * @throws SQLException Erreur SQL */ public void deleteUser(User user) throws SQLException { PreparedStatement statement = this.query(UserManager.DELETE_USER); statement.setInt(1, user.getId()); statement.executeUpdate(); } }