View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.client.enduser.pages;
20  
21  import org.apache.syncope.client.enduser.SyncopeEnduserSession;
22  import org.apache.syncope.client.enduser.SyncopeWebApplication;
23  import org.apache.syncope.client.enduser.commons.EnduserConstants;
24  import org.apache.syncope.client.enduser.panels.captcha.CaptchaPanel;
25  import org.apache.syncope.client.enduser.rest.SecurityQuestionRestClient;
26  import org.apache.syncope.client.enduser.rest.UserSelfRestClient;
27  import org.apache.syncope.client.ui.commons.Constants;
28  import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
29  import org.apache.syncope.client.ui.commons.panels.CardPanel;
30  import org.apache.syncope.common.lib.SyncopeClientException;
31  import org.apache.syncope.common.lib.to.SecurityQuestionTO;
32  import org.apache.wicket.PageReference;
33  import org.apache.wicket.ajax.AjaxRequestTarget;
34  import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
35  import org.apache.wicket.ajax.markup.html.AjaxLink;
36  import org.apache.wicket.ajax.markup.html.form.AjaxButton;
37  import org.apache.wicket.markup.html.WebMarkupContainer;
38  import org.apache.wicket.markup.html.basic.Label;
39  import org.apache.wicket.markup.html.form.Button;
40  import org.apache.wicket.markup.html.form.Form;
41  import org.apache.wicket.markup.html.form.TextField;
42  import org.apache.wicket.markup.html.panel.Panel;
43  import org.apache.wicket.model.Model;
44  import org.apache.wicket.model.PropertyModel;
45  import org.apache.wicket.model.ResourceModel;
46  import org.apache.wicket.request.mapper.parameter.PageParameters;
47  import org.apache.wicket.spring.injection.annot.SpringBean;
48  
49  public class SelfPasswordReset extends BasePage {
50  
51      private static final long serialVersionUID = 164651008547631054L;
52  
53      protected static final String SELF_PWD_RESET = "page.selfPwdReset";
54  
55      @SpringBean
56      protected UserSelfRestClient userSelfRestClient;
57  
58      @SpringBean
59      protected SecurityQuestionRestClient securityQuestionRestClient;
60  
61      protected String usernameValue;
62  
63      protected String securityAnswerValue;
64  
65      protected final CaptchaPanel<Void> captcha;
66  
67      protected final SelfPwdResetPanel pwdResetPanel;
68  
69      public SelfPasswordReset(final PageParameters parameters) {
70          super(parameters, SELF_PWD_RESET);
71  
72          setDomain(parameters);
73          disableSidebar();
74  
75          captcha = new CaptchaPanel<>("captchaPanel");
76          captcha.setOutputMarkupPlaceholderTag(true);
77          captcha.setVisible(SyncopeWebApplication.get().isCaptchaEnabled());
78  
79          WebMarkupContainer content = new WebMarkupContainer("content");
80          content.setOutputMarkupId(true);
81          contentWrapper.add(content);
82  
83          Form<?> form = new Form<>("selfPwdResetForm");
84          content.add(form);
85  
86          pwdResetPanel = new SelfPwdResetPanel(EnduserConstants.CONTENT_PANEL, captcha, getPageReference());
87          pwdResetPanel.setOutputMarkupId(true);
88  
89          form.add(new CardPanel.Builder<SelfPwdResetPanel>()
90                  .setName("selfPasswordResetPanel")
91                  .setComponent(pwdResetPanel)
92                  .isVisible(true)
93                  .build("selfPasswordResetPanelCard"));
94  
95          AjaxButton submitButton = new AjaxButton("submit") {
96  
97              private static final long serialVersionUID = 4284361595033427185L;
98  
99              @Override
100             protected void onSubmit(final AjaxRequestTarget target) {
101                 if (SyncopeWebApplication.get().isCaptchaEnabled() && !captcha.check()) {
102                     SyncopeEnduserSession.get().error(getString(Constants.CAPTCHA_ERROR));
103                     SelfPasswordReset.this.getNotificationPanel().refresh(target);
104                 } else {
105                     PageParameters parameters = new PageParameters();
106                     try {
107                         userSelfRestClient.requestPasswordReset(usernameValue, securityAnswerValue);
108                         parameters.add(EnduserConstants.STATUS, Constants.OPERATION_SUCCEEDED);
109                         parameters.add(Constants.NOTIFICATION_TITLE_PARAM, getString("self.pwd.reset.success"));
110                         parameters.add(Constants.NOTIFICATION_MSG_PARAM, getString("self.pwd.reset.success.msg"));
111                         parameters.add(EnduserConstants.LANDING_PAGE, Login.class.getName());
112                         setResponsePage(SelfResult.class, parameters);
113                     } catch (SyncopeClientException sce) {
114                         LOG.error("Unable to reset password of [{}]", usernameValue, sce);
115                         SyncopeEnduserSession.get().onException(sce);
116                         SelfPasswordReset.this.getNotificationPanel().refresh(target);
117                     }
118                 }
119             }
120 
121         };
122         submitButton.setOutputMarkupId(true);
123         submitButton.setDefaultFormProcessing(false);
124         form.add(submitButton);
125 
126         Button cancel = new Button("cancel") {
127 
128             private static final long serialVersionUID = 3669569969172391336L;
129 
130             @Override
131             public void onSubmit() {
132                 setResponsePage(getApplication().getHomePage());
133             }
134 
135         };
136         cancel.setOutputMarkupId(true);
137         cancel.setDefaultFormProcessing(false);
138         form.add(cancel);
139     }
140 
141     public class SelfPwdResetPanel extends Panel {
142 
143         private static final long serialVersionUID = -2841210052053545578L;
144 
145         private final TextField<String> securityQuestion;
146 
147         SelfPwdResetPanel(final String id, final CaptchaPanel<Void> captcha, final PageReference pageRef) {
148             super(id);
149 
150             boolean isSecurityQuestionEnabled =
151                     SyncopeEnduserSession.get().getPlatformInfo().isPwdResetRequiringSecurityQuestions();
152 
153             TextField<String> username = new TextField<>("username",
154                     new PropertyModel<>(SelfPasswordReset.this, "usernameValue"), String.class);
155             username.add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_BLUR) {
156 
157                 private static final long serialVersionUID = -1107858522700306810L;
158 
159                 @Override
160                 protected void onUpdate(final AjaxRequestTarget target) {
161                     if (isSecurityQuestionEnabled) {
162                         loadSecurityQuestion(pageRef, target);
163                     }
164                 }
165             });
166             username.setRequired(true);
167             add(username);
168 
169             Label sqLabel =
170                     new Label("securityQuestionLabel", new ResourceModel("securityQuestion", "securityQuestion"));
171             sqLabel.setOutputMarkupPlaceholderTag(true);
172             sqLabel.setVisible(isSecurityQuestionEnabled);
173             add(sqLabel);
174 
175             securityQuestion =
176                     new TextField<>("securityQuestion", new PropertyModel<>(Model.of(), "content"), String.class);
177             securityQuestion.setOutputMarkupId(true);
178             securityQuestion.setEnabled(false);
179             securityQuestion.setOutputMarkupPlaceholderTag(true);
180             securityQuestion.setVisible(isSecurityQuestionEnabled);
181             add(securityQuestion);
182 
183             Label notLoading = new Label("not.loading", new ResourceModel("not.loading", "not.loading"));
184             notLoading.setOutputMarkupPlaceholderTag(true);
185             notLoading.setVisible(isSecurityQuestionEnabled);
186             add(notLoading);
187 
188             AjaxLink<Void> reloadLink = new AjaxLink<>("reloadLink") {
189 
190                 private static final long serialVersionUID = -817438685948164787L;
191 
192                 @Override
193                 public void onClick(final AjaxRequestTarget target) {
194                     loadSecurityQuestion(pageRef, target);
195                 }
196             };
197             reloadLink.setOutputMarkupPlaceholderTag(true);
198             reloadLink.setVisible(isSecurityQuestionEnabled);
199             add(reloadLink);
200 
201             Label saLabel = new Label("securityAnswerLabel", new ResourceModel("securityAnswer", "securityAnswer"));
202             saLabel.setOutputMarkupPlaceholderTag(true);
203             saLabel.setVisible(isSecurityQuestionEnabled);
204             add(saLabel);
205 
206             TextField<String> securityAnswer =
207                     new TextField<>("securityAnswer", new PropertyModel<>(SelfPasswordReset.this,
208                             "securityAnswerValue"), String.class);
209             securityAnswer.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
210 
211                 private static final long serialVersionUID = -1107858522700306810L;
212 
213                 @Override
214                 protected void onUpdate(final AjaxRequestTarget target) {
215                     // do nothing
216                 }
217             });
218             securityAnswer.setRequired(isSecurityQuestionEnabled);
219             securityAnswer.setOutputMarkupPlaceholderTag(true);
220             securityAnswer.setVisible(isSecurityQuestionEnabled);
221             add(securityAnswer);
222 
223             add(captcha);
224         }
225 
226         protected void loadSecurityQuestion(final PageReference pageRef, final AjaxRequestTarget target) {
227             try {
228                 SecurityQuestionTO securityQuestionTO = securityQuestionRestClient.readByUser(usernameValue);
229                 // set security question field model
230                 securityQuestion.setModel(Model.of(securityQuestionTO.getContent()));
231                 target.add(securityQuestion);
232             } catch (Exception e) {
233                 LOG.error("Unable to get security question for [{}]", usernameValue, e);
234                 SyncopeEnduserSession.get().onException(e);
235                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
236             }
237         }
238     }
239 }