Exemple #1
0
        public async Task <ApiResponse <AdminEditClaimVM> > DeleteClaimAsync(AuthenticateUserVM authUser, AdminEditClaimVM claimToDelete)
        {
            try
            {
                if (authUser == null || !authUser.IsAuthenticated || !authUser.HasRole("Admin"))
                {
                    return(new ApiResponse <AdminEditClaimVM>(StatusCodeType.Status401Unauthorized, "You are not Authorized to Delete Claims", null));
                }
                if (claimToDelete.Name.IsNullOrWhiteSpace())
                {
                    return(new ApiResponse <AdminEditClaimVM>(StatusCodeType.Status400BadRequest, "Name for the Claim was not supplied, as it is done automatically it should never happen", null));
                }
                var claimResp = await FindClaimByNameAsync(claimToDelete.Name);

                if (claimResp.IsError)
                {
                    return(new ApiResponse <AdminEditClaimVM>(StatusCodeType.Status400BadRequest, $"Claim \"{claimToDelete.Name}\" was not found, it should never happen", null));
                }

                _db.UserClaims.RemoveBy(c => c.ClaimType.ToLower() == claimToDelete.Name.ToLower());
                await _db.SaveChangesAsync();

                return(new ApiResponse <AdminEditClaimVM>(StatusCodeType.Status201Created, $"Successfully Deleted Claim \"{claimToDelete.Name}\"", null, claimToDelete));
            }
            catch (Exception ex)
            {
                return(new ApiResponse <AdminEditClaimVM>(StatusCodeType.Status500InternalServerError, "Deleting Claim Failed", null, null, ex));
            }
        }
Exemple #2
0
        public async Task <ApiResponse <List <FindUserVM> > > GetAllUsersAsync(AuthenticateUserVM authenticatedUser)
        {
            try
            {
                if (authenticatedUser == null || !authenticatedUser.IsAuthenticated || !authenticatedUser.HasRole("Admin"))
                {
                    return(new ApiResponse <List <FindUserVM> >(StatusCodeType.Status401Unauthorized, "You are not Authorized to Access Users' Data", null));
                }

                var users = await _userManager.Users.ToListAsync();

                var userToFind = new List <FindUserVM>();
                foreach (var user in users)
                {
                    var userToEditByAdmin = _mapper.Map(user, new FindUserVM());
                    userToEditByAdmin.Roles  = (await _userManager.GetRolesAsync(user)).Select(r => FindRoleByName(r).Result).ToList();
                    userToEditByAdmin.Claims = (await _userManager.GetClaimsAsync(user)).Select(c => FindClaimByName(c.Type).Result).Where(c => !c.Name.EqualsIgnoreCase("Email")).ToList();
                    userToFind.Add(userToEditByAdmin);
                }

                return(new ApiResponse <List <FindUserVM> >(StatusCodeType.Status201Created, "Successfully Retrieved Users", null, userToFind));
            }
            catch (Exception ex)
            {
                return(new ApiResponse <List <FindUserVM> >(StatusCodeType.Status500InternalServerError, "Retrieving Users Failed", null, null, ex));
            }
        }
Exemple #3
0
        public async Task <ApiResponse <List <FindRoleVM> > > GetRolesAsync(AuthenticateUserVM authenticatedUser)
        {
            try
            {
                if (authenticatedUser == null || !authenticatedUser.IsAuthenticated || !authenticatedUser.HasRole("Admin"))
                {
                    return(new ApiResponse <List <FindRoleVM> >(StatusCodeType.Status401Unauthorized, "You are not Authorized to Access Roles", null));
                }

                var foundRoles = (await _roleManager.Roles.ToListAsync()).Select(rl => new FindRoleVM
                {
                    Id        = rl.Id,
                    Name      = rl.Name,
                    UserNames = (
                        from ur in _db.UserRoles
                        join r in _db.Roles on ur.RoleId equals r.Id
                        join u in _db.Users on ur.UserId equals u.Id
                        where rl.Id == r.Id
                        select u.UserName).ToList()
                }).ToList();

                return(new ApiResponse <List <FindRoleVM> >(StatusCodeType.Status201Created, "Successfully Retrieved Roles", null, foundRoles));
            }
            catch (Exception ex)
            {
                return(new ApiResponse <List <FindRoleVM> >(StatusCodeType.Status500InternalServerError, "Retrieving Roles Failed", null, null, ex));
            }
        }
