public async Task <IHttpActionResult> CreateUser(CreateUserBinding newUser)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            var user = new IdentityUser(newUser.ClientId, newUser.UserName)
            {
                Email     = newUser.Email,
                FirstName = newUser.FirstName,
                LastName  = newUser.LastName,
                Level     = 1,
                JoinDate  = DateTime.Now.Date,
            };

            var addUserResult = await JWTUserManager.CreateAsync(user, newUser.Password);

            if (!addUserResult.Succeeded)
            {
                return(GetErrorResult(addUserResult));
            }

            var code = await JWTUserManager.GenerateEmailConfirmationTokenAsync(user.Id);

            var callbackUrl = new Uri(Url.Link("ConfirmEmailRoute", new { userId = user.Id, code = code }));

            await JWTUserManager.SendEmailAsync(user.Id, JWTAuthServerConstants.ConfirmMailSubject,
                                                string.Format(JWTAuthServerConstants.ConfirmMailBody, callbackUrl));

            var locationHeader = new Uri(Url.Link("GetUserById", new { id = user.Id }));

            return(Created(locationHeader, EntityFactory.Create(user)));
        }
        public async Task <IHttpActionResult> ChangePassword(ChangePasswordBinding changedPassword)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            var requestingUserId = User.Identity.GetUserId();

            var result = await JWTUserManager.ChangePasswordAsync(
                User.Identity.GetUserId(), changedPassword.OldPassword, changedPassword.NewPassword);

            if (!result.Succeeded)
            {
                return(GetErrorResult(result));
            }

            var changingUser = JWTUserManager.FindById(requestingUserId);
            var client       = JWTClientManager.FindById(changingUser.ClientId);

            JWTMailer.Send(changingUser.Email, JWTAuthServerConstants.PasswordChangeMailSubject,
                           string.Format(JWTAuthServerConstants.PasswordChangeMailBody, client.Name));

            return(Ok());
        }
        public async Task <IHttpActionResult> ConfirmEmail(string userId = "", string code = "")
        {
            if (string.IsNullOrWhiteSpace(userId) || string.IsNullOrWhiteSpace(code))
            {
                ModelState.AddModelError("", JWTAuthServerConstants.UserIdAndCode);
                return(BadRequest(ModelState));
            }

            var result = await JWTUserManager.ConfirmEmailAsync(userId, code);

            if (result.Succeeded)
            {
                // Assigning the default user role when successfully confirming the email
                // so the user will have the default rights to access the API.
                await JWTUserManager.AddToRoleAsync(userId,
                                                    ConfigurationManager.AppSettings["JWTServer.InitialUserRole"]);

                var confirmedUser = JWTUserManager.FindById(userId);
                var client        = JWTClientManager.FindById(confirmedUser.ClientId);

                JWTMailer.Send(confirmedUser.Email, JWTAuthServerConstants.ConfirmResponseMailSubject,
                               string.Format(JWTAuthServerConstants.ConfirmResponseMailBody, client.Name));

                return(Ok());
            }
            else
            {
                return(GetErrorResult(result));
            }
        }
        public async Task <IHttpActionResult> GetUserByName(string username)
        {
            var user = await JWTUserManager.FindByNameAsync(username);

            if (user != null)
            {
                return(Ok(EntityFactory.Create(user)));
            }

            return(NotFound());
        }
        public async Task <IHttpActionResult> AssignRolesToUser(
            [FromUri] string id, [FromBody] string[] rolesToAssign)
        {
            var user = await JWTUserManager.FindByIdAsync(id);

            if (user == null)
            {
                return(NotFound());
            }

            var currentRoleSet =
                JWTRoleManager.Roles
                .Where(r => r.ClientId == user.ClientId || r.ClientId == null)
                .ToList();

            var currentUserRolesList = await JWTUserManager.GetRolesAsync(user.Id);

            var currentUserRoles = currentUserRolesList.List;

            var nonExistingRoles = rolesToAssign.Except(currentRoleSet.Select(r => r.Name)).ToArray();

            if (nonExistingRoles.Any())
            {
                ModelState.AddModelError("",
                                         string.Format(JWTAuthServerConstants.RolesDontExist, string.Join(",", nonExistingRoles)));
                return(BadRequest(ModelState));
            }

            var removeResult =
                await JWTUserManager.RemoveFromRolesAsync(user.Id, currentUserRoles.Select(r => r.Name).ToArray());

            if (!removeResult.Succeeded)
            {
                ModelState.AddModelError("", JWTAuthServerConstants.RoleRemoveFailed);
                return(BadRequest(ModelState));
            }

            var addResult = await JWTUserManager.AddToRolesAsync(user.Id, rolesToAssign);

            if (!addResult.Succeeded)
            {
                ModelState.AddModelError("", JWTAuthServerConstants.RoleAddFailed);
                return(BadRequest(ModelState));
            }

            return(Ok());
        }
        private JObject GenerateLocalAccessTokenResponse(IdentityUser user)
        {
            var tokenExpiration = TimeSpan.FromHours(1);

            var identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType);

            identity.AddClaim(new Claim(ClaimTypes.Name, user.UserName));
            identity.AddClaim(new Claim(ClaimTypes.Email, user.Email));

            //Get all assigned claims and add them
            var userClaims = JWTUserManager.GetClaims(user.Id);

            foreach (var userClaim in userClaims)
            {
                identity.AddClaim(new Claim(userClaim.Type, userClaim.Value));
            }

            //Get all assigned roles and add them as claims
            var userRoles = JWTUserManager.GetRoles(user.Id);

            foreach (var userRole in userRoles)
            {
                identity.AddClaim(new Claim(ClaimTypes.Role, userRole));
            }

            var props = new AuthenticationProperties()
            {
                IssuedUtc  = DateTime.UtcNow,
                ExpiresUtc = DateTime.UtcNow.Add(tokenExpiration),
            };

            var ticket = new AuthenticationTicket(identity, props);

            var accessToken = StartUpExtensions.OAuthBearerOptions.AccessTokenFormat.Protect(ticket);

            var tokenResponse = new JObject(
                new JProperty("userName", user.UserName)
                , new JProperty("access_token", accessToken)
                , new JProperty("token_type", "bearer")
                , new JProperty("expires_in", tokenExpiration.TotalSeconds.ToString())
                , new JProperty(".issued", ticket.Properties.IssuedUtc.ToString())
                , new JProperty(".expires", ticket.Properties.ExpiresUtc.ToString())
                );

            return(tokenResponse);
        }
        public async Task <IHttpActionResult> DeleteUser(string id)
        {
            var appUser = await JWTUserManager.FindByIdAsync(id);

            if (appUser != null)
            {
                var result = await JWTUserManager.DeleteAsync(appUser);

                if (!result.Succeeded)
                {
                    return(GetErrorResult(result));
                }

                return(Ok());
            }

            return(NotFound());
        }
        public async Task <IHttpActionResult> RegisterExternal(RegisterExternalBindingModel model)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            var verifiedAccessToken = await VerifyExternalAccessToken(model.Provider, model.ExternalAccessToken);

            if (verifiedAccessToken == null)
            {
                return(BadRequest("Invalid Provider or External Access Token"));
            }

            var user =
                await JWTUserLoginManager.FindUserByLoginAsync(new IdentityUserLogin()
            {
                LoginProvider = model.Provider,
                ProviderKey   = verifiedAccessToken.user_id
            }
                                                               );

            var hasRegistered = user != null;

            if (hasRegistered)
            {
                return(BadRequest("External user is already registered"));
            }

            user = new IdentityUser(model.ClientId, model.UserName)
            {
                Email = model.EMail
            };

            var result = await JWTUserManager.CreateAsync(user);

            if (!result.Succeeded)
            {
                return(GetErrorResult(result));
            }

            var userRole = await JWTRoleManager.FindByNameAsync(IdentityConstants.User);

            if (userRole != null)
            {
                await JWTUserManager.AddToRoleAsync(user, userRole);
            }

            result = await JWTUserLoginManager.CreateAsync(new IdentityUserLogin()
            {
                UserId          = user.Id
                , ClientId      = user.ClientId
                , LoginProvider = model.Provider
                , ProviderKey   = verifiedAccessToken.user_id
            }
                                                           );

            if (!result.Succeeded)
            {
                return(GetErrorResult(result));
            }

            //generate access token response
            var accessTokenResponse = GenerateLocalAccessTokenResponse(user);

            return(Ok(accessTokenResponse));
        }