Ejemplo n.º 1
0
        public LoginModule(IFlexMembershipProvider membership,
            IFlexOAuthProvider oAuthProvider,
            IDocumentSession session)
            : base(session)
        {
            _membership = membership;
            _oAuthProvider = oAuthProvider;
            Get["/login"] = p => View["login", new LoginModel
                {
                    ReturnUrl = Request.Query.returnUrl
                }];

            Post["/externallogin"] = p =>
                {
                    var model = this.Bind<LoginModel>();
                    _oAuthProvider.RequestOAuthAuthentication("Google", "/externalcallback?returnUrl=" + model.ReturnUrl);
                    return null;
                };

            Get["/externalfailure"] = p => View["externalfailure"];

            Get["/externalcallback"] = p =>
                {
                    var result = _oAuthProvider.VerifyOAuthAuthentication("/externalcallback");
                    if (!result.IsSuccessful)
                    {
                        return Response.AsRedirect("/externalfailure");
                    }

                    if (_oAuthProvider.OAuthLogin(result.Provider, result.ProviderUserId, persistCookie: false))
                    {
                        //Seems like OAuthLogin writes an auth cookie, but it can't be the cookie
                        //that nancy is expecting because it doesn't work

                        //we're all good up to here but then when we try to redirect to /events or whatever
                        //we just end up at the login screen again. We need to tell nancy that we're
                        //logged in somehow. Why does this have to be so hard?
                        string retVal = Request.Query.returnUrl;
                        return Response.AsRedirect(retVal ?? "/");
                    }

                    if (Context.CurrentUser != null)
                    {
                        // If the current user is logged in add the new account
                        var user = new User
                        {
                            UserName = Context.CurrentUser.UserName,
                            Id = Guid.NewGuid().ToString()
                        };
                        _oAuthProvider.CreateOAuthAccount(result.Provider, result.ProviderUserId, user);
                        CreateOrUpdatePersonRecord(user.UserName, user);
                        return Response.AsRedirect(Request.Query.returnUrl as string);
                    }
                    else
                    {
                        // User is new, ask for their desired membership name
                        var loginData = _encoder.SerializeOAuthProviderUserId(result.Provider, result.ProviderUserId);
                        return
                            View[
                                "externalloginconfirmation",
                                new RegisterExternalLoginModel
                                    {
                                        UserName = result.UserName,
                                        ExternalLoginData = loginData,
                                        ReturnUrl = Request.Query.returnUrl
                                    }];
                    }
                };

            Post["/externalloginconfirmation"] = p =>
                {
                    string provider = null;
                    string providerUserId = null;

                    Context.Request.Session["UserId"] = null;
                    Context.Request.Session["PersonId"] = null;

                    var model = this.Bind<RegisterExternalLoginModel>();

                    if (Context.CurrentUser != null || !_encoder.TryDeserializeOAuthProviderUserId(model.ExternalLoginData, out provider, out providerUserId))
                    {
                        return Response.AsRedirect("/manage");
                    }

                    if (!_membership.HasLocalAccount(model.UserName))
                    {
                        var user = new User
                        {
                            UserName = model.UserName,
                            Id = Guid.NewGuid().ToString()
                        };
                        _oAuthProvider.CreateOAuthAccount(provider, providerUserId, user);
                        _oAuthProvider.OAuthLogin(provider, providerUserId, persistCookie: false);
                        CreateOrUpdatePersonRecord(user.UserName, user);
                        return Response.AsRedirect(Request.Query.returnUrl as string);
                    }
                    else
                    {
                        //not sure how to do model validation yet
                        //ModelState.AddModelError("UserName", "User name already exists. Please enter a different user name.");
                    }

                    return View["/externalloginconfirmation", model];
                };

            Post["/login"] = p =>
                {
                    var model = this.Bind<LoginModel>();
                    var id = _membership.ValidateUser(model.UserName, model.Password);
                    if (id == null)
                    {
                        return Response.AsRedirect("/");
                    }

                    DateTime? expiry = null;

                    return this.LoginAndRedirect(id.Value, expiry, model.ReturnUrl);
                };

            Get["/logout"] = x => this.LogoutAndRedirect("~/");
        }
Ejemplo n.º 2
0
        private void CreateOrUpdatePersonRecord(string name, User user)
        {
            var person =
                Session.Query<Person>()
                            .FirstOrDefault(
                                p => p.EmailAddress.Equals(user.UserName, StringComparison.InvariantCultureIgnoreCase))
                ?? new Person
                {
                    Id = Guid.NewGuid().ToString(),
                    EmailAddress = user.UserName.ToLower(),
                    Name = name
                };

            person.UserId = user.Id;
            Session.Store(person);
        }