Exemple #4
0
        public async Task <ApiResponse <AdminEditUserVM> > AddUserAsync(AuthenticateUserVM authUser, AdminEditUserVM userToAdd)
        {
            try
            {
                if (authUser == null || !authUser.IsAuthenticated || !authUser.HasRole("Admin"))
                {
                    return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status401Unauthorized, "You are not Authorized to Add Users", null));
                }

                var user = new User
                {
                    UserName       = userToAdd.UserName,
                    Email          = userToAdd.Email,
                    EmailConfirmed = userToAdd.IsConfirmed,
                };

                var addUserResp = await _userManager.CreateAsync(user);

                if (!addUserResp.Succeeded)
                {
                    return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status400BadRequest, $"Adding User \"{userToAdd.UserName}\" Failed. ({addUserResp.FirstError()})", null));
                }

                if (!userToAdd.Password.IsNullOrWhiteSpace())
                {
                    user = await _db.Users.SingleOrDefaultAsync(u => u.UserName.ToLower() == userToAdd.UserName.ToLower());

                    user.PasswordHash = _passwordHasher.HashPassword(user, userToAdd.Password); // use db directly to override identity constraints, we are admin after all here
                    await _db.SaveChangesAsync();
                }

                var addRolesResp = await _userManager.AddToRolesAsync(user, userToAdd.Roles.Select(r => r.Name));

                if (!addRolesResp.Succeeded)
                {
                    return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status400BadRequest, $"Adding User \"{userToAdd.UserName}\" Succeeded, but modifying Roles Failed. ({addRolesResp.FirstError()})", null));
                }

                var addClaimsResp = await _userManager.AddClaimsAsync(user, userToAdd.Claims.Select(c => new Claim(c.Name, c.Values.First().Value))); // we don't consider values for simplicity sake so we can tak any (first) available

                if (!addClaimsResp.Succeeded)
                {
                    return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status400BadRequest, $"Editing User with Id: \"{userToAdd.Id}\" Succeeded, but modifying Claims Failed. ({addClaimsResp.FirstError()})", null));
                }

                return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status201Created, $"Successfully Added User: \"{userToAdd.UserName}\"", null, userToAdd));
            }
            catch (Exception ex)
            {
                return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status500InternalServerError, "Adding User Failed", null, null, ex));
            }
        }
Exemple #5
0
        public async Task <ApiResponse <AuthenticateUserVM> > LogoutAsync(AuthenticateUserVM authUser)
        {
            try
            {
                if (authUser == null || !authUser.IsAuthenticated)
                {
                    return(new ApiResponse <AuthenticateUserVM>(StatusCodeType.Status401Unauthorized, "You are not Authorized so you can't log out", null));
                }

                await _signInManager.SignOutAsync();

                return(new ApiResponse <AuthenticateUserVM>(StatusCodeType.Status200OK, $"You (\"{authUser.UserName}\") have been successfully logged out ", null, authUser));
            }
            catch (Exception ex)
            {
                return(new ApiResponse <AuthenticateUserVM>(StatusCodeType.Status500InternalServerError, "Loggin User out has Failed", null, null, ex));
            }
        }
Exemple #6
0
        public async Task <ApiResponse <AuthenticateUserVM> > GetAuthenticatedUserAsync()
        {
            try
            {
                var cookieTIcket = await _jsRuntime.InvokeAsync <string>("Cookies.get", "Ticket");

                var localStorageTicket = await _localStorage.GetItemAsStringAsync("Ticket");

                var userToAuthenticate = new AuthenticateUserVM {
                    Ticket = cookieTIcket ?? localStorageTicket, IsAuthenticated = false
                };
                return(await _httpClient.PostJTokenAsync <ApiResponse <AuthenticateUserVM> >("api/account/authenticateuser", userToAuthenticate));
            }
            catch (Exception ex)
            {
                return(new ApiResponse <AuthenticateUserVM>(StatusCodeType.Status500InternalServerError, "API threw an exception while trying to authenticate user", null, AuthenticateUserVM.NotAuthenticated, ex));
            }
        }
