PageRenderTime 71ms CodeModel.GetById 29ms app.highlight 36ms RepoModel.GetById 1ms app.codeStats 0ms

/RealState-Site/Site/Areas/Customer/Controllers/AccountController.cs

https://gitlab.com/hebron80/sample-app
C# | 409 lines | 323 code | 38 blank | 48 comment | 40 complexity | 13f433ac35dfa948f0632c9dc57b2844 MD5 | raw file
  1using System;
  2using System.Collections.Generic;
  3using System.Linq;
  4using System.Security.Claims;
  5using System.Threading.Tasks;
  6using System.Web;
  7using System.Web.Mvc;
  8using Microsoft.AspNet.Identity;
  9using Microsoft.AspNet.Identity.EntityFramework;
 10using Microsoft.Owin.Security;
 11using Site.Areas.Customer.Models;
 12
 13
 14namespace Site.Areas.Customer.Controllers
 15{
 16    //[Authorize]
 17    public class AccountController : BaseController
 18    {
 19        //public AccountController()
 20        //    : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
 21        //{
 22        //}
 23
 24        //public AccountController(UserManager<ApplicationUser> userManager)
 25        //{
 26        //    UserManager = userManager;
 27        //}
 28
 29        //public UserManager<ApplicationUser> UserManager { get; private set; }
 30
 31        //
 32        // GET: /Account/Login
 33        [AllowAnonymous]
 34        public ActionResult Login(string returnUrl)
 35        {
 36            ViewBag.ReturnUrl = returnUrl;
 37            return View();
 38        }
 39
 40        //
 41        // POST: /Account/Login
 42        [HttpPost]
 43        [AllowAnonymous]
 44        [ValidateAntiForgeryToken]
 45        public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
 46        {
 47            if (ModelState.IsValid)
 48            {
 49                var user = await UserManager.FindAsync(model.UserName, model.Password);
 50                if (user != null)
 51                {
 52                    await SignInAsync(user, model.RememberMe);
 53                    return RedirectToLocal(returnUrl);
 54                }
 55                else
 56                {
 57                    ModelState.AddModelError("", "Invalid username or password.");
 58                }
 59            }
 60
 61            // If we got this far, something failed, redisplay form
 62            return View(model);
 63        }
 64
 65        //
 66        // GET: /Account/Register
 67        [AllowAnonymous]
 68        public ActionResult Register()
 69        {
 70            return View();
 71        }
 72
 73        //
 74        // POST: /Account/Register
 75        [HttpPost]
 76        [AllowAnonymous]
 77        [ValidateAntiForgeryToken]
 78        public async Task<ActionResult> Register(RegisterViewModel model)
 79        {
 80            if (ModelState.IsValid)
 81            {
 82                var user = new ApplicationUser() { UserName = model.UserName };
 83                var result = await UserManager.CreateAsync(user, model.Password);
 84                if (result.Succeeded)
 85                {
 86                    await SignInAsync(user, isPersistent: false);
 87                    return RedirectToAction("Index", "Home");
 88                }
 89                else
 90                {
 91                    AddErrors(result);
 92                }
 93            }
 94
 95            // If we got this far, something failed, redisplay form
 96            return View(model);
 97        }
 98
 99        //
100        // POST: /Account/Disassociate
101        [HttpPost]
102        [ValidateAntiForgeryToken]
103        public async Task<ActionResult> Disassociate(string loginProvider, string providerKey)
104        {
105            ManageMessageId? message = null;
106            IdentityResult result = await UserManager.RemoveLoginAsync(User.Identity.GetUserId(), new UserLoginInfo(loginProvider, providerKey));
107            if (result.Succeeded)
108            {
109                message = ManageMessageId.RemoveLoginSuccess;
110            }
111            else
112            {
113                message = ManageMessageId.Error;
114            }
115            return RedirectToAction("Manage", new { Message = message });
116        }
117
118        //
119        // GET: /Account/Manage
120        public ActionResult Manage(ManageMessageId? message)
121        {
122            ViewBag.StatusMessage =
123                message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
124                : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
125                : message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
126                : message == ManageMessageId.Error ? "An error has occurred."
127                : "";
128            ViewBag.HasLocalPassword = HasPassword();
129            ViewBag.ReturnUrl = Url.Action("Manage");
130            return View();
131        }
132
133        //
134        // POST: /Account/Manage
135        [HttpPost]
136        [ValidateAntiForgeryToken]
137        public async Task<ActionResult> Manage(ManageUserViewModel model)
138        {
139            bool hasPassword = HasPassword();
140            ViewBag.HasLocalPassword = hasPassword;
141            ViewBag.ReturnUrl = Url.Action("Manage");
142            if (hasPassword)
143            {
144                if (ModelState.IsValid)
145                {
146                    IdentityResult result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword);
147                    if (result.Succeeded)
148                    {
149                        return RedirectToAction("Manage", new { Message = ManageMessageId.ChangePasswordSuccess });
150                    }
151                    else
152                    {
153                        AddErrors(result);
154                    }
155                }
156            }
157            else
158            {
159                // User does not have a password so remove any validation errors caused by a missing OldPassword field
160                ModelState state = ModelState["OldPassword"];
161                if (state != null)
162                {
163                    state.Errors.Clear();
164                }
165
166                if (ModelState.IsValid)
167                {
168                    IdentityResult result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword);
169                    if (result.Succeeded)
170                    {
171                        return RedirectToAction("Manage", new { Message = ManageMessageId.SetPasswordSuccess });
172                    }
173                    else
174                    {
175                        AddErrors(result);
176                    }
177                }
178            }
179
180            // If we got this far, something failed, redisplay form
181            return View(model);
182        }
183
184        //
185        // POST: /Account/ExternalLogin
186        [HttpPost]
187        [AllowAnonymous]
188        [ValidateAntiForgeryToken]
189        public ActionResult ExternalLogin(string provider, string returnUrl)
190        {
191            // Request a redirect to the external login provider
192            return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));
193        }
194
195        //
196        // GET: /Account/ExternalLoginCallback
197        [AllowAnonymous]
198        public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
199        {
200            var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
201            if (loginInfo == null)
202            {
203                return RedirectToAction("Login");
204            }
205
206            // Sign in the user with this external login provider if the user already has a login
207            var user = await UserManager.FindAsync(loginInfo.Login);
208            if (user != null)
209            {
210                await SignInAsync(user, isPersistent: false);
211                return RedirectToLocal(returnUrl);
212            }
213            else
214            {
215                // If the user does not have an account, then prompt the user to create an account
216                ViewBag.ReturnUrl = returnUrl;
217                ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
218                return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { UserName = loginInfo.DefaultUserName });
219            }
220        }
221
222        //
223        // POST: /Account/LinkLogin
224        [HttpPost]
225        [ValidateAntiForgeryToken]
226        public ActionResult LinkLogin(string provider)
227        {
228            // Request a redirect to the external login provider to link a login for the current user
229            return new ChallengeResult(provider, Url.Action("LinkLoginCallback", "Account"), User.Identity.GetUserId());
230        }
231
232        //
233        // GET: /Account/LinkLoginCallback
234        public async Task<ActionResult> LinkLoginCallback()
235        {
236            var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(XsrfKey, User.Identity.GetUserId());
237            if (loginInfo == null)
238            {
239                return RedirectToAction("Manage", new { Message = ManageMessageId.Error });
240            }
241            var result = await UserManager.AddLoginAsync(User.Identity.GetUserId(), loginInfo.Login);
242            if (result.Succeeded)
243            {
244                return RedirectToAction("Manage");
245            }
246            return RedirectToAction("Manage", new { Message = ManageMessageId.Error });
247        }
248
249        //
250        // POST: /Account/ExternalLoginConfirmation
251        [HttpPost]
252        [AllowAnonymous]
253        [ValidateAntiForgeryToken]
254        public async Task<ActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl)
255        {
256            if (User.Identity.IsAuthenticated)
257            {
258                return RedirectToAction("Manage");
259            }
260
261            if (ModelState.IsValid)
262            {
263                // Get the information about the user from the external login provider
264                var info = await AuthenticationManager.GetExternalLoginInfoAsync();
265                if (info == null)
266                {
267                    return View("ExternalLoginFailure");
268                }
269                var user = new ApplicationUser() { UserName = model.UserName };
270                var result = await UserManager.CreateAsync(user);
271                if (result.Succeeded)
272                {
273                    result = await UserManager.AddLoginAsync(user.Id, info.Login);
274                    if (result.Succeeded)
275                    {
276                        await SignInAsync(user, isPersistent: false);
277                        return RedirectToLocal(returnUrl);
278                    }
279                }
280                AddErrors(result);
281            }
282
283            ViewBag.ReturnUrl = returnUrl;
284            return View(model);
285        }
286
287        //
288        // POST: /Account/LogOff
289        [HttpPost]
290        [ValidateAntiForgeryToken]
291        public ActionResult LogOff()
292        {
293            AuthenticationManager.SignOut();
294            return RedirectToAction("Index", "Home");
295        }
296
297        //
298        // GET: /Account/ExternalLoginFailure
299        [AllowAnonymous]
300        public ActionResult ExternalLoginFailure()
301        {
302            return View();
303        }
304
305        [ChildActionOnly]
306        public ActionResult RemoveAccountList()
307        {
308            var linkedAccounts = UserManager.GetLogins(User.Identity.GetUserId());
309            ViewBag.ShowRemoveButton = HasPassword() || linkedAccounts.Count > 1;
310            return (ActionResult)PartialView("_RemoveAccountPartial", linkedAccounts);
311        }
312
313        protected override void Dispose(bool disposing)
314        {
315            if (disposing && UserManager != null)
316            {
317                UserManager.Dispose();
318                UserManager = null;
319            }
320            base.Dispose(disposing);
321        }
322
323        #region Helpers
324        // Used for XSRF protection when adding external logins
325        private const string XsrfKey = "XsrfId";
326
327        private IAuthenticationManager AuthenticationManager
328        {
329            get
330            {
331                return HttpContext.GetOwinContext().Authentication;
332            }
333        }
334
335        private async Task SignInAsync(ApplicationUser user, bool isPersistent)
336        {
337            AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
338            var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
339            AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
340        }
341
342        private void AddErrors(IdentityResult result)
343        {
344            foreach (var error in result.Errors)
345            {
346                ModelState.AddModelError("", error);
347            }
348        }
349
350        private bool HasPassword()
351        {
352            var user = UserManager.FindById(User.Identity.GetUserId());
353            if (user != null)
354            {
355                return user.PasswordHash != null;
356            }
357            return false;
358        }
359
360        public enum ManageMessageId
361        {
362            ChangePasswordSuccess,
363            SetPasswordSuccess,
364            RemoveLoginSuccess,
365            Error
366        }
367
368        private ActionResult RedirectToLocal(string returnUrl)
369        {
370            if (Url.IsLocalUrl(returnUrl))
371            {
372                return Redirect(returnUrl);
373            }
374            else
375            {
376                return RedirectToAction("Index", "Home");
377            }
378        }
379
380        private class ChallengeResult : HttpUnauthorizedResult
381        {
382            public ChallengeResult(string provider, string redirectUri) : this(provider, redirectUri, null)
383            {
384            }
385
386            public ChallengeResult(string provider, string redirectUri, string userId)
387            {
388                LoginProvider = provider;
389                RedirectUri = redirectUri;
390                UserId = userId;
391            }
392
393            public string LoginProvider { get; set; }
394            public string RedirectUri { get; set; }
395            public string UserId { get; set; }
396
397            public override void ExecuteResult(ControllerContext context)
398            {
399                var properties = new AuthenticationProperties() { RedirectUri = RedirectUri };
400                if (UserId != null)
401                {
402                    properties.Dictionary[XsrfKey] = UserId;
403                }
404                context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
405            }
406        }
407        #endregion
408    }
409}