2008-03-13 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / PasswordRecovery.cs
1 //
2 // System.Web.UI.WebControls.PasswordRecovery.cs
3 //
4 // Authors:
5 //      Vladimir Krasnov (vladimirk@mainsoft.com)
6 //
7 // (C) 2006 Mainsoft, Inc (http://www.mainsoft.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 #if NET_2_0
30
31 using System;
32 using System.Net.Mail;
33 using System.Collections;
34 using System.Collections.Specialized;
35 using System.ComponentModel;
36 using System.Drawing.Design;
37 using System.Web;
38 using System.Web.UI;
39 using System.Web.Security;
40
41 namespace System.Web.UI.WebControls
42 {
43         [Bindable (false)]
44         public class PasswordRecovery : CompositeControl
45         {
46                 public static readonly string SubmitButtonCommandName = "Submit";
47
48                 TableItemStyle _failureTextStyle;
49                 TableItemStyle _hyperLinkStyle;
50                 TableItemStyle _instructionTextStyle;
51                 TableItemStyle _labelStyle;
52                 Style _submitButtonStyle;
53                 TableItemStyle _successTextStyle;
54                 Style _textBoxStyle;
55                 TableItemStyle _titleTextStyle;
56                 Style _validatorTextStyle;
57
58                 MailDefinition _mailDefinition;
59                 MembershipProvider _provider = null;
60
61                 ITemplate _questionTemplate = null;
62                 ITemplate _successTemplate = null;
63                 ITemplate _userNameTemplate = null;
64
65                 QuestionContainer _questionTemplateContainer = null;
66                 SuccessContainer _successTemplateContainer = null;
67                 UserNameContainer _userNameTemplateContainer = null;
68
69                 PasswordReciveryStep _currentStep = PasswordReciveryStep.StepUserName;
70
71                 string _username = null;
72                 string _answer = null;
73
74                 public PasswordRecovery ()
75                 {
76                 }
77
78                 [Themeable (false)]
79                 public virtual string Answer
80                 {
81                         get { return _answer != null ? _answer : string.Empty; }
82                 }
83
84                 [Localizable (true)]
85                 public virtual string AnswerLabelText
86                 {
87                         get { return ViewState.GetString ("AnswerLabelText", "Answer:"); }
88                         set { ViewState ["AnswerLabelText"] = value; }
89                 }
90
91                 [Localizable (true)]
92                 public virtual string AnswerRequiredErrorMessage
93                 {
94                         get { return ViewState.GetString ("AnswerRequiredErrorMessage", "Answer is required."); }
95                         set { ViewState ["AnswerRequiredErrorMessage"] = value; }
96                 }
97
98                 public virtual int BorderPadding
99                 {
100                         get { return ViewState.GetInt ("BorderPadding", 1); }
101                         set
102                         {
103                                 if (value < -1)
104                                         throw new ArgumentOutOfRangeException ();
105                                 ViewState ["BorderPadding"] = value;
106                         }
107                 }
108
109                 [Localizable (true)]
110                 public virtual string GeneralFailureText
111                 {
112                         get { return ViewState.GetString ("GeneralFailureText", "Your attempt to retrieve your password was not successful. Please try again."); }
113                         set { ViewState ["GeneralFailureText"] = value; }
114                 }
115
116                 public virtual string HelpPageIconUrl
117                 {
118                         get { return ViewState.GetString ("HelpPageIconUrl", String.Empty); }
119                         set { ViewState ["HelpPageIconUrl"] = value; }
120                 }
121
122                 [Localizable (true)]
123                 public virtual string HelpPageText
124                 {
125                         get { return ViewState.GetString ("HelpPageText", String.Empty); }
126                         set { ViewState ["HelpPageText"] = value; }
127                 }
128
129                 public virtual string HelpPageUrl
130                 {
131                         get { return ViewState.GetString ("HelpPageUrl", String.Empty); }
132                         set { ViewState ["HelpPageUrl"] = value; }
133                 }
134
135                 [Themeable (false)]
136                 public MailDefinition MailDefinition
137                 {
138                         get
139                         {
140                                 if (_mailDefinition == null) {
141                                         _mailDefinition = new MailDefinition ();
142                                         if (IsTrackingViewState)
143                                                 ((IStateManager) _mailDefinition).TrackViewState ();
144                                 }
145                                 return _mailDefinition;
146                         }
147                 }
148
149                 [Themeable (false)]
150                 public virtual string MembershipProvider
151                 {
152                         get { return ViewState.GetString ("MembershipProvider", String.Empty); }
153                         set { ViewState ["MembershipProvider"] = value; }
154                 }
155
156                 [Themeable (false)]
157                 public virtual string Question
158                 {
159                         get { return ViewState.GetString ("Question", ""); }
160                         private set { ViewState ["Question"] = value; }
161                 }
162
163                 [Localizable (true)]
164                 public virtual string QuestionFailureText
165                 {
166                         get { return ViewState.GetString ("QuestionFailureText", "Your answer could not be verified. Please try again."); }
167                         set { ViewState ["QuestionFailureText"] = value; }
168                 }
169
170                 [Localizable (true)]
171                 public virtual string QuestionInstructionText
172                 {
173                         get { return ViewState.GetString ("QuestionInstructionText", "Answer the following question to receive your password."); }
174                         set { ViewState ["QuestionInstructionText"] = value; }
175                 }
176
177                 [Localizable (true)]
178                 public virtual string QuestionLabelText
179                 {
180                         get { return ViewState.GetString ("QuestionLabelText", "Question:"); }
181                         set { ViewState ["QuestionLabelText"] = value; }
182                 }
183
184                 [Localizable (true)]
185                 public virtual string QuestionTitleText
186                 {
187                         get { return ViewState.GetString ("QuestionTitleText", "Identity Confirmation"); }
188                         set { ViewState ["QuestionTitleText"] = value; }
189                 }
190
191                 public virtual string SubmitButtonImageUrl
192                 {
193                         get { return ViewState.GetString ("SubmitButtonImageUrl", String.Empty); }
194                         set { ViewState ["SubmitButtonImageUrl"] = value; }
195                 }
196
197                 [Localizable (true)]
198                 public virtual string SubmitButtonText
199                 {
200                         get { return ViewState.GetString ("SubmitButtonText", "Submit"); }
201                         set { ViewState ["SubmitButtonText"] = value; }
202                 }
203
204                 public virtual ButtonType SubmitButtonType
205                 {
206                         get
207                         {
208                                 object o = ViewState ["SubmitButtonType"];
209                                 return (o == null) ? ButtonType.Button : (ButtonType) o;
210                         }
211                         set
212                         {
213                                 if ((value < ButtonType.Button) || (value > ButtonType.Link))
214                                         throw new ArgumentOutOfRangeException ("SubmitButtonType");
215                                 ViewState ["SubmitButtonType"] = (int) value;
216                         }
217                 }
218
219                 [Themeable (false)]
220                 public virtual string SuccessPageUrl
221                 {
222                         get { return ViewState.GetString ("SuccessPageUrl", String.Empty); }
223                         set { ViewState ["SuccessPageUrl"] = value; }
224                 }
225
226                 [Localizable (true)]
227                 public virtual string SuccessText
228                 {
229                         get { return ViewState.GetString ("SuccessText", "Your password has been sent to you."); }
230                         set { ViewState ["SuccessText"] = value; }
231                 }
232
233                 public virtual LoginTextLayout TextLayout
234                 {
235                         get
236                         {
237                                 object o = ViewState ["TextLayout"];
238                                 return (o == null) ? LoginTextLayout.TextOnLeft : (LoginTextLayout) o;
239                         }
240                         set
241                         {
242                                 if ((value < LoginTextLayout.TextOnLeft) || (value > LoginTextLayout.TextOnTop))
243                                         throw new ArgumentOutOfRangeException ("TextLayout");
244                                 ViewState ["TextLayout"] = (int) value;
245                         }
246                 }
247
248                 [Localizable (true)]
249                 public virtual string UserName
250                 {
251                         get { return _username != null ? _username : ""; }
252                         set { _username = value; }
253                 }
254
255                 [Localizable (true)]
256                 public virtual string UserNameFailureText
257                 {
258                         get { return ViewState.GetString ("UserNameFailureText", "We were unable to access your information. Please try again."); }
259                         set { ViewState ["UserNameFailureText"] = value; }
260                 }
261
262                 [Localizable (true)]
263                 public virtual string UserNameInstructionText
264                 {
265                         get { return ViewState.GetString ("UserNameInstructionText", "Enter your User Name to receive your password."); }
266                         set { ViewState ["UserNameInstructionText"] = value; }
267                 }
268
269                 [Localizable (true)]
270                 public virtual string UserNameLabelText
271                 {
272                         get { return ViewState.GetString ("UserNameLabelText", "User Name:"); }
273                         set { ViewState ["UserNameLabelText"] = value; }
274                 }
275
276                 [Localizable (true)]
277                 public virtual string UserNameRequiredErrorMessage
278                 {
279                         get { return ViewState.GetString ("UserNameRequiredErrorMessage", "User Name is required."); }
280                         set { ViewState ["UserNameRequiredErrorMessage"] = value; }
281                 }
282
283                 [Localizable (true)]
284                 public virtual string UserNameTitleText
285                 {
286                         get { return ViewState.GetString ("UserNameTitleText", "Forgot Your Password?"); }
287                         set { ViewState ["UserNameTitleText"] = value; }
288                 }
289
290                 [TemplateContainer (typeof (PasswordRecovery))]
291                 public virtual ITemplate QuestionTemplate
292                 {
293                         get { return _questionTemplate; }
294                         set { _questionTemplate = value; }
295                 }
296
297                 public Control QuestionTemplateContainer
298                 {
299                         get
300                         {
301                                 if (_questionTemplateContainer == null)
302                                         _questionTemplateContainer = new QuestionContainer (this);
303                                 return _questionTemplateContainer;
304                         }
305                 }
306
307                 [TemplateContainer (typeof (PasswordRecovery))]
308                 public virtual ITemplate SuccessTemplate
309                 {
310                         get { return _successTemplate; }
311                         set { _successTemplate = value; }
312                 }
313
314                 public Control SuccessTemplateContainer
315                 {
316                         get
317                         {
318                                 if (_successTemplateContainer == null)
319                                         _successTemplateContainer = new SuccessContainer (this);
320                                 return _successTemplateContainer;
321                         }
322                 }
323
324                 [TemplateContainer (typeof (PasswordRecovery))]
325                 public virtual ITemplate UserNameTemplate
326                 {
327                         get { return _userNameTemplate; }
328                         set { _userNameTemplate = value; }
329                 }
330
331                 public Control UserNameTemplateContainer
332                 {
333                         get
334                         {
335                                 if (_userNameTemplateContainer == null)
336                                         _userNameTemplateContainer = new UserNameContainer (this);
337                                 return _userNameTemplateContainer;
338                         }
339                 }
340
341                 public TableItemStyle FailureTextStyle
342                 {
343                         get
344                         {
345                                 if (_failureTextStyle == null) {
346                                         _failureTextStyle = new TableItemStyle ();
347                                         if (IsTrackingViewState)
348                                                 _failureTextStyle.TrackViewState ();
349                                 }
350                                 return _failureTextStyle;
351                         }
352                 }
353
354                 public TableItemStyle HyperLinkStyle
355                 {
356                         get
357                         {
358                                 if (_hyperLinkStyle == null) {
359                                         _hyperLinkStyle = new TableItemStyle ();
360                                         if (IsTrackingViewState)
361                                                 _hyperLinkStyle.TrackViewState ();
362                                 }
363                                 return _hyperLinkStyle;
364                         }
365                 }
366
367                 public TableItemStyle InstructionTextStyle
368                 {
369                         get
370                         {
371                                 if (_instructionTextStyle == null) {
372                                         _instructionTextStyle = new TableItemStyle ();
373                                         if (IsTrackingViewState)
374                                                 _instructionTextStyle.TrackViewState ();
375                                 }
376                                 return _instructionTextStyle;
377                         }
378                 }
379
380                 public TableItemStyle LabelStyle
381                 {
382                         get
383                         {
384                                 if (_labelStyle == null) {
385                                         _labelStyle = new TableItemStyle ();
386                                         if (IsTrackingViewState)
387                                                 _labelStyle.TrackViewState ();
388                                 }
389                                 return _labelStyle;
390                         }
391                 }
392
393                 public Style SubmitButtonStyle
394                 {
395                         get
396                         {
397                                 if (_submitButtonStyle == null) {
398                                         _submitButtonStyle = new TableItemStyle ();
399                                         if (IsTrackingViewState)
400                                                 _submitButtonStyle.TrackViewState ();
401                                 }
402                                 return _submitButtonStyle;
403                         }
404                 }
405
406                 public TableItemStyle SuccessTextStyle
407                 {
408                         get
409                         {
410                                 if (_successTextStyle == null) {
411                                         _successTextStyle = new TableItemStyle ();
412                                         if (IsTrackingViewState)
413                                                 _successTextStyle.TrackViewState ();
414                                 }
415                                 return _successTextStyle;
416                         }
417                 }
418
419                 public Style TextBoxStyle
420                 {
421                         get
422                         {
423                                 if (_textBoxStyle == null) {
424                                         _textBoxStyle = new TableItemStyle ();
425                                         if (IsTrackingViewState)
426                                                 _textBoxStyle.TrackViewState ();
427                                 }
428                                 return _textBoxStyle;
429                         }
430                 }
431
432                 public TableItemStyle TitleTextStyle
433                 {
434                         get
435                         {
436                                 if (_titleTextStyle == null) {
437                                         _titleTextStyle = new TableItemStyle ();
438                                         if (IsTrackingViewState)
439                                                 _titleTextStyle.TrackViewState ();
440                                 }
441                                 return _titleTextStyle;
442                         }
443                 }
444
445                 public Style ValidatorTextStyle
446                 {
447                         get
448                         {
449                                 if (_validatorTextStyle == null) {
450                                         _validatorTextStyle = new TableItemStyle ();
451                                         if (IsTrackingViewState)
452                                                 _validatorTextStyle.TrackViewState ();
453                                 }
454                                 return _validatorTextStyle;
455                         }
456                 }
457
458                 #region Protected Properties
459
460                 protected override HtmlTextWriterTag TagKey
461                 {
462                         get { return HtmlTextWriterTag.Table; }
463                 }
464
465                 internal virtual MembershipProvider MembershipProviderInternal
466                 {
467                         get
468                         {
469                                 if (_provider == null)
470                                         InitMemberShipProvider ();
471
472                                 return _provider;
473                         }
474                 }
475
476                 #endregion
477
478                 #region Events
479
480                 public event EventHandler AnswerLookupError;
481                 public event MailMessageEventHandler SendingMail;
482                 public event SendMailErrorEventHandler SendMailError;
483                 public event EventHandler UserLookupError;
484                 public event LoginCancelEventHandler VerifyingAnswer;
485                 public event LoginCancelEventHandler VerifyingUser;
486
487                 #endregion
488
489                 protected internal override void CreateChildControls ()
490                 {
491                         ITemplate userNameTemplate = UserNameTemplate;
492                         if (userNameTemplate == null)
493                                 userNameTemplate = new UserNameDefaultTemplate (this);
494                         ((UserNameContainer) UserNameTemplateContainer).InstantiateTemplate (userNameTemplate);
495
496                         ITemplate questionTemplate = QuestionTemplate;
497                         if (questionTemplate == null)
498                                 questionTemplate = new QuestionDefaultTemplate (this);
499                         ((QuestionContainer) QuestionTemplateContainer).InstantiateTemplate (questionTemplate);
500
501                         ITemplate successTemplate = SuccessTemplate;
502                         if (successTemplate == null)
503                                 successTemplate = new SuccessDefaultTemplate (this);
504                         ((SuccessContainer) SuccessTemplateContainer).InstantiateTemplate (successTemplate);
505
506                         Controls.AddAt (0, UserNameTemplateContainer);
507                         Controls.AddAt (1, QuestionTemplateContainer);
508                         Controls.AddAt (2, SuccessTemplateContainer);
509
510                         IEditableTextControl editable;
511
512                         editable = ((UserNameContainer) UserNameTemplateContainer).UserNameTextBox;
513                         if (editable != null)
514                                 editable.TextChanged += new EventHandler (UserName_TextChanged);
515
516                         editable = ((QuestionContainer) QuestionTemplateContainer).AnswerTextBox;
517                         if (editable != null)
518                                 editable.TextChanged += new EventHandler (Answer_TextChanged);
519                 }
520
521                 #region Protected methods
522
523                 protected internal override void Render (HtmlTextWriter writer)
524                 {
525                         ((QuestionContainer) QuestionTemplateContainer).UpdateChildControls ();
526
527                         for (int i = 0; i < Controls.Count; i++)
528                                 if (Controls [i].Visible)
529                                         Controls [i].Render (writer);
530                 }
531
532                 protected internal override void LoadControlState (object savedState)
533                 {
534                         if (savedState == null) return;
535                         object [] state = (object []) savedState;
536                         base.LoadControlState (state [0]);
537
538                         _currentStep = (PasswordReciveryStep) state [1];
539                         _username = (string) state [2];
540                 }
541
542                 protected internal override object SaveControlState ()
543                 {
544                         object state = base.SaveControlState ();
545                         return new object [] { state, _currentStep, _username };
546                 }
547
548                 protected override void TrackViewState ()
549                 {
550                         base.TrackViewState ();
551
552                         if (_failureTextStyle != null)
553                                 _failureTextStyle.TrackViewState ();
554
555                         if (_hyperLinkStyle != null)
556                                 _hyperLinkStyle.TrackViewState ();
557
558                         if (_instructionTextStyle != null)
559                                 _instructionTextStyle.TrackViewState ();
560
561                         if (_labelStyle != null)
562                                 _labelStyle.TrackViewState ();
563
564                         if (_submitButtonStyle != null)
565                                 _submitButtonStyle.TrackViewState ();
566
567                         if (_successTextStyle != null)
568                                 _successTextStyle.TrackViewState ();
569
570                         if (_textBoxStyle != null)
571                                 _textBoxStyle.TrackViewState ();
572
573                         if (_titleTextStyle != null)
574                                 _titleTextStyle.TrackViewState ();
575
576                         if (_validatorTextStyle != null)
577                                 _validatorTextStyle.TrackViewState ();
578
579                         if (_mailDefinition != null)
580                                 ((IStateManager) _mailDefinition).TrackViewState ();
581                 }
582
583                 protected override void LoadViewState (object savedState)
584                 {
585                         if (savedState == null)
586                                 return;
587
588                         object [] states = (object []) savedState;
589                         base.LoadViewState (states [0]);
590
591                         if (states [1] != null)
592                                 FailureTextStyle.LoadViewState (states [1]);
593
594                         if (states [2] != null)
595                                 HyperLinkStyle.LoadViewState (states [2]);
596
597                         if (states [3] != null)
598                                 InstructionTextStyle.LoadViewState (states [3]);
599
600                         if (states [4] != null)
601                                 LabelStyle.LoadViewState (states [4]);
602
603                         if (states [5] != null)
604                                 SubmitButtonStyle.LoadViewState (states [5]);
605
606                         if (states [6] != null)
607                                 SuccessTextStyle.LoadViewState (states [6]);
608
609                         if (states [7] != null)
610                                 TextBoxStyle.LoadViewState (states [7]);
611
612                         if (states [8] != null)
613                                 TitleTextStyle.LoadViewState (states [8]);
614
615                         if (states [9] != null)
616                                 ValidatorTextStyle.LoadViewState (states [9]);
617
618                         if (states [10] != null)
619                                 ((IStateManager) MailDefinition).LoadViewState (states [10]);
620                 }
621
622                 protected override object SaveViewState ()
623                 {
624                         object [] states = new object [11];
625                         states [0] = base.SaveViewState ();
626
627                         if (_failureTextStyle != null)
628                                 states [1] = _failureTextStyle.SaveViewState ();
629
630                         if (_hyperLinkStyle != null)
631                                 states [2] = _hyperLinkStyle.SaveViewState ();
632
633                         if (_instructionTextStyle != null)
634                                 states [3] = _instructionTextStyle.SaveViewState ();
635
636                         if (_labelStyle != null)
637                                 states [4] = _labelStyle.SaveViewState ();
638
639                         if (_submitButtonStyle != null)
640                                 states [5] = _submitButtonStyle.SaveViewState ();
641
642                         if (_successTextStyle != null)
643                                 states [6] = _successTextStyle.SaveViewState ();
644
645                         if (_textBoxStyle != null)
646                                 states [7] = _textBoxStyle.SaveViewState ();
647
648                         if (_titleTextStyle != null)
649                                 states [8] = _titleTextStyle.SaveViewState ();
650
651                         if (_validatorTextStyle != null)
652                                 states [9] = _validatorTextStyle.SaveViewState ();
653
654                         if (_mailDefinition != null)
655                                 states [10] = ((IStateManager) _mailDefinition).SaveViewState ();
656
657                         for (int i = 0; i < states.Length; i++) {
658                                 if (states [i] != null)
659                                         return states;
660                         }
661                         return null;
662
663                 }
664
665                 #endregion
666
667                 void ProcessCommand (CommandEventArgs args)
668                 {
669                         if (!Page.IsValid)
670                                 return;
671
672                         switch (_currentStep) {
673                                 case PasswordReciveryStep.StepUserName:
674                                         ProcessUserName ();
675                                         break;
676                                 case PasswordReciveryStep.StepAnswer:
677                                         ProcessUserAnswer ();
678                                         break;
679                         }
680
681                 }
682
683                 void ProcessUserName ()
684                 {
685                         LoginCancelEventArgs args = new LoginCancelEventArgs ();
686                         OnVerifyingUser (args);
687                         if (args.Cancel)
688                                 return;
689
690                         MembershipUser user = MembershipProviderInternal.GetUser (UserName, false);
691                         if (user == null) {
692                                 OnUserLookupError (EventArgs.Empty);
693                                 ((UserNameContainer) UserNameTemplateContainer).FailureTextLiteral.Text = UserNameFailureText;
694                                 return;
695                         }
696                         
697                         Question = user.PasswordQuestion;
698                         _currentStep = PasswordReciveryStep.StepAnswer;
699                         return;
700                 }
701
702                 private void ProcessUserAnswer ()
703                 {
704                         LoginCancelEventArgs args = new LoginCancelEventArgs ();
705                         OnVerifyingAnswer (args);
706                         if (args.Cancel)
707                                 return;
708
709                         MembershipUser user = MembershipProviderInternal.GetUser (UserName, false);
710                         if (user == null || string.IsNullOrEmpty (user.Email)) {
711                                 ((QuestionContainer) QuestionTemplateContainer).FailureTextLiteral.Text = GeneralFailureText;
712                                 return;
713                         }
714
715                         string newPassword = "";
716                         try {
717                                 if (MembershipProviderInternal.EnablePasswordRetrieval) {
718                                         newPassword = MembershipProviderInternal.GetPassword (UserName, Answer);
719                                 }
720                                 else if (MembershipProviderInternal.EnablePasswordReset) {
721                                         newPassword = MembershipProviderInternal.ResetPassword (UserName, Answer);
722                                 }
723                                 else
724                                         throw new HttpException ("Membership provider does not support password retrieval or reset.");
725                         }
726                         catch (MembershipPasswordException) {
727                                 OnAnswerLookupError (EventArgs.Empty);
728                                 ((QuestionContainer) QuestionTemplateContainer).FailureTextLiteral.Text = QuestionFailureText;
729                                 return;
730                         }
731
732                         SendPasswordByMail (UserName, newPassword);
733
734                         _currentStep = PasswordReciveryStep.StepSuccess;
735                         return;
736                 }
737
738                 private void InitMemberShipProvider ()
739                 {
740                         string mp = MembershipProvider;
741                         _provider = (mp.Length == 0) ? _provider = Membership.Provider : Membership.Providers [mp];
742                         if (_provider == null)
743                                 throw new HttpException (Locale.GetText ("No provider named '{0}' could be found.", mp));
744                 }
745
746                 private void SendPasswordByMail (string username, string password)
747                 {
748                         MembershipUser user = MembershipProviderInternal.GetUser (UserName, false);
749                         if (user == null)
750                                 return;
751
752                         string messageText = "Please return to the site and log in using the following information.\n" +
753                                 "User Name: <%USERNAME%>\nPassword: <%PASSWORD%>";
754
755                         ListDictionary dictionary = new ListDictionary ();
756                         dictionary.Add ("<%USERNAME%>", username);
757                         dictionary.Add ("<%PASSWORD%>", password);
758
759                         MailMessage message = null;
760                         
761                         if (MailDefinition.BodyFileName.Length == 0)
762                                 message = MailDefinition.CreateMailMessage (user.Email, dictionary, messageText, this);
763                         else
764                                 message = MailDefinition.CreateMailMessage (user.Email, dictionary, this);
765
766                         if (string.IsNullOrEmpty (message.Subject))
767                                 message.Subject = "Password";
768
769                         MailMessageEventArgs args = new MailMessageEventArgs (message);
770                         OnSendingMail (args);
771
772                         SmtpClient smtpClient = new SmtpClient ();
773                         try {
774                                 smtpClient.Send (message);
775                         }
776                         catch (Exception e) {
777                                 SendMailErrorEventArgs mailArgs = new SendMailErrorEventArgs (e);
778                                 OnSendMailError (mailArgs);
779                                 if (!mailArgs.Handled)
780                                         throw e;
781                         }
782                 }
783
784                 #region Event handlers
785
786                 protected virtual void OnAnswerLookupError (EventArgs e)
787                 {
788                 }
789
790                 protected override bool OnBubbleEvent (object source, EventArgs e)
791                 {
792                         CommandEventArgs args = e as CommandEventArgs;
793                         if (e != null && args.CommandName == SubmitButtonCommandName) {
794                                 ProcessCommand (args);
795                                 return true;
796                         }
797                         return base.OnBubbleEvent (source, e);
798                 }
799
800                 protected internal override void OnInit (EventArgs e)
801                 {
802                         Page.RegisterRequiresControlState (this);
803                         base.OnInit (e);
804                 }
805
806                 protected internal override void OnPreRender (EventArgs e)
807                 {
808                         UserNameTemplateContainer.Visible = false;
809                         QuestionTemplateContainer.Visible = false;
810                         SuccessTemplateContainer.Visible = false;
811
812                         switch (_currentStep) {
813                                 case PasswordReciveryStep.StepUserName:
814                                         UserNameTemplateContainer.Visible = true;
815                                         break;
816                                 case PasswordReciveryStep.StepAnswer:
817                                         QuestionTemplateContainer.Visible = true;
818                                         break;
819                                 case PasswordReciveryStep.StepSuccess:
820                                         SuccessTemplateContainer.Visible = true;
821                                         break;
822                         }
823
824                         base.OnPreRender (e);
825                 }
826
827                 protected virtual void OnSendingMail (MailMessageEventArgs e)
828                 {
829                         if (SendingMail != null)
830                                 SendingMail (this, e);
831                 }
832
833                 protected virtual void OnSendMailError (SendMailErrorEventArgs e)
834                 {
835                         if (SendMailError != null)
836                                 SendMailError (this, e);
837                 }
838
839                 protected virtual void OnUserLookupError (EventArgs e)
840                 {
841                         if (UserLookupError != null)
842                                 UserLookupError (this, e);
843                 }
844
845                 protected virtual void OnVerifyingAnswer (LoginCancelEventArgs e)
846                 {
847                         if (VerifyingAnswer != null)
848                                 VerifyingAnswer (this, e);
849                 }
850
851                 protected virtual void OnVerifyingUser (LoginCancelEventArgs e)
852                 {
853                         if (VerifyingUser != null)
854                                 VerifyingUser (this, e);
855                 }
856
857                 #endregion
858
859                 #region Private Event Handlers
860
861                 private void UserName_TextChanged (object sender, EventArgs e)
862                 {
863                         UserName = ((ITextControl) sender).Text;
864                 }
865
866                 private void Answer_TextChanged (object sender, EventArgs e)
867                 {
868                         _answer = ((ITextControl) sender).Text;
869                 }
870
871                 #endregion
872
873                 [MonoTODO ("Not implemented")]
874                 protected override void SetDesignModeState (IDictionary data)
875                 {
876                         throw new NotImplementedException ();
877                 }
878
879
880                 abstract class BasePasswordRecoveryContainer : Table, INamingContainer
881                 {
882                         protected readonly PasswordRecovery _owner = null;
883                         TableCell _containerCell = null;
884
885                         public BasePasswordRecoveryContainer (PasswordRecovery owner)
886                         {
887                                 _owner = owner;
888                                 InitTable ();
889                         }
890
891                         public void InstantiateTemplate (ITemplate template)
892                         {
893                                 template.InstantiateIn (_containerCell);
894                         }
895
896                         private void InitTable ()
897                         {
898                                 Attributes.Add ("ID", _owner.ID);
899
900                                 CellSpacing = 0;
901                                 CellPadding = _owner.BorderPadding;
902
903                                 _containerCell = new TableCell ();
904
905                                 TableRow row = new TableRow ();
906                                 row.Cells.Add (_containerCell);
907                                 Rows.Add (row);
908                         }
909
910                         protected internal override void OnPreRender (EventArgs e)
911                         {
912                                 ApplyStyle (_owner.ControlStyle);
913                                 base.OnPreRender (e);
914                         }
915
916                         public abstract void UpdateChildControls();
917                 }
918
919
920                 sealed class QuestionContainer : BasePasswordRecoveryContainer
921                 {
922                         public QuestionContainer (PasswordRecovery owner)
923                                 : base (owner)
924                         {
925                         }
926                         // Requried controls
927                         public IEditableTextControl AnswerTextBox
928                         {
929                                 get
930                                 {
931                                         Control c = FindControl ("Answer");
932                                         if (c == null)
933                                                 throw new HttpException ("QuestionTemplate does not contain an IEditableTextControl with ID Answer for the username.");
934                                         return c as IEditableTextControl;
935                                 }
936                         }
937                         // Optional controls
938                         public Literal UserNameLiteral
939                         {
940                                 get { return FindControl ("UserName") as Literal; }
941                         }
942                         public Literal QuestionLiteral
943                         {
944                                 get { return FindControl ("Question") as Literal; }
945                         }
946                         public Literal FailureTextLiteral
947                         {
948                                 get { return FindControl ("FailureText") as Literal; }
949                         }
950
951                         public override void UpdateChildControls ()
952                         {
953                                 if (UserNameLiteral != null)
954                                         UserNameLiteral.Text = _owner.UserName;
955
956                                 if (QuestionLiteral != null)
957                                         QuestionLiteral.Text = _owner.Question;
958                         }
959                 }
960
961                 sealed class SuccessContainer : BasePasswordRecoveryContainer
962                 {
963                         public SuccessContainer (PasswordRecovery owner)
964                                 : base (owner)
965                         {
966                         }
967
968                         public override void UpdateChildControls ()
969                         {
970                         }
971                 }
972
973                 sealed class UserNameContainer : BasePasswordRecoveryContainer
974                 {
975                         public UserNameContainer (PasswordRecovery owner)
976                                 : base (owner)
977                         {
978                         }
979                         // Requried controls
980                         public IEditableTextControl UserNameTextBox
981                         {
982                                 get
983                                 {
984                                         Control c = FindControl ("UserName");
985                                         if (c == null)
986                                                 throw new HttpException ("UserNameTemplate does not contain an IEditableTextControl with ID UserName for the username.");
987                                         return c as IEditableTextControl;
988                                 }
989                         }
990                         // Optional controls
991                         public ITextControl FailureTextLiteral
992                         {
993                                 get { return FindControl ("FailureText") as ITextControl; }
994                         }
995
996                         public override void UpdateChildControls ()
997                         {
998                         }
999                 }
1000
1001                 class TemplateUtils
1002                 {
1003                         public static TableRow CreateRow(Control c1, Control c2, Style s1, Style s2, bool twoCells)
1004                         {
1005                                 TableRow row = new TableRow ();
1006                                 TableCell cell1 = new TableCell ();
1007
1008                                 cell1.Controls.Add (c1);
1009                                 if (s1 != null)
1010                                         cell1.ApplyStyle (s1);
1011
1012                                 row.Cells.Add (cell1);
1013
1014                                 if (c2 != null) {
1015                                         TableCell cell2 = new TableCell ();
1016                                         cell2.Controls.Add (c2);
1017
1018                                         if (s2 != null)
1019                                                 cell2.ApplyStyle (s2);
1020
1021                                         row.Cells.Add (cell2);
1022
1023                                         cell1.HorizontalAlign = HorizontalAlign.Right;
1024                                         cell2.HorizontalAlign = HorizontalAlign.Left;
1025                                 }
1026                                 else {
1027                                         cell1.HorizontalAlign = HorizontalAlign.Center;
1028                                         if (twoCells)
1029                                                 cell1.ColumnSpan = 2;
1030                                 }
1031                                 
1032                                 return row;
1033                         }
1034
1035                         public static TableRow CreateHelpRow (string pageUrl, string linkText, string linkIcon, Style linkStyle, bool twoCells)
1036                         {
1037                                 TableRow row = new TableRow ();
1038                                 TableCell cell1 = new TableCell ();
1039
1040                                 if (linkIcon.Length > 0) {
1041                                         Image img = new Image ();
1042                                         img.ImageUrl = linkIcon;
1043                                         cell1.Controls.Add (img);
1044                                 }
1045                                 if (linkText.Length > 0) {
1046                                         HyperLink link = new HyperLink ();
1047                                         link.NavigateUrl = pageUrl;
1048                                         link.Text = linkText;
1049                                         link.ControlStyle.CopyTextStylesFrom (linkStyle);
1050                                         cell1.Controls.Add (link);
1051                                 }
1052
1053                                 if (twoCells)
1054                                         cell1.ColumnSpan = 2;
1055
1056                                 row.ControlStyle.CopyFrom (linkStyle);
1057                                 row.Cells.Add (cell1);
1058                                 return row;
1059                         }
1060                 }
1061
1062                 sealed class UserNameDefaultTemplate : ITemplate
1063                 {
1064                         readonly PasswordRecovery _owner = null;
1065
1066                         public UserNameDefaultTemplate (PasswordRecovery _owner)
1067                         {
1068                                 this._owner = _owner;
1069                         }
1070
1071                         public void InstantiateIn (Control container)
1072                         {
1073                                 Table table = new Table ();
1074                                 table.CellPadding = 0;
1075
1076                                 bool twoCells = _owner.TextLayout == LoginTextLayout.TextOnLeft;
1077
1078                                 // row 0
1079                                 table.Rows.Add (
1080                                         TemplateUtils.CreateRow (new LiteralControl (_owner.UserNameTitleText), null, _owner.TitleTextStyle, null, twoCells));
1081
1082                                 // row 1
1083                                 table.Rows.Add (
1084                                         TemplateUtils.CreateRow (new LiteralControl (_owner.UserNameInstructionText), null, _owner.InstructionTextStyle, null, twoCells));
1085
1086                                 // row 2
1087                                 TextBox UserNameTextBox = new TextBox ();
1088                                 UserNameTextBox.ID = "UserName";
1089                                 UserNameTextBox.Text = _owner.UserName;
1090                                 UserNameTextBox.ApplyStyle (_owner.TextBoxStyle);
1091
1092                                 Label UserNameLabel = new Label ();
1093                                 UserNameLabel.ID = "UserNameLabel";
1094                                 UserNameLabel.AssociatedControlID = "UserName";
1095                                 UserNameLabel.Text = _owner.UserNameLabelText;
1096                                 UserNameLabel.ApplyStyle (_owner.LabelStyle);
1097
1098                                 RequiredFieldValidator UserNameRequired = new RequiredFieldValidator ();
1099                                 UserNameRequired.ID = "UserNameRequired";
1100                                 UserNameRequired.ControlToValidate = "UserName";
1101                                 UserNameRequired.ErrorMessage = _owner.UserNameRequiredErrorMessage;
1102                                 UserNameRequired.ToolTip = _owner.UserNameRequiredErrorMessage;
1103                                 UserNameRequired.Text = "*";
1104                                 UserNameRequired.ValidationGroup = _owner.ID;
1105                                 UserNameRequired.ApplyStyle (_owner.ValidatorTextStyle);
1106
1107                                 if (twoCells) {
1108                                         TableRow row = TemplateUtils.CreateRow (UserNameLabel, UserNameTextBox, null, null, twoCells);
1109                                         row.Cells [1].Controls.Add (UserNameRequired);
1110                                         table.Rows.Add (row);
1111                                 }
1112                                 else {
1113                                         table.Rows.Add (TemplateUtils.CreateRow (UserNameLabel, null, null, null, twoCells));
1114                                         TableRow row = TemplateUtils.CreateRow (UserNameTextBox, null, null, null, twoCells);
1115                                         row.Cells [0].Controls.Add (UserNameRequired);
1116                                         table.Rows.Add (row);
1117                                 }
1118
1119                                 // row 3
1120                                 Literal FailureText = new Literal ();
1121                                 FailureText.ID = "FailureText";
1122                                 if (_owner.FailureTextStyle.ForeColor.IsEmpty)
1123                                         _owner.FailureTextStyle.ForeColor = System.Drawing.Color.Red;
1124                                 table.Rows.Add (TemplateUtils.CreateRow (FailureText, null, _owner.FailureTextStyle, null, twoCells));
1125
1126                                 // row 4
1127                                 WebControl SubmitButton = null;
1128                                 switch (_owner.SubmitButtonType) {
1129                                         case ButtonType.Button:
1130                                                 SubmitButton = new Button ();
1131                                                 break;
1132                                         case ButtonType.Image:
1133                                                 SubmitButton = new ImageButton ();
1134                                                 break;
1135                                         case ButtonType.Link:
1136                                                 SubmitButton = new LinkButton ();
1137                                                 break;
1138                                 }
1139
1140                                 SubmitButton.ID = "SubmitButton";
1141                                 SubmitButton.ApplyStyle (_owner.SubmitButtonStyle);
1142                                 ((IButtonControl) SubmitButton).CommandName = PasswordRecovery.SubmitButtonCommandName;
1143                                 ((IButtonControl) SubmitButton).Text = _owner.SubmitButtonText;
1144                                 ((IButtonControl) SubmitButton).ValidationGroup = _owner.ID;
1145
1146                                 TableRow buttonRow = TemplateUtils.CreateRow (SubmitButton, null, null, null, twoCells);
1147                                 buttonRow.Cells [0].HorizontalAlign = HorizontalAlign.Right;
1148                                 table.Rows.Add (buttonRow);
1149
1150                                 // row 5
1151                                 table.Rows.Add (
1152                                         TemplateUtils.CreateHelpRow (
1153                                         _owner.HelpPageUrl, _owner.HelpPageText, _owner.HelpPageIconUrl, _owner.HyperLinkStyle, twoCells));
1154
1155                                 container.Controls.Add (table);
1156                         }
1157                 }
1158
1159                 sealed class QuestionDefaultTemplate : ITemplate
1160                 {
1161                         readonly PasswordRecovery _owner = null;
1162
1163                         public QuestionDefaultTemplate (PasswordRecovery _owner)
1164                         {
1165                                 this._owner = _owner;
1166                         }
1167
1168                         public void InstantiateIn (Control container)
1169                         {
1170                                 Table table = new Table ();
1171                                 table.CellPadding = 0;
1172
1173                                 bool twoCells = _owner.TextLayout == LoginTextLayout.TextOnLeft;
1174
1175                                 // row 0
1176                                 table.Rows.Add (
1177                                         TemplateUtils.CreateRow (new LiteralControl (_owner.QuestionTitleText), null, _owner.TitleTextStyle, null, twoCells));
1178
1179                                 // row 1
1180                                 table.Rows.Add (
1181                                         TemplateUtils.CreateRow (new LiteralControl (_owner.QuestionInstructionText), null, _owner.InstructionTextStyle, null, twoCells));
1182
1183                                 // row 2
1184                                 Literal UserNameLiteral = new Literal ();
1185                                 UserNameLiteral.ID = "UserName";
1186
1187                                 table.Rows.Add (
1188                                         TemplateUtils.CreateRow (new LiteralControl (_owner.UserNameLabelText), UserNameLiteral, _owner.LabelStyle, _owner.LabelStyle, twoCells));
1189
1190                                 // row 3
1191                                 Literal QuestionLiteral = new Literal ();
1192                                 QuestionLiteral.ID = "Question";
1193
1194                                 table.Rows.Add (
1195                                         TemplateUtils.CreateRow (new LiteralControl (_owner.QuestionLabelText), QuestionLiteral, _owner.LabelStyle, _owner.LabelStyle, twoCells));
1196
1197                                 // row 5
1198                                 TextBox AnswerTextBox = new TextBox ();
1199                                 AnswerTextBox.ID = "Answer";
1200                                 AnswerTextBox.ApplyStyle (_owner.TextBoxStyle);
1201
1202                                 Label AnswerLabel = new Label ();
1203                                 AnswerLabel.ID = "AnswerLabel";
1204                                 AnswerLabel.AssociatedControlID = "Answer";
1205                                 AnswerLabel.Text = _owner.AnswerLabelText;
1206                                 AnswerLabel.ApplyStyle (_owner.LabelStyle);
1207
1208                                 RequiredFieldValidator AnswerRequired = new RequiredFieldValidator ();
1209                                 AnswerRequired.ID = "AnswerRequired";
1210                                 AnswerRequired.ControlToValidate = "Answer";
1211                                 AnswerRequired.ErrorMessage = _owner.AnswerRequiredErrorMessage;
1212                                 AnswerRequired.ToolTip = _owner.AnswerRequiredErrorMessage;
1213                                 AnswerRequired.Text = "*";
1214                                 AnswerRequired.ValidationGroup = _owner.ID;
1215                                 AnswerRequired.ApplyStyle (_owner.ValidatorTextStyle);
1216
1217                                 if (twoCells) {
1218                                         TableRow row = TemplateUtils.CreateRow (AnswerLabel, AnswerTextBox, null, null, twoCells);
1219                                         row.Cells [1].Controls.Add (AnswerRequired);
1220                                         table.Rows.Add (row);
1221                                 }
1222                                 else {
1223                                         table.Rows.Add (TemplateUtils.CreateRow (AnswerLabel, null, null, null, twoCells));
1224                                         TableRow row = TemplateUtils.CreateRow (AnswerTextBox, null, null, null, twoCells);
1225                                         row.Cells [0].Controls.Add (AnswerRequired);
1226                                         table.Rows.Add (row);
1227                                 }
1228
1229                                 // row 6
1230                                 Literal FailureText = new Literal ();
1231                                 FailureText.ID = "FailureText";
1232                                 if (_owner.FailureTextStyle.ForeColor.IsEmpty)
1233                                         _owner.FailureTextStyle.ForeColor = System.Drawing.Color.Red;
1234                                 table.Rows.Add (TemplateUtils.CreateRow (FailureText, null, _owner.FailureTextStyle, null, twoCells));
1235
1236                                 // row 7
1237                                 WebControl SubmitButton = null;
1238                                 switch (_owner.SubmitButtonType) {
1239                                         case ButtonType.Button:
1240                                                 SubmitButton = new Button ();
1241                                                 break;
1242                                         case ButtonType.Image:
1243                                                 SubmitButton = new ImageButton ();
1244                                                 break;
1245                                         case ButtonType.Link:
1246                                                 SubmitButton = new LinkButton ();
1247                                                 break;
1248                                 }
1249
1250                                 SubmitButton.ID = "SubmitButton";
1251                                 SubmitButton.ApplyStyle (_owner.SubmitButtonStyle);
1252                                 ((IButtonControl) SubmitButton).CommandName = PasswordRecovery.SubmitButtonCommandName;
1253                                 ((IButtonControl) SubmitButton).Text = _owner.SubmitButtonText;
1254                                 ((IButtonControl) SubmitButton).ValidationGroup = _owner.ID;
1255
1256                                 TableRow buttonRow = TemplateUtils.CreateRow (SubmitButton, null, null, null, twoCells);
1257                                 buttonRow.Cells [0].HorizontalAlign = HorizontalAlign.Right;
1258                                 table.Rows.Add (buttonRow);
1259
1260                                 // row 8
1261                                 table.Rows.Add (
1262                                         TemplateUtils.CreateHelpRow (
1263                                         _owner.HelpPageUrl, _owner.HelpPageText, _owner.HelpPageIconUrl, _owner.HyperLinkStyle, twoCells));
1264
1265                                 container.Controls.Add (table);
1266                         }
1267                 }
1268
1269                 sealed class SuccessDefaultTemplate : ITemplate
1270                 {
1271                         readonly PasswordRecovery _owner = null;
1272
1273                         public SuccessDefaultTemplate (PasswordRecovery _owner)
1274                         {
1275                                 this._owner = _owner;
1276                         }
1277
1278                         public void InstantiateIn (Control container)
1279                         {
1280                                 Table table = new Table ();
1281                                 table.CellPadding = 0;
1282
1283                                 bool twoCells = _owner.TextLayout == LoginTextLayout.TextOnLeft;
1284
1285                                 // row 0
1286                                 table.Rows.Add (
1287                                         TemplateUtils.CreateRow (new LiteralControl (_owner.SuccessText), null, _owner.SuccessTextStyle, null, twoCells));
1288
1289                                 container.Controls.Add (table);
1290                         }
1291                 }
1292
1293                 private enum PasswordReciveryStep
1294                 {
1295                         StepUserName,
1296                         StepAnswer,
1297                         StepSuccess,
1298                 }
1299         }
1300 }
1301
1302 #endif