1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
|
namespace OpenIdProviderMvc.Controllers {
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Security.Principal;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Web.UI;
using OpenIdProviderMvc.Code;
[HandleError]
public class AccountController : Controller {
/// <summary>
/// Initializes a new instance of the <see cref="AccountController"/> class.
/// </summary>
/// <remarks>
/// This constructor is used by the MVC framework to instantiate the controller using
/// the default forms authentication and membership providers.
/// </remarks>
public AccountController()
: this(null, null) {
}
/// <summary>
/// Initializes a new instance of the <see cref="AccountController"/> class.
/// </summary>
/// <param name="formsAuth">The forms authentication service.</param>
/// <param name="service">The membership service.</param>
/// <remarks>
/// This constructor is not used by the MVC framework but is instead provided for ease
/// of unit testing this type. See the comments at the end of this file for more
/// information.
/// </remarks>
public AccountController(IFormsAuthentication formsAuth, IMembershipService service) {
this.FormsAuth = formsAuth ?? new FormsAuthenticationService();
this.MembershipService = service ?? new AccountMembershipService();
}
public IFormsAuthentication FormsAuth { get; private set; }
public IMembershipService MembershipService { get; private set; }
public ActionResult LogOn() {
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
[SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", Justification = "Needs to take same parameter type as Controller.Redirect()")]
public ActionResult LogOn(string userName, string password, bool rememberMe, string returnUrl) {
if (!this.ValidateLogOn(userName, password)) {
return View();
}
this.FormsAuth.SignIn(userName, rememberMe);
if (!string.IsNullOrEmpty(returnUrl)) {
return Redirect(returnUrl);
} else {
return RedirectToAction("Index", "Home");
}
}
public ActionResult LogOff() {
this.FormsAuth.SignOut();
return RedirectToAction("Index", "Home");
}
public ActionResult Register() {
ViewData["PasswordLength"] = this.MembershipService.MinPasswordLength;
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Register(string userName, string email, string password, string confirmPassword) {
this.ViewData["PasswordLength"] = this.MembershipService.MinPasswordLength;
if (this.ValidateRegistration(userName, email, password, confirmPassword)) {
// Attempt to register the user
MembershipCreateStatus createStatus = this.MembershipService.CreateUser(userName, password, email);
if (createStatus == MembershipCreateStatus.Success) {
this.FormsAuth.SignIn(userName, false /* createPersistentCookie */);
return RedirectToAction("Index", "Home");
} else {
ModelState.AddModelError("_FORM", ErrorCodeToString(createStatus));
}
}
// If we got this far, something failed, redisplay form
return View();
}
[Authorize]
public ActionResult ChangePassword() {
ViewData["PasswordLength"] = this.MembershipService.MinPasswordLength;
return View();
}
[Authorize]
[AcceptVerbs(HttpVerbs.Post)]
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Exceptions result in password not being changed.")]
public ActionResult ChangePassword(string currentPassword, string newPassword, string confirmPassword) {
ViewData["PasswordLength"] = this.MembershipService.MinPasswordLength;
if (!this.ValidateChangePassword(currentPassword, newPassword, confirmPassword)) {
return View();
}
try {
if (this.MembershipService.ChangePassword(User.Identity.Name, currentPassword, newPassword)) {
return RedirectToAction("ChangePasswordSuccess");
} else {
ModelState.AddModelError("_FORM", "The current password is incorrect or the new password is invalid.");
return View();
}
} catch {
ModelState.AddModelError("_FORM", "The current password is incorrect or the new password is invalid.");
return View();
}
}
public ActionResult ChangePasswordSuccess() {
return View();
}
protected override void OnActionExecuting(ActionExecutingContext filterContext) {
if (filterContext.HttpContext.User.Identity is WindowsIdentity) {
throw new InvalidOperationException("Windows authentication is not supported.");
}
}
#region Validation Methods
private static string ErrorCodeToString(MembershipCreateStatus createStatus) {
// See http://msdn.microsoft.com/en-us/library/system.web.security.membershipcreatestatus.aspx for
// a full list of status codes.
switch (createStatus) {
case MembershipCreateStatus.DuplicateUserName:
return "Username already exists. Please enter a different user name.";
case MembershipCreateStatus.DuplicateEmail:
return "A username for that e-mail address already exists. Please enter a different e-mail address.";
case MembershipCreateStatus.InvalidPassword:
return "The password provided is invalid. Please enter a valid password value.";
case MembershipCreateStatus.InvalidEmail:
return "The e-mail address provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.InvalidAnswer:
return "The password retrieval answer provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.InvalidQuestion:
return "The password retrieval question provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.InvalidUserName:
return "The user name provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.ProviderError:
return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
case MembershipCreateStatus.UserRejected:
return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
default:
return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
}
}
private bool ValidateChangePassword(string currentPassword, string newPassword, string confirmPassword) {
if (string.IsNullOrEmpty(currentPassword)) {
ModelState.AddModelError("currentPassword", "You must specify a current password.");
}
if (newPassword == null || newPassword.Length < this.MembershipService.MinPasswordLength) {
ModelState.AddModelError(
"newPassword",
string.Format(CultureInfo.CurrentCulture, "You must specify a new password of {0} or more characters.", this.MembershipService.MinPasswordLength));
}
if (!string.Equals(newPassword, confirmPassword, StringComparison.Ordinal)) {
ModelState.AddModelError("_FORM", "The new password and confirmation password do not match.");
}
return ModelState.IsValid;
}
private bool ValidateLogOn(string userName, string password) {
if (string.IsNullOrEmpty(userName)) {
ModelState.AddModelError("username", "You must specify a username.");
}
if (string.IsNullOrEmpty(password)) {
ModelState.AddModelError("password", "You must specify a password.");
}
if (!this.MembershipService.ValidateUser(userName, password)) {
ModelState.AddModelError("_FORM", "The username or password provided is incorrect.");
}
return ModelState.IsValid;
}
private bool ValidateRegistration(string userName, string email, string password, string confirmPassword) {
if (string.IsNullOrEmpty(userName)) {
ModelState.AddModelError("username", "You must specify a username.");
}
if (string.IsNullOrEmpty(email)) {
ModelState.AddModelError("email", "You must specify an email address.");
}
if (password == null || password.Length < this.MembershipService.MinPasswordLength) {
ModelState.AddModelError(
"password",
string.Format(CultureInfo.CurrentCulture, "You must specify a password of {0} or more characters.", this.MembershipService.MinPasswordLength));
}
if (!string.Equals(password, confirmPassword, StringComparison.Ordinal)) {
ModelState.AddModelError("_FORM", "The new password and confirmation password do not match.");
}
return ModelState.IsValid;
}
#endregion
}
}
|