/* * Copyright (c) JForum Team. All rights reserved. * * The software in this package is published under the terms of the LGPL * license a copy of which has been included with this distribution in the * license.txt file. * * The JForum Project * http://www.jforum.net */ package net.jforum.controllers; import java.util.ArrayList; import java.util.List; import javax.servlet.http.HttpServletRequest; import net.jforum.actions.helpers.Domain; import net.jforum.core.SecurityConstraint; import net.jforum.core.SessionManager; import net.jforum.entities.Avatar; import net.jforum.entities.AvatarType; import net.jforum.entities.Post; import net.jforum.entities.Ranking; import net.jforum.entities.Topic; import net.jforum.entities.User; import net.jforum.entities.UserSession; import net.jforum.entities.util.Pagination; import net.jforum.repository.RankingRepository; import net.jforum.repository.UserRepository; import net.jforum.security.EditUserRule; import net.jforum.security.RoleManager; import net.jforum.services.AvatarService; import net.jforum.services.LostPasswordService; import net.jforum.services.UserService; import net.jforum.util.ConfigKeys; import net.jforum.util.JForumConfig; import net.jforum.util.SecurityConstants; import org.apache.commons.lang.StringUtils; import br.com.caelum.vraptor.Path; import br.com.caelum.vraptor.Resource; import br.com.caelum.vraptor.Result; import br.com.caelum.vraptor.interceptor.multipart.UploadedFile; /** * @author Rafael Steil */ @Resource @Path(Domain.USER) public class UserController { private UserRepository userRepository; private UserService userService; private UserSession userSession; private SessionManager sessionManager; private LostPasswordService lostPasswordService; private JForumConfig config; private AvatarService avatarService; private RankingRepository rankingRepository; private final Result result; private final HttpServletRequest request; public UserController(UserRepository userRepository, UserSession userSession, UserService userService, SessionManager sessionFacade, JForumConfig config, LostPasswordService lostPasswordService, AvatarService avatarService, RankingRepository rankingRepository, Result result, HttpServletRequest request) { this.userRepository = userRepository; this.userService = userService; this.sessionManager = sessionFacade; this.userSession = userSession; this.config = config; this.lostPasswordService = lostPasswordService; this.avatarService = avatarService; this.rankingRepository = rankingRepository; this.result = result; this.request = request; } /** * Shows the page with all registered users * @param page the pagination first record to start showing */ public void list(int page) { RoleManager roleManager = this.userSession.getRoleManager(); if (!roleManager.isUserListingEnabled()) { this.result.include("users", new ArrayList<User>()); } else { Pagination pagination = new Pagination(this.config, page) .forUsers(this.userRepository.getTotalUsers()); if (roleManager.roleExists(SecurityConstants.INTERACT_OTHER_GROUPS)) { this.result.include("users", this.userRepository.getAllUsers(pagination.getStart(), pagination.getRecordsPerPage())); } else { User currentUser = this.userSession.getUser(); this.result.include("users", this.userRepository.getAllUsers(pagination.getStart(), pagination.getRecordsPerPage(), currentUser.getGroups())); } this.result.include("pagination", pagination); } } /** * Logout an authenticated user */ public void logout() { UserSession us = this.userSession; this.sessionManager.storeSession(us.getSessionId()); us.becomeAnonymous(this.config.getInt(ConfigKeys.ANONYMOUS_USER_ID)); this.sessionManager.remove(us.getSessionId()); this.sessionManager.add(us); this.removeAutoLoginCookies(us); this.result.redirectTo(ForumController.class).list(); } /** * Shows the form to log in */ public void login(String returnPath, boolean failed) { if (StringUtils.isEmpty(returnPath) && !this.config.getBoolean(ConfigKeys.LOGIN_IGNORE_REFERER)) { returnPath = this.request.getHeader("Referer"); } result.include("invalidLogin", failed); if (!StringUtils.isEmpty(returnPath)) { this.result.include("returnPath", returnPath); } } /** * Called from {@link #login(String)}, to validate the user credentials * * @param username the username * @param password the password * @param autoLogin autoLogin */ @br.com.caelum.vraptor.Post public void authenticateUser(String username, String password, boolean autoLogin, String returnPath) { User user = this.userService.validateLogin(username, password); if (user == null) { result.redirectTo(this).login(returnPath, true); } else { this.userSession.setUser(user); this.userSession.becomeLogged(); if (autoLogin) { this.activateAutoLogin(user); } else { this.removeAutoLoginCookies(this.userSession); } this.sessionManager.add(this.userSession); if (!StringUtils.isEmpty(returnPath)) { this.result.redirectTo(returnPath); } else { this.result.redirectTo(ForumController.class).list(); } } } /** * Shows the page to edit the user profile * @param userId the user id */ @SecurityConstraint(EditUserRule.class) @Path("/edit/{userId}") public void edit(int userId) { User userToEdit = this.userRepository.get(userId); this.result.include("user", userToEdit); this.result.include("rankings", this.rankingRepository.getAllRankings()); this.result.include("avatars", this.avatarService.getAvatarGallery()); } /** * Updates an existing user * @param user the user to update */ @SecurityConstraint(EditUserRule.class) public void editSave(User user, Integer avatarId, UploadedFile image, Integer rankingId) { Avatar avatar = null; if (avatarId != null){ avatar = new Avatar(); avatar.setId(avatarId); avatar.setAvatarType(AvatarType.AVATAR_GALLERY); } else if (image != null) { avatar = new Avatar(); avatar.setAvatarType(AvatarType.AVATAR_UPLOAD); this.avatarService.add(avatar, image); } user.setAvatar(avatar); if (rankingId == null) { user.setRanking(null); } else { Ranking ranking = new Ranking(); ranking.setId(rankingId); user.setRanking(ranking); } RoleManager roleManager = this.userSession.getRoleManager(); boolean canChangeUserName = roleManager.isAdministrator() || roleManager.isCoAdministrator(); boolean isSSOAuthentication = ConfigKeys.TYPE_SSO.equals(this.config.getValue(ConfigKeys.AUTHENTICATION_TYPE)); canChangeUserName = canChangeUserName && !isSSOAuthentication; this.userService.update(user, canChangeUserName); this.result.redirectTo(this).edit(user.getId()); } /** * Shows the page to create a new user */ //@InterceptedBy(ExternalUserManagementInterceptor.class) public void insert() { } /** * Adds a new user * @param user the user to add */ @br.com.caelum.vraptor.Post public void insertSave(User user) { boolean error = false; if (!error && user.getUsername().length() > this.config.getInt(ConfigKeys.USERNAME_MAX_LENGTH)) { this.result.include("error", "User.usernameTooBig"); error = true; } if (!error && user.getUsername().indexOf('<') > -1 || user.getUsername().indexOf('>') > -1) { this.result.include("error", "User.usernameInvalidChars"); error = true; } if (!error && !this.userRepository.isUsernameAvailable(user.getUsername(), user.getEmail())) { this.result.include("error", "User.usernameNotAvailable"); error = true; } if (error) { this.result.forwardTo(this).insert(); return; } this.userService.add(user); this.registerUserInSession(user); this.result.redirectTo(this).registrationCompleted(); } /** * Shows the profile of some user * @param userId the user to show */ @Path("/profile/{userId}") public void profile(int userId) { if (!this.userSession.getRoleManager().getCanViewProfile()) { this.result.redirectTo(MessageController.class).accessDenied(); } else { User userToEdit = this.userRepository.get(userId); this.result.include("user", userToEdit); this.result.include("userTotalTopics", this.userRepository.getTotalTopics(userId)); this.result.include("rankings", this.rankingRepository.getAllRankings()); this.result.include("isAnonymousUser", userId == this.config.getInt(ConfigKeys.ANONYMOUS_USER_ID)); boolean canEdit = userSession.getRoleManager().getCanEditUser(userToEdit, userSession.getUser().getGroups()); this.result.include("canEdit", canEdit); } } /** * Shows a nice message after a sucessful registration */ public void registrationCompleted() { if (!this.userSession.isLogged()) { this.result.redirectTo(this).insert(); } else { this.result.include("user", this.userSession.getUser()); } } public void lostPassword() { } public void lostPasswordSend(String username, String email) { boolean success = this.lostPasswordService.send(username, email); this.result.include("success", success); } /** * Shows the page asking the user a new password * @param hash the validation hash */ public void recoverPassword(String hash) { this.result.include("hash", hash); } /** * Validate the new password hash * @param hash the hash received by email * @param username the username associated with the hash * @param newPassword the new password to set */ public void recoverPasswordValidate(String hash, String username, String newPassword) { User user = this.userRepository.validateLostPasswordHash(username, hash); if (user == null) { this.result.include("error", true); this.result.include("message", "PasswordRecovery.invalidData"); } else { user.setPassword(newPassword); this.result.include("message", "PasswordRecovery.ok"); } } /** * Lists all the posts made by an user * @param userId the user id */ public void posts(int userId, int page) { User user = userRepository.get(userId); Pagination pagination = new Pagination(this.config, page).forUserPosts(user); List<Post> posts = userRepository.getPosts(user, pagination.getStart(), pagination.getRecordsPerPage()); this.result.include("pagination", pagination); this.result.include("posts", posts); this.result.include("user", user); } /** * Lists all the topics made by an user * @param userId the user id */ public void topics(int userId, int page) { User user = userRepository.get(userId); Pagination pagination = new Pagination(this.config, page).forUserTopics(user, userRepository.getTotalTopics(userId)); List<Topic> topics = userRepository.getTopics(user, pagination.getStart(), pagination.getRecordsPerPage()); this.result.include("pagination", pagination); this.result.include("topics", topics); this.result.include("user", user); } private void registerUserInSession(User user) { this.userSession.setUser(user); this.userSession.becomeLogged(); this.sessionManager.add(this.userSession); } private void removeAutoLoginCookies(UserSession us) { us.removeCookie(this.config.getValue(ConfigKeys.COOKIE_AUTO_LOGIN)); us.removeCookie(this.config.getValue(ConfigKeys.COOKIE_USER_HASH)); } private void activateAutoLogin(User user) { String securityHash = this.userService.generateAutoLoginSecurityHash(user.getId()); user.setSecurityHash(securityHash); String userHash = this.userService.generateAutoLoginUserHash(securityHash); this.userSession.addCookie(this.config.getValue(ConfigKeys.COOKIE_AUTO_LOGIN), "1"); this.userSession.addCookie(this.config.getValue(ConfigKeys.COOKIE_USER_HASH), userHash); this.userSession.addCookie(this.config.getValue(ConfigKeys.COOKIE_USER_ID), Integer.toString(user.getId())); } }