/* * KBAccess - Collaborative database of accessibility examples * Copyright (C) 2012-2016 Open-S Company * * This file is part of KBAccess. * * KBAccess is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Contact us by mail: open-s AT open-s DOT com */ package org.opens.kbaccess.controller; import java.util.Collection; import java.util.Iterator; import java.util.Set; import java.util.TreeSet; import org.apache.commons.logging.LogFactory; import org.opens.kbaccess.command.AccountCommand; import org.opens.kbaccess.command.ChangePasswordCommand; import org.opens.kbaccess.command.NewPasswordCommand; import org.opens.kbaccess.controller.utils.AController; import org.opens.kbaccess.entity.authorization.Account; import org.opens.kbaccess.entity.service.statistics.StatisticsDataService; import org.opens.kbaccess.entity.service.subject.WebarchiveDataService; import org.opens.kbaccess.entity.statistics.AccountStatistics; import org.opens.kbaccess.keystore.MessageKeyStore; import org.opens.kbaccess.keystore.ModelAttributeKeyStore; import org.opens.kbaccess.presentation.AccountPresentation; import org.opens.kbaccess.presentation.factory.AccountPresentationFactory; import org.opens.kbaccess.presentation.factory.TestcasePresentationFactory; import org.opens.kbaccess.presentation.factory.WebarchivePresentationFactory; import org.opens.kbaccess.utils.AccountUtils; import org.opens.kbaccess.utils.TgolTokenHelper; import org.opens.kbaccess.validator.AccountDetailsValidator; import org.opens.kbaccess.validator.ChangePasswordValidator; import org.opens.kbaccess.validator.NewPasswordValidator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; /** * * @author bcareil */ @Controller @RequestMapping("/account/") public class AccountController extends AController { @Autowired private WebarchiveDataService webarchiveDataService; @Autowired private StatisticsDataService statisticsDataService; @Autowired private AccountPresentationFactory accountPresentationFactory; @Autowired private TestcasePresentationFactory testcasePresentationFactory; @Autowired private WebarchivePresentationFactory webarchivePresentationFactory; /* * Private methods */ private String displayNewPasswordForm(Model model, NewPasswordCommand newPasswordCommand) { // Breadcrumb handleBreadcrumbTrail(model); model.addAttribute("newPasswordCommand", newPasswordCommand); return "account/new-password"; } /* * account details handler */ @RequestMapping(value="my-account", method=RequestMethod.GET) public String myAccountHandler( Model model ) { AccountPresentation accountPresentation; Account currentUser; AccountCommand accountCommand; // handle login form handleUserLoginForm(model); currentUser = AccountUtils.getInstance().getCurrentUser(); if (currentUser == null) { return "home"; } accountPresentation = accountPresentationFactory.create(currentUser); // Add edit settings form accountCommand = new AccountCommand(currentUser); model.addAttribute("accountCommand", accountCommand); handleBreadcrumbTrail(model); // Account details and testcases model.addAttribute("account", accountPresentation); model.addAttribute( ModelAttributeKeyStore.TESTCASE_LIST_KEY, testcasePresentationFactory.createFromCollection( testcaseDataService.getLastTestcasesFromAccount(currentUser, 5) ) ); return "account/my-account"; } @RequestMapping(value="my-account", method=RequestMethod.POST) public String myAccountHandler( @ModelAttribute("accountCommand") AccountCommand accountCommand, BindingResult result, Model model ) { Account currentUser = AccountUtils.getInstance().getCurrentUser(); AccountPresentation accountPresentation; // check authority (spring security should avoid that this test passed) if (currentUser == null) { LogFactory.getLog(AccountController.class).error("An unauthentified user reached /account/details, check spring security configuration"); return "guest/login"; } // Handle login and breadcrumb handleUserLoginForm(model); handleBreadcrumbTrail(model); // validate new account details AccountDetailsValidator accountDetailsValidator = new AccountDetailsValidator(accountDataService, currentUser.getEmail()); accountDetailsValidator.validate(accountCommand, result); model.addAttribute("accountCommand", accountCommand); if (result.hasErrors()) { accountPresentation = accountPresentationFactory.create(currentUser); model.addAttribute("account", accountPresentation); return "account/my-account"; } // update account accountCommand.updateAccount(currentUser); accountDataService.update(currentUser); accountPresentation = accountPresentationFactory.create(currentUser); handleUserLoginForm(model); model.addAttribute("account", accountPresentation); model.addAttribute( ModelAttributeKeyStore.TESTCASE_LIST_KEY, testcasePresentationFactory.createFromCollection( testcaseDataService.getLastTestcasesFromAccount(currentUser, 5) ) ); model.addAttribute("successMessage", MessageKeyStore.ACCOUNT_EDITED); return "account/my-account"; } @RequestMapping(value="details/{id}/*", method=RequestMethod.GET) public String detailsHandler( @PathVariable("id") Long id, Model model ) { AccountPresentation accountPresentation; Account requestedUser; // handle login form handleUserLoginForm(model); // fetch the requested account and check it exists requestedUser = accountDataService.read(id); if (requestedUser == null) { return "home"; } accountPresentation = accountPresentationFactory.create(requestedUser); handleBreadcrumbTrail(model); model.addAttribute("account", accountPresentation); model.addAttribute( ModelAttributeKeyStore.TESTCASE_LIST_KEY, testcasePresentationFactory.createFromCollection( testcaseDataService.getLastTestcasesFromAccount(requestedUser, 5) ) ); return "account/details"; } /* * other handlers */ @RequestMapping("my-webarchives") public String myWebarchivesHandler(Model model) { Account currentUser; // handleUserLoginForm(model); handleBreadcrumbTrail(model); // currentUser = AccountUtils.getInstance().getCurrentUser(); if (currentUser == null) { LogFactory.getLog(AccountController.class).error("An unauthentified user reached account/my-webpages, check spring security configuration"); return "guest/login"; } model.addAttribute(ModelAttributeKeyStore.WEBARCHIVE_LIST_KEY, webarchivePresentationFactory.createFromCollection( webarchiveDataService.getAllFromUserAccount(currentUser) ) ); return "account/my-webarchives"; } @RequestMapping("my-examples") public String myTestcasesHanlder(Model model) { Account currentUser; // handleUserLoginForm(model); handleBreadcrumbTrail(model); // currentUser = AccountUtils.getInstance().getCurrentUser(); if (currentUser == null) { LogFactory.getLog(AccountController.class).error("An unauthentified user reached account/my-testcases, check spring security configuration"); return "guest/login"; } // model.addAttribute( ModelAttributeKeyStore.TESTCASE_LIST_KEY, testcasePresentationFactory.createFromCollection( testcaseDataService.getAllFromAccount(currentUser) ) ); return "account/my-examples"; } @RequestMapping(value="change-password", method=RequestMethod.GET) public String changePasswordHandler(Model model) { ChangePasswordCommand changePasswordCommand; Account currentUser; // handleUserLoginForm(model); handleBreadcrumbTrail(model); // currentUser = AccountUtils.getInstance().getCurrentUser(); if (currentUser == null) { LogFactory.getLog(AccountController.class).error("An unauthentified user reached account/change-password, check spring security configuration"); return "guest/login"; } changePasswordCommand = new ChangePasswordCommand(); model.addAttribute("changePasswordCommand", changePasswordCommand); return "account/change-password"; } @RequestMapping(value="change-password", method=RequestMethod.POST) public String changePasswordHandler( @ModelAttribute("changePasswordCommand") ChangePasswordCommand changePasswordCommand, BindingResult result, Model model ) { Account currentUser = AccountUtils.getInstance().getCurrentUser(); // handleUserLoginForm(model); handleBreadcrumbTrail(model); if (currentUser == null) { LogFactory.getLog(AccountController.class).error("An unauthentified user reached account/change-password, check spring security configuration"); return "guest/login"; } // validate new account details ChangePasswordValidator changePasswordValidator = new ChangePasswordValidator(accountDataService, currentUser.getEmail()); changePasswordValidator.validate(changePasswordCommand, result); model.addAttribute("changePasswordCommand", changePasswordCommand); if (result.hasErrors()) { return "account/change-password"; } changePasswordCommand.updateAccount(currentUser); accountDataService.update(currentUser); handleUserLoginForm(model); model.addAttribute("successMessage", MessageKeyStore.PASSWORD_CHANGED); return "account/change-password"; } @RequestMapping(value="new-password", method=RequestMethod.GET) public String newPasswordHandler( Model model, @RequestParam(value="token", required=true) String token ) { NewPasswordCommand newPasswordCommand; LogFactory.getLog(AccountController.class).info("token : " + token); if (!AccountUtils.getInstance().isTokenValid(token)) { return "guest/login"; } // Users will potentially ask for a new password if they're trying to access their non-activated account // In this case we need to activate the user String requestedUserEmail = TgolTokenHelper.getInstance().getUserEmailFromToken(token); Account requestedUser = accountDataService.getAccountFromEmail(requestedUserEmail); if (requestedUser != null) { if (!requestedUser.isActivated()) { requestedUser.setActivated(true); requestedUser.setAuthCode(null); accountDataService.saveOrUpdate(requestedUser); } } // New password form newPasswordCommand = new NewPasswordCommand(); newPasswordCommand.setToken(token); return displayNewPasswordForm(model, newPasswordCommand); } @RequestMapping(value="new-password", method=RequestMethod.POST) public String newPasswordHandler( @ModelAttribute("newPasswordCommand") NewPasswordCommand newPasswordCommand, BindingResult result, Model model ) { String token = newPasswordCommand.getToken(); TgolTokenHelper tokenHelper = TgolTokenHelper.getInstance(); if (!AccountUtils.getInstance().isTokenValid(token)) { return "guest/login"; } NewPasswordValidator newPasswordValidator = new NewPasswordValidator(accountDataService, null); newPasswordValidator.validate(newPasswordCommand, result); if (result.hasErrors()) { return displayNewPasswordForm(model, newPasswordCommand); } // Update account's password String requestedUserEmail = tokenHelper.getUserEmailFromToken(token); Account requestedUser = accountDataService.getAccountFromEmail(requestedUserEmail); // Set the token as used requestedUser.setAuthCode(null); // Update account newPasswordCommand.updateAccount(requestedUser); accountDataService.update(requestedUser); model.addAttribute("successMessage", MessageKeyStore.PASSWORD_CHANGED); return displayNewPasswordForm(model, newPasswordCommand); } @RequestMapping(value="list", method=RequestMethod.GET) public String accountListHandler( Model model ) { Collection<AccountStatistics> contributorsStatistics; Set<AccountPresentation> contributors = new TreeSet<AccountPresentation>(); handleUserLoginForm(model); handleBreadcrumbTrail(model); // fetch contributors contributorsStatistics = statisticsDataService.getAccountOrderByTestcaseCount(false, 0); // Generate a displayable name for most active contributors for (Iterator it = contributorsStatistics.iterator(); it.hasNext();) { AccountStatistics accountStatistics = (AccountStatistics) it.next(); Account account = accountDataService.read(accountStatistics.getId()); contributors.add(accountPresentationFactory.create(account)); } model.addAttribute("contributors", contributors); return "account/list"; } /* * Accessors */ public WebarchiveDataService getWebarchiveDataService() { return webarchiveDataService; } public void setWebarchiveDataService(WebarchiveDataService webarchiveDataService) { this.webarchiveDataService = webarchiveDataService; } public StatisticsDataService getStatisticsDataService() { return statisticsDataService; } public void setStatisticsDataService(StatisticsDataService statisticsDataService) { this.statisticsDataService = statisticsDataService; } public AccountPresentationFactory getAccountPresentationFactory() { return accountPresentationFactory; } public void setAccountPresentationFactory(AccountPresentationFactory accountPresentationFactory) { this.accountPresentationFactory = accountPresentationFactory; } public TestcasePresentationFactory getTestcasePresentationFactory() { return testcasePresentationFactory; } public void setTestcasePresentationFactory(TestcasePresentationFactory testcasePresentationFactory) { this.testcasePresentationFactory = testcasePresentationFactory; } public WebarchivePresentationFactory getWebarchivePresentationFactory() { return webarchivePresentationFactory; } public void setWebarchivePresentationFactory(WebarchivePresentationFactory webarchivePresentationFactory) { this.webarchivePresentationFactory = webarchivePresentationFactory; } }