Exemple #7
0
        public async Task <ApiResponse <AdminEditRoleVM> > AddRoleAsync(AuthenticateUserVM authUser, AdminEditRoleVM roleToAdd)
        {
            try
            {
                if (authUser == null || !authUser.IsAuthenticated || !authUser.HasRole("Admin"))
                {
                    return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status401Unauthorized, "You are not Authorized to Add Roles", null));
                }

                var role = new IdentityRole <Guid> {
                    Name = roleToAdd.Name
                };

                var addRoleResp = await _roleManager.CreateAsync(role);

                if (!addRoleResp.Succeeded)
                {
                    return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status400BadRequest, $"Adding Role \"{roleToAdd.Name}\" Failed. ({addRoleResp.FirstError()})", null));
                }

                foreach (var userName in roleToAdd.UserNames)
                {
                    var user = await _userManager.FindByNameAsync(userName);

                    if (user == null)
                    {
                        return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status400BadRequest, $"Adding Role \"{roleToAdd.Name}\" to User \"{userName}\" Failed, there is no such User", null));
                    }

                    var addRoleToUserResp = await _userManager.AddToRoleAsync(user, role.Name);

                    if (!addRoleToUserResp.Succeeded)
                    {
                        return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status400BadRequest, $"Adding Role \"{roleToAdd.Name}\" to User \"{userName}\" Failed. ({addRoleResp.FirstError()})", null));
                    }
                }

                return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status201Created, $"Successfully Added Role: \"{roleToAdd.Name}\"", null, roleToAdd));
            }
            catch (Exception ex)
            {
                return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status500InternalServerError, "Adding Role Failed", null, null, ex));
            }
        }
        public async Task <ActionResult <AuthenticatedUserVM> > Authenticate(AuthenticateUserVM user)
        {
            try
            {
                AuthenticatedUserVM authenticatedUser = await this._tokenService.GenerateApiToken(user.UserName, user.UserPassword);

                LogTraceVM logTrace = new LogTraceVM(string.Empty, "AuthenticateController", "Authenticate");
                logTrace.Parameters.Add(user);

                return(Ok(authenticatedUser));
            }
            catch (Exception error)
            {
                LogErrorVM logError = new LogErrorVM(error.Message, error.StackTrace, "AuthenticateController", "Authenticate");
                logError.Parameters.Add(user);
                this._logger.LogError(error, logError.ToString());
                return(BadRequest(error.Message));
            }
        }
Exemple #9
0
        public async Task <ApiResponse <AdminEditUserVM> > DeleteUserAsync(AuthenticateUserVM authenticatedUser, AdminEditUserVM userToDelete)
        {
            try
            {
                if (authenticatedUser == null || !authenticatedUser.IsAuthenticated || !authenticatedUser.HasRole("Admin"))
                {
                    return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status401Unauthorized, "You are not Authorized to Delete Users", null));
                }
                if (authenticatedUser.Id == userToDelete.Id)
                {
                    return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status401Unauthorized, "You can't Delete yourself", null));
                }

                if (userToDelete.Id == default)
                {
                    return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status400BadRequest, "Id for the User was not supplied, as it is done automatically it should never happen", null));
                }

                var user = await _userManager.FindByIdAsync(userToDelete.Id.ToString());

                if (user == null)
                {
                    return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status400BadRequest, $"User with Id: \"{userToDelete.Id}\" was not found, it should never happen", null));
                }

                var deleteUserResponse = await _userManager.DeleteAsync(user);

                if (!deleteUserResponse.Succeeded)
                {
                    return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status400BadRequest, $"Deleting User with Id: \"{userToDelete.Id}\" Failed. ({deleteUserResponse.FirstError()})", null));
                }

                userToDelete.IsDeleted = true;
                return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status201Created, $"Successfully Deleted User: \"{userToDelete.UserName}\"", null, userToDelete));
            }
            catch (Exception ex)
            {
                return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status500InternalServerError, "Deleting User Failed", null, null, ex));
            }
        }
