35c21ece43e5ced8d228d9362d127c37c7771806
[cdm-vaadin.git] / src / main / java / eu / etaxonomy / cdm / vaadin / view / PasswordResetPresenter.java
1 /**
2 * Copyright (C) 2021 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9 package eu.etaxonomy.cdm.vaadin.view;
10
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.Optional;
14 import java.util.concurrent.CountDownLatch;
15 import java.util.concurrent.ExecutionException;
16 import java.util.concurrent.TimeUnit;
17
18 import org.springframework.beans.factory.annotation.Autowired;
19 import org.springframework.beans.factory.annotation.Qualifier;
20 import org.springframework.mail.MailException;
21 import org.springframework.util.concurrent.ListenableFuture;
22 import org.vaadin.spring.events.EventBus;
23 import org.vaadin.spring.events.annotation.EventBusListenerMethod;
24
25 import com.vaadin.spring.annotation.SpringComponent;
26 import com.vaadin.spring.annotation.ViewScope;
27
28 import eu.etaxonomy.cdm.api.application.ICdmRepository;
29 import eu.etaxonomy.cdm.api.security.IAbstractRequestTokenStore;
30 import eu.etaxonomy.cdm.api.security.PasswordResetRequest;
31 import eu.etaxonomy.cdm.api.service.security.AccountSelfManagementException;
32 import eu.etaxonomy.cdm.model.permission.User;
33 import eu.etaxonomy.cdm.vaadin.event.UserAccountEvent;
34 import eu.etaxonomy.vaadin.mvp.AbstractPresenter;
35
36 /**
37 * @author a.kohlbecker
38 * @since Nov 11, 2021
39 */
40 @SpringComponent
41 @ViewScope
42 public class PasswordResetPresenter extends AbstractPresenter<PasswordResetView> {
43
44 private static final long serialVersionUID = 2656148780493202130L;
45
46 @Autowired
47 @Qualifier("cdmRepository")
48 private ICdmRepository repo;
49
50 @Autowired
51 @Qualifier("passwordResetTokenStore")
52 private IAbstractRequestTokenStore<PasswordResetRequest, User> tokenStore;
53
54 protected EventBus.UIEventBus uiEventBus;
55
56 PasswordResetRequest resetRequest = null;
57
58 @Autowired
59 protected void setUIEventBus(EventBus.UIEventBus uiEventBus){
60 this.uiEventBus = uiEventBus;
61 uiEventBus.subscribe(this);
62 }
63
64 @Override
65 public void handleViewEntered() {
66
67 boolean debug = false;
68 if(debug) {
69 getView().setUserName("debug-user");
70 } else {
71 List<String> viewParameters = getNavigationManager().getCurrentViewParameters();
72 if(viewParameters.size() != 1 || !tokenStore.isEligibleToken(viewParameters.get(0))) {
73 // invalid token show error
74 getView().showErrorMessage("Invalid token");
75 }
76 Optional<PasswordResetRequest> resetRequestOpt = tokenStore.findRequest(viewParameters.get(0));
77 if(resetRequestOpt.isPresent()) {
78 resetRequest = resetRequestOpt.get();
79 getView().setUserName(resetRequest.getUserName());
80 }
81 }
82 }
83
84 @EventBusListenerMethod
85 public void onPasswordRevoveryEvent(UserAccountEvent event) throws AccountSelfManagementException, ExecutionException {
86
87 if(event.getAction().equals(UserAccountEvent.UserAccountAction.RESET_PASSWORD)) {
88 String newPassword = getView().getPassword1Field().getValue();
89
90 CountDownLatch passwordChangedSignal = new CountDownLatch(1);
91 List<Throwable> asyncException = new ArrayList<>(1);
92 ListenableFuture<Boolean> resetPasswordFuture = repo.getPasswordResetService().resetPassword(resetRequest.getToken(), newPassword);
93 resetPasswordFuture.addCallback(requestSuccessVal -> {
94 passwordChangedSignal.countDown();
95 }, futureException -> {
96 asyncException.add(futureException);
97 passwordChangedSignal.countDown();
98 });
99 // -- wait for passwordResetService.resetPassword to complete
100 boolean asyncTimeout = false;
101 Boolean result = false;
102 try {
103 passwordChangedSignal.await(2, TimeUnit.SECONDS);
104 result = resetPasswordFuture.get();
105 } catch (InterruptedException e) {
106 asyncTimeout = true;
107 }
108 if(!asyncException.isEmpty()) {
109 if(asyncException.get(0) instanceof MailException) {
110 getView().showSuccessMessage("Your password has been changed but sending the confirmation email has failed.");
111 } else if(asyncException.get(0) instanceof AccountSelfManagementException) {
112 getView().showErrorMessage("The password reset token has beceome invalid. Please request gain for a password reset.");
113 }
114 } else {
115 if(!asyncTimeout && result) {
116 getView().showSuccessMessage("Your password has been changed and a confirmation email has been sent to you.");
117 } else {
118 getView().showErrorMessage("A timeout has occured, please try again.");
119 }
120 }
121
122 }
123 }
124 }