Java tutorial
/* * Copyright 2012-2016 Andrey Grigorov, Anton Grigorov * * 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 org.cherchgk.services; import org.apache.shiro.crypto.RandomNumberGenerator; import org.apache.shiro.crypto.SecureRandomNumberGenerator; import org.apache.shiro.crypto.hash.Sha512Hash; import org.apache.shiro.util.ByteSource; import org.cherchgk.domain.security.Permission; import org.cherchgk.domain.security.Role; import org.cherchgk.domain.security.Token; import org.cherchgk.domain.security.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import javax.mail.MessagingException; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.TypedQuery; import java.util.*; /** * ? ? ?? ??. * <p/> * ? ?? ?? , ? * ?? ? ?? ??. * * @author Andrey Grigorov */ @Transactional(rollbackFor = Throwable.class) public class SecurityService { /** * ? , ??? ?. * ? ? passwordMatcher.hashIterations, * .../web/WEB-INF/shiro.ini. */ private static final int hashIterations = 1024; private EntityManager entityManager; @Autowired private MailService mailService; @Autowired private SettingsService settingsService; @PersistenceContext public void setEntityManager(EntityManager entityManager) { this.entityManager = entityManager; } /** * ? . * ? ? ??, ? * ?. ? ? ??, * ? . * * @param roleName ? . * @param permissions ? . */ public void setRolePermissions(String roleName, Set<Permission> permissions) { Role role = getRoleByName(roleName); if (role == null) { role = new Role(); role.setName(roleName); role.setPermissions(permissions); entityManager.persist(role); } else { role.getPermissions().clear(); role.getPermissions().addAll(permissions); entityManager.merge(role); } } /** * ?, ? ??. * * @param username ? ?. * @param password . * @param roleName ? . */ public void createUserIfNotExist(String username, String password, String roleName) { User user = getUserByName(username); if (user == null) { createUser(username, password, null, getRoleByName(roleName), false); } } /** * ?. * * @param username ? ?. * @param password . * @param email ?? ? . * @param role . * @param blocked ? ?. true - , * false - . * @return . */ public User createUser(String username, String password, String email, Role role, boolean blocked) { User user = new User(); user.setUsername(username); setUserPassword(user, password); if (email != null) { user.setEmail(email.trim().toLowerCase()); } user.setBlocked(blocked); user.setRoles(new HashSet<Role>(Arrays.asList(role))); entityManager.persist(user); return user; } /** * ? ?? ? * ? ? ? ? ? ?? ? ? * ?. * ?? "organizer". * ?, ? ? , * ? ??? ?. * * @param username ? ?. * @param password . * @param email ?? ? . * @throws MessagingException ? ? ? ? * ?? ?. */ public void registerNewUser(String username, String password, String email) throws MessagingException { Role role = getRoleByName("organizer"); User user = createUser(username, password, email, role, true); Token token = new Token(); token.setType(Token.Type.SIGN_UP); token.setUuid(UUID.randomUUID().toString()); token.setUser(user); token.setCreateDate(new Date()); entityManager.persist(token); mailService.sendMail(email, "?? ?? ? \"? ? ?\"", "? ? ? <a href=\"" + settingsService.getHostName() + "/confirm-sign-up?tokenUUID=" + token.getUuid() + "\">??</a>."); } /** * ??? ? ?. * ?, ? ? ? * , ?? ? * . * * @param tokenUUID . * @return true - ?? ? , * false - . */ public boolean confirmRegistration(String tokenUUID) { Token token = getTokenByUUID(tokenUUID); if ((token == null) || !Token.Type.SIGN_UP.equals(token.getType())) { return false; } User user = token.getUser(); entityManager.remove(token); if (!user.getBlocked()) { return true; } user.setBlocked(false); entityManager.merge(user); return true; } /** * ? . * * @param tokenUUID . * @return ? null. */ private Token getTokenByUUID(String tokenUUID) { TypedQuery<Token> tokenQuery = entityManager .createQuery("select token " + "from Token token " + "where uuid = :tokenUUID", Token.class) .setParameter("tokenUUID", tokenUUID); tokenQuery.setHint("org.hibernate.cacheable", true); List<Token> tokens = tokenQuery.getResultList(); if (tokens.isEmpty()) { return null; } return tokens.get(0); } /** * ? , ???? * . * * @param user , . * @param tokenType , . */ private void deleteTokens(User user, Token.Type tokenType) { entityManager.createQuery("delete from Token where user = :user and type = :tokenType") .setParameter("user", user).setParameter("tokenType", tokenType).executeUpdate(); } /** * ??? ? * . * * @param tokenUUID . * @param tokenType . * @return true - ??, false - . */ public boolean isValidToken(String tokenUUID, Token.Type tokenType) { Token token = getTokenByUUID(tokenUUID); return (token != null) && token.getType().equals(tokenType); } /** * ? ? ? ? ?? ?. * * @param user . * @throws MessagingException ? ? ? ? * ? ?? ?. */ public void restorePassword(User user) throws MessagingException { deleteTokens(user, Token.Type.RESTORE_PASSWORD); Token token = new Token(); token.setType(Token.Type.RESTORE_PASSWORD); token.setUuid(UUID.randomUUID().toString()); token.setUser(user); token.setCreateDate(new Date()); entityManager.persist(token); mailService.sendMail(user.getEmail(), "?? ? ?? ? \"? ? ?\"", "? ? ? <a href=\"" + settingsService.getHostName() + "/show-set-new-password-page?tokenUUID=" + token.getUuid() + "\">??</a>."); } /** * ? ? . * * @param tokenUUID , ?? ? ??? ?. * @param password ? . * @return true - ? ? ?, false - ? ? * ?? ?. */ public boolean setNewPassword(String tokenUUID, String password) { Token token = getTokenByUUID(tokenUUID); if ((token == null) || !Token.Type.RESTORE_PASSWORD.equals(token.getType())) { return false; } setUserPassword(token.getUser(), password); entityManager.remove(token); return true; } /** * ? ?. * * @param user * @param password . */ public void setUserPassword(User user, String password) { RandomNumberGenerator rng = new SecureRandomNumberGenerator(); ByteSource salt = rng.nextBytes(); String passwordHash = new Sha512Hash(password, salt, hashIterations).toHex(); user.setPassword(passwordHash); user.setPasswordSalt(salt.toHex()); } /** * ?, . * * @param userId ?, . */ public void deleteUser(Long userId) { User user = getUserById(userId); entityManager.remove(user); } /** * ?? "". * * @param user . */ public void updateUser(User user) { entityManager.merge(user); } /** * . * * @param roleName ? . * @return null, ? ? ??. */ public Role getRoleByName(String roleName) { TypedQuery<Role> roleQuery = entityManager .createQuery("select role " + "from Role role " + "where role.name = :roleName", Role.class) .setParameter("roleName", roleName); roleQuery.setHint("org.hibernate.cacheable", true); List<Role> roles = roleQuery.getResultList(); return roles.isEmpty() ? null : roles.get(0); } /** * ? ( ?? {@link org.cherchgk.domain.security.User}) * (). * * @param username ? () ?. * @return null, ? ? ? . */ public User getUserByName(String username) { TypedQuery<User> userQuery = entityManager .createQuery("select user " + "from User user " + "where user.username = :username", User.class) .setParameter("username", username); userQuery.setHint("org.hibernate.cacheable", true); List<User> users = userQuery.getResultList(); return users.isEmpty() ? null : users.get(0); } /** * ? ( ?? {@link org.cherchgk.domain.security.User} * ? ? . * * @param email ?? ? . * @return null, ? ? ? * ? . */ public User getUserByEmail(String email) { TypedQuery<User> userQuery = entityManager .createQuery("select user " + "from User user " + "where user.email = :email", User.class) .setParameter("email", email.trim().toLowerCase()); userQuery.setHint("org.hibernate.cacheable", true); List<User> users = userQuery.getResultList(); return users.isEmpty() ? null : users.get(0); } /** * ? ( ?? {@link org.cherchgk.domain.security.User}) * . * * @param userId ?. * @return null, ? ? * . */ public User getUserById(Long userId) { TypedQuery<User> userQuery = entityManager .createQuery("select user " + "from User user " + "where user.id = :userId", User.class) .setParameter("userId", userId); userQuery.setHint("org.hibernate.cacheable", true); List<User> users = userQuery.getResultList(); return users.isEmpty() ? null : users.get(0); } /** * ?? ? ? ?? . * * @return ? ? ? ?? . */ public List<User> getAllUsers() { TypedQuery<User> usersQuery = entityManager .createQuery("select user " + "from User user " + "order by user.username", User.class); usersQuery.setHint("org.hibernate.cacheable", true); return usersQuery.getResultList(); } }