Exemple #10
0
        public async Task <ApiResponse <AdminEditRoleVM> > DeleteRoleAsync(AuthenticateUserVM authUser, AdminEditRoleVM roleToDelete)
        {
            try
            {
                if (authUser == null || !authUser.IsAuthenticated || !authUser.HasRole("Admin"))
                {
                    return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status401Unauthorized, "You are not Authorized to Delete Roles", null));
                }
                if (roleToDelete.Name.IsNullOrWhiteSpace())
                {
                    return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status400BadRequest, "Name for the Role was not supplied, as it is done automatically it should never happen", null));
                }
                if (roleToDelete.Name.EqualsIgnoreCase("Admin"))
                {
                    return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status400BadRequest, "You can't remove \"Admin\" role, it would be just dumb", null));
                }
                var role = await _roleManager.FindByNameAsync(roleToDelete.Name);

                if (role == null)
                {
                    return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status400BadRequest, $"Role \"{roleToDelete.Name}\" was not found, it should never happen", null));
                }

                var deleteRoleResponse = await _roleManager.DeleteAsync(role);

                if (!deleteRoleResponse.Succeeded)
                {
                    return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status400BadRequest, $"Deleting Role \"{roleToDelete.Name}\" Failed. ({deleteRoleResponse.FirstError()})", null));
                }

                return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status201Created, $"Successfully Deleted Role \"{roleToDelete.Name}\"", null, roleToDelete));
            }
            catch (Exception ex)
            {
                return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status500InternalServerError, "Deleting Role Failed", null, null, ex));
            }
        }
Exemple #11
0
        public async Task <ApiResponse <List <FindClaimVM> > > GetClaimsAsync(AuthenticateUserVM authenticatedUser)
        {
            try
            {
                if (authenticatedUser == null || !authenticatedUser.IsAuthenticated || !authenticatedUser.HasRole("Admin"))
                {
                    return(new ApiResponse <List <FindClaimVM> >(StatusCodeType.Status401Unauthorized, "You are not Authorized to Access Claims", null));
                }

                var claims = (
                    from uc in await _db.UserClaims.ToListAsync()
                    group uc by uc.ClaimType
                    into claimsByType
                    select new FindClaimVM
                {
                    Name = claimsByType.Key,
                    Values = (
                        from cbt in claimsByType
                        group cbt by cbt.ClaimValue
                        into claimByTypeByValue
                        select new FindClaimValueVM
                    {
                        Value = claimByTypeByValue.Key,
                        UserNames = (
                            from cbtbv in claimByTypeByValue
                            join u in _db.Users.ToList() on cbtbv.UserId equals u.Id
                            select u.UserName).ToList()
                    }).ToList()
                }).ToList();

                return(new ApiResponse <List <FindClaimVM> >(StatusCodeType.Status201Created, "Successfully Retrieved Claims", null, claims));
            }
            catch (Exception ex)
            {
                return(new ApiResponse <List <FindClaimVM> >(StatusCodeType.Status500InternalServerError, "Retrieving Claims Failed", null, null, ex));
            }
        }
Exemple #12
0
        public async Task <ApiResponse <AdminEditClaimVM> > EditClaimAsync(AuthenticateUserVM authUser, AdminEditClaimVM claimToEdit)
        {
            try
            {
                if (authUser == null || !authUser.IsAuthenticated || !authUser.HasRole("Admin"))
                {
                    return(new ApiResponse <AdminEditClaimVM>(StatusCodeType.Status401Unauthorized, "You are not Authorized to Edit Claims", null));
                }
                if (claimToEdit.Name.IsNullOrWhiteSpace())
                {
                    return(new ApiResponse <AdminEditClaimVM>(StatusCodeType.Status400BadRequest, "Claim Name cannot be Empty", new[] { new KeyValuePair <string, string>("Name", "You need to provide Claim Name") }.ToLookup()));
                }
                var claimsResp = await GetClaimsAsync(authUser);

                if (claimsResp.IsError)
                {
                    return(new ApiResponse <AdminEditClaimVM>(StatusCodeType.Status400BadRequest, "Unable to retrieve other Claims", null));
                }
                var otherClaims = claimsResp.Result.Where(c => !c.Name.EqualsIgnoreCase(claimToEdit.OriginalName));
                if (claimToEdit.Name.EqAnyIgnoreCase(otherClaims.Select(c => c.Name)))
                {
                    return(new ApiResponse <AdminEditClaimVM>(StatusCodeType.Status400BadRequest, "Claim Name cannot be a Duplicate", new[] { new KeyValuePair <string, string>("Name", "Claim Name is a Duplicate") }.ToLookup()));
                }
                if (!claimToEdit.GetUserNames().Any())
                {
                    return(new ApiResponse <AdminEditClaimVM>(StatusCodeType.Status400BadRequest, "You need to choose at least one User because Claims exist soloely in the context of users", null));
                }

                _db.UserClaims.RemoveBy(c => c.ClaimType.ToLower() == claimToEdit.OriginalName.ToLower()); // as much as I'd love to add 'EqualsInvariantIgnoreCase' in all these 'Queryable' backed places, I can't :/.
                await _db.SaveChangesAsync();

                foreach (var claimVal in claimToEdit.Values) // claims have no table, they exist in thew context of users only so if sb removes a claim from all users, the claim is no longer stored anywhere
                {
                    foreach (var userName in claimVal.UserNames)
                    {
                        var user = await _userManager.FindByNameAsync(userName);

                        if (user == null)
                        {
                            return(new ApiResponse <AdminEditClaimVM>(StatusCodeType.Status400BadRequest, $"Editing Claim \"{claimToEdit.Name}\" for User \"{userName}\" Failed, there is no such User", null));
                        }
                        var hasClaimResp = await HasClaimAsync(user, claimToEdit.Name);

                        if (hasClaimResp.IsError)
                        {
                            return(new ApiResponse <AdminEditClaimVM>(StatusCodeType.Status400BadRequest, $"Checking Claim \"{claimToEdit.Name}\" existence for User \"{userName}\" Failed", null));
                        }
                        var hasClaim = hasClaimResp.Result;

                        if (!hasClaim)
                        {
                            var addClaimToUserResp = await _userManager.AddClaimAsync(user, new Claim(claimToEdit.Name, claimVal.Value));

                            if (!addClaimToUserResp.Succeeded)
                            {
                                return(new ApiResponse <AdminEditClaimVM>(StatusCodeType.Status400BadRequest, $"Editing Claim \"{claimToEdit.Name}\" for User \"{userName}\" Failed. ({addClaimToUserResp.FirstError()})", null));
                            }
                        }
                    }
                }

                return(new ApiResponse <AdminEditClaimVM>(StatusCodeType.Status201Created, $"Successfully Edited Claim: \"{claimToEdit.Name}\"", null, claimToEdit));
            }
            catch (Exception ex)
            {
                return(new ApiResponse <AdminEditClaimVM>(StatusCodeType.Status500InternalServerError, "Editing Claim Failed", null, null, ex));
            }
        }
Exemple #13
0
        public async Task <ApiResponse <AdminEditRoleVM> > EditRoleAsync(AuthenticateUserVM authUser, AdminEditRoleVM roleToEdit)
        {
            try
            {
                if (authUser == null || !authUser.IsAuthenticated || !authUser.HasRole("Admin"))
                {
                    return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status401Unauthorized, "You are not Authorized to Edit Roles", null));
                }
                if (roleToEdit.Id == default)
                {
                    return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status400BadRequest, "Role Id is Empty, it should never happen", null));
                }
                var role = await _roleManager.FindByIdAsync(roleToEdit.Id.ToString());

                if (role.Name.EqualsIgnoreCase("Admin") && !role.Name.EqualsIgnoreCase(roleToEdit.Name))
                {
                    return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status400BadRequest, $"You can't change \"{role.Name}\" Role Name", null));
                }
                if (role.Name.EqualsIgnoreCase("Admin") && !authUser.UserName.EqAnyIgnoreCase(roleToEdit.UserNames))
                {
                    return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status400BadRequest, $"You can't remove \"{role.Name}\" Role from yourself", null));
                }

                _mapper.Map(roleToEdit, role);

                var updateRoleResp = await _roleManager.UpdateAsync(role);

                if (!updateRoleResp.Succeeded)
                {
                    return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status400BadRequest, $"Editing Role \"{roleToEdit.Name}\" Failed. ({updateRoleResp.FirstError()})", null));
                }

                var users = await _userManager.Users.ToListAsync();

                foreach (var user in users)
                {
                    if (user.UserName.In(roleToEdit.UserNames) && !await _userManager.IsInRoleAsync(user, roleToEdit.Name))
                    {
                        var addUserToRoleResp = await _userManager.AddToRoleAsync(user, roleToEdit.Name);

                        if (!addUserToRoleResp.Succeeded)
                        {
                            return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status400BadRequest, $"Adding Role \"{roleToEdit.Name}\" to User \"{user.UserName}\" Failed. ({updateRoleResp.FirstError()})", null));
                        }
                    }

                    if (!user.UserName.In(roleToEdit.UserNames) && await _userManager.IsInRoleAsync(user, roleToEdit.Name))
                    {
                        var removeUserfromRoleResp = await _userManager.RemoveFromRoleAsync(user, roleToEdit.Name);

                        if (!removeUserfromRoleResp.Succeeded)
                        {
                            return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status400BadRequest, $"Removing Role \"{roleToEdit.Name}\" from User \"{user.UserName}\" Failed. ({updateRoleResp.FirstError()})", null));
                        }
                    }
                }

                return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status201Created, $"Successfully Updated Role: \"{roleToEdit.Name}\"", null, roleToEdit));
            }
            catch (Exception ex)
            {
                return(new ApiResponse <AdminEditRoleVM>(StatusCodeType.Status500InternalServerError, "Adding Role Failed", null, null, ex));
            }
        }
Exemple #14
0
        public async Task <ApiResponse <AdminEditUserVM> > EditUserAsync(AuthenticateUserVM authenticatedUser, AdminEditUserVM userToEdit)
        {
            try
            {
                if (authenticatedUser == null || !authenticatedUser.IsAuthenticated || !authenticatedUser.HasRole("Admin"))
                {
                    return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status401Unauthorized, "You are not Authorized to Edit Users", null));
                }
                if (userToEdit.Id == authenticatedUser.Id && !userToEdit.HasRole("Admin"))
                {
                    return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status401Unauthorized, "You can't remove \"Admin\" Role from your own Account", null));
                }
                if (userToEdit.Id == default)
                {
                    return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status400BadRequest, "Id for the User was not supplied, as it is done automatically it should never happen", null));
                }
                var user = await _db.Users.SingleOrDefaultAsync(u => u.Id == userToEdit.Id);

                if (user == null)
                {
                    return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status400BadRequest, $"User with Id: \"{userToEdit.Id}\" was not found, it should never happen", null));
                }

                user.Email          = userToEdit.Email.IsNullOrWhiteSpace() ? user.Email : userToEdit.Email;
                user.UserName       = userToEdit.UserName.IsNullOrWhiteSpace() ? user.UserName : userToEdit.UserName;
                user.EmailConfirmed = userToEdit.IsConfirmed;
                var updateuserResp = await _userManager.UpdateAsync(user);

                if (!updateuserResp.Succeeded)
                {
                    return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status400BadRequest, $"Editing User with Id: \"{userToEdit.Id}\" Failed", updateuserResp.Errors.ToLookup(userToEdit.GetPropertyNames())));
                }

                if (!userToEdit.Password.IsNullOrWhiteSpace() && _passwordHasher.VerifyHashedPassword(user, user.PasswordHash, userToEdit.Password) != PasswordVerificationResult.Success) // if admin changed password to a new one
                {
                    user.PasswordHash = _passwordHasher.HashPassword(user, userToEdit.Password);
                    await _db.SaveChangesAsync();

                    if (userToEdit.Id == authenticatedUser.Id)
                    {
                        userToEdit.Ticket = await _accountManager.GenerateLoginTicketAsync(user.Id, user.PasswordHash, authenticatedUser.RememberMe);
                    }
                }

                var removeRolesResp = await _userManager.RemoveFromRolesAsync(user, await _userManager.GetRolesAsync(user));

                var editRolesResp = await _userManager.AddToRolesAsync(user, userToEdit.Roles.Select(r => r.Name));

                if (!removeRolesResp.Succeeded || !editRolesResp.Succeeded)
                {
                    return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status400BadRequest, $"Editing User with Id: \"{userToEdit.Id}\" Succeeded, but modifying Roles Failed. ({(!removeRolesResp.Succeeded ? removeRolesResp.FirstError() : editRolesResp.FirstError())})", null));
                }

                var removeClaimsResp = await _userManager.RemoveClaimsAsync(user, await _userManager.GetClaimsAsync(user));

                var editClaimsResp = await _userManager.AddClaimsAsync(user, userToEdit.Claims.Select(c => new Claim(c.Name, c.Values.First().Value))); // we don't consider values for simplicity sake so we can tak any (first) available

                if (!removeClaimsResp.Succeeded || !editClaimsResp.Succeeded)
                {
                    return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status400BadRequest, $"Editing User with Id: \"{userToEdit.Id}\" Succeeded, but modifying Claims Failed. ({(!removeClaimsResp.Succeeded ? removeClaimsResp.FirstError() : editClaimsResp.FirstError())})", null));
                }

                return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status201Created, $"Successfully Modified User: \"{userToEdit.UserName}\"", null, userToEdit));
            }
            catch (Exception ex)
            {
                return(new ApiResponse <AdminEditUserVM>(StatusCodeType.Status500InternalServerError, "Updating User Failed", null, null, ex));
            }
        }
Exemple #15
0
        public async Task <ApiResponse <EditUserVM> > EditAsync(AuthenticateUserVM authUser, EditUserVM userToEdit)
        {
            try
            {
                if (authUser == null || !authUser.IsAuthenticated)
                {
                    return(new ApiResponse <EditUserVM>(StatusCodeType.Status401Unauthorized, "You are not Authorized to Edit User Data", null));
                }
                if (userToEdit.Id == default)
                {
                    return(new ApiResponse <EditUserVM>(StatusCodeType.Status404NotFound, "Id wasn't supplied", new[] { new KeyValuePair <string, string>("Id", "Id is empty") }.ToLookup()));
                }

                var user = await _userManager.FindByIdAsync(userToEdit.Id.ToString());

                if (userToEdit.Id == default)
                {
                    return(new ApiResponse <EditUserVM>(StatusCodeType.Status404NotFound, "There is no User with this Id", new[] { new KeyValuePair <string, string>("Id", "There is no User with the supplied Id") }.ToLookup()));
                }

                var isConfirmationRequired = !userToEdit.Email.EqualsInvariant(user.Email) && _userManager.Options.SignIn.RequireConfirmedEmail;
                user.Email    = userToEdit.Email.IsNullOrWhiteSpace() ? user.Email : userToEdit.Email;
                user.UserName = userToEdit.UserName.IsNullOrWhiteSpace() ? user.UserName : userToEdit.UserName;
                await _userManager.UpdateAsync(user);

                if (!userToEdit.NewPassword.IsNullOrWhiteSpace() && !userToEdit.NewPassword.EqualsInvariant(userToEdit.OldPassword))
                {
                    user = await _db.Users.SingleOrDefaultAsync(u => u.Id == userToEdit.Id);

                    if (user.PasswordHash != null && _passwordHasher.VerifyHashedPassword(user, user.PasswordHash, userToEdit.OldPassword) != PasswordVerificationResult.Success) // user should be allowed to change password if he didn't set one at all (was logging in exclusively with an external provider) or if he provided correct Old Password to his Account
                    {
                        return(new ApiResponse <EditUserVM>(StatusCodeType.Status401Unauthorized, "Old Password is not Correct", new[] { new KeyValuePair <string, string>("OldPassword", "Incorrect Password") }.ToLookup()));
                    }

                    var errors = new List <IdentityError>();
                    foreach (var v in _userManager.PasswordValidators)
                    {
                        errors.AddRange((await v.ValidateAsync(_userManager, user, userToEdit.NewPassword)).Errors);
                    }
                    if (errors.Any())
                    {
                        return(new ApiResponse <EditUserVM>(StatusCodeType.Status401Unauthorized, "New Password is Invalid", errors.ToLookup(userToEdit.GetPropertyNames().Append("Password")).RenameKey("Password", nameof(userToEdit.NewPassword))));
                    }

                    user.PasswordHash = _passwordHasher.HashPassword(user, userToEdit.NewPassword); // use db directly to override identity validation because we want to be able to provide password  for a null hash if user didn't set password before
                    userToEdit.Ticket = await GenerateLoginTicketAsync(userToEdit.Id, user.PasswordHash, authUser.RememberMe);

                    await _db.SaveChangesAsync();
                }

                if (isConfirmationRequired)
                {
                    user.EmailConfirmed = false;
                    await _db.SaveChangesAsync();

                    var resendConfirmationResult = await ResendEmailConfirmationAsync(_mapper.Map(userToEdit, new ResendEmailConfirmationUserVM()));

                    if (resendConfirmationResult.IsError)
                    {
                        return(new ApiResponse <EditUserVM>(StatusCodeType.Status400BadRequest, "User Details have been Updated buy system can't resend Confirmation Email. Please try again later.", null));
                    }

                    userToEdit.ReturnUrl = $"{ConfigUtils.FrontendBaseUrl}/Account/ConfirmEmail?email={user.Email}";
                    await _signInManager.SignOutAsync();

                    return(new ApiResponse <EditUserVM>(StatusCodeType.Status202Accepted, $"Successfully updated User \"{userToEdit.UserName}\", since you have updated your email address the confirmation code has been sent to: \"{userToEdit.Email}\"", null, userToEdit));
                }

                await _signInManager.SignInAsync(user, true);

                return(new ApiResponse <EditUserVM>(StatusCodeType.Status202Accepted, $"Successfully updated User \"{userToEdit.UserName}\"", null, userToEdit));
            }
            catch (Exception ex)
            {
                return(new ApiResponse <EditUserVM>(StatusCodeType.Status500InternalServerError, "Editing User Failed", null, null, ex));
            }
        }
Exemple #16
0
        public async Task <ApiResponse <AuthenticateUserVM> > GetAuthenticatedUserAsync(HttpContext http, ClaimsPrincipal principal, AuthenticateUserVM userToAuthenticate)
        {
            try
            {
                userToAuthenticate.IsAuthenticated = false;
                var contextPrincipal = http != null ? (await http.AuthenticateAsync(IdentityConstants.ApplicationScheme))?.Principal : null;
                var principals       = new[] { principal, contextPrincipal };
                var claimsPrincipal  = principals.FirstOrDefault(p => p?.Identity?.Name != null && p.Identity.IsAuthenticated);

                if (userToAuthenticate.Ticket.IsNullOrWhiteSpace())
                {
                    await _signInManager.SignOutAsync();

                    return(new ApiResponse <AuthenticateUserVM>(StatusCodeType.Status200OK, "User is not Authenticated", null, userToAuthenticate));
                }

                var key             = (await _db.CryptographyKeys.SingleOrDefaultAsync(k => k.Name == "LoginTicket"))?.Value?.Base64SafeUrlToByteArray();
                var decryptedTicket = userToAuthenticate.Ticket.Base64SafeUrlToByteArray().DecryptCamellia(key).ToBase64SafeUrlString().Base64SafeUrlToUTF8().Split("|");
                var timeStamp       = Convert.ToInt64(decryptedTicket[0]).UnixTimeStampToDateTime();
                var id           = decryptedTicket[1];
                var passwordHash = decryptedTicket[2].IsNullOrWhiteSpace() ? null : decryptedTicket[2]; // we need to nullify the empty string that comes from a decrypted ticket because otherwise we would get passwordHash ("") == user.PasswordHash (null) = false
                var rememberMe   = Convert.ToBoolean(Convert.ToInt32(decryptedTicket[3]));

                User user = null;
                if (claimsPrincipal?.Identity?.Name != null)
                {
                    user = await _userManager.FindByNameAsync(claimsPrincipal.Identity.Name);
                }
                if (user == null)
                {
                    user = await _userManager.FindByIdAsync(id);

                    if (user == null || !id.EqualsInvariant(user.Id.ToString()) || !passwordHash.EqualsInvariant(user.PasswordHash) || DateTimeOffset.UtcNow - timeStamp >= TimeSpan.FromDays(365))
                    {
                        await _signInManager.SignOutAsync();

                        return(new ApiResponse <AuthenticateUserVM>(StatusCodeType.Status200OK, "User is not Authenticated", null, userToAuthenticate));
                    }

                    await _signInManager.SignInAsync(user, true);
                }

                _mapper.Map(user, userToAuthenticate);
                userToAuthenticate.RememberMe      = rememberMe;
                userToAuthenticate.HasPassword     = user.PasswordHash != null;
                userToAuthenticate.IsAuthenticated = true;
                userToAuthenticate.Roles           = (await _userManager.GetRolesAsync(user)).Select(r => new FindRoleVM {
                    Name = r
                }).ToList();
                userToAuthenticate.Claims = (await _userManager.GetClaimsAsync(user)).Select(c => new FindClaimVM {
                    Name = c.Type
                }).Where(c => !c.Name.EqualsIgnoreCase("Email")).ToList();
                return(new ApiResponse <AuthenticateUserVM>(StatusCodeType.Status200OK, "Getting Authenticated User was Successful", null, userToAuthenticate));
            }
            catch
            {
                return(new ApiResponse <AuthenticateUserVM>(StatusCodeType.Status500InternalServerError, "Getting Authenticated User Failed", null));
            }
        }