public async Task <IActionResult> ExternalLogin([FromBody] Core.CSharp.Models.ExternalLoginInfo externalLoginInfo)
        {
            try
            {
                if (!TryValidateModel(externalLoginInfo))
                {
                    AppFunc.ExtractErrors(ModelState, ref ErrorsList);
                    return(UnprocessableEntity(ErrorsList));
                }

                User returnedUser = new User();
                switch (externalLoginInfo.Type)
                {
                case CoreConst.RegistrationTypes.Google:
                    returnedUser = await GetGoogleUserInfo(externalLoginInfo).ConfigureAwait(false);

                    break;

                case CoreConst.RegistrationTypes.Facebook:
                    returnedUser = await GetFacebookUserInfo(externalLoginInfo).ConfigureAwait(false);

                    break;

                case CoreConst.RegistrationTypes.Github:
                    returnedUser = await GetGithubUserInfo(externalLoginInfo).ConfigureAwait(false);

                    break;
                }

                // Try to retrieve the user information from App database
                User newUser = await _DbContext.Users
                               .Include(u => u.Role)
                               .Include(u => u.RegistrationMethod)
                               .SingleOrDefaultAsync(u => u.RegistrationMethod.Type == externalLoginInfo.Type && u.RegistrationMethod.ExternalLinkedId == returnedUser.RegistrationMethod.ExternalLinkedId)
                               .ConfigureAwait(false);

                // if the user is already registered
                if (newUser != null)
                {
                    // sign the user in without any password
                    await _AuthManager.SignInAsync(newUser, externalLoginInfo.RememberMe).ConfigureAwait(false);

                    var test = User;
                    return(Ok(newUser));
                }

                // else if the user is not registered
                // else return 206 partial content
                return(StatusCode(206, returnedUser));
            }
            catch (Exception ee)
            {
                AppFunc.Error(ref ErrorsList, AppConst.CommonErrors.ServerError);
                return(StatusCode(417, ErrorsList));
            }
        }
Exemple #2
0
        // [Authorize(AppConst.AccessPolicies.Secret)]  /// Done
        public async Task <IActionResult> Post([FromBody] Role newRole)
        {
            try
            {
                int langId = AppFunc.GetLanguageId();
                /// if model validation failed
                if (!TryValidateModel(newRole))
                {
                    AppFunc.ExtractErrors(ModelState, ref ErrorsList);
                    /// return Unprocessable Entity with all the errors
                    return(UnprocessableEntity(ErrorsList));
                }



                /// check the database to see if a role with the same name exists
                if (await AppDbContext.Roles.Include(r => r.RoleTranslates).Select(p => new Role
                {
                    Name = p.RoleTranslates.FirstOrDefault(e => e.LangId == langId).Name,
                    AccessClaim = p.AccessClaim,
                    Id = p.Id
                }).AnyAsync(d => d.Name.Equals(newRole.Name) && d.AccessClaim.Equals(newRole.AccessClaim)).ConfigureAwait(false))
                {
                    /// extract the errors and return bad request containing the errors
                    AppFunc.Error(ref ErrorsList, _localizer["Role already exists."].Value);
                    return(StatusCode(412, ErrorsList));
                }
                foreach (string lang in AppConst.SupportLanguages)
                {
                    newRole.RoleTranslates.Add(new RoleTranslate()
                    {
                        LangId = AppFunc.GetLanguageId(lang), Name = newRole.Name
                    });
                }
                /// else role object is made without any errors
                /// Add the new role to the EF context
                await AppDbContext.Roles.AddAsync(newRole).ConfigureAwait(false);

                /// save the changes to the data base
                await AppDbContext.SaveChangesAsync().ConfigureAwait(false);

                /// return 201 created status with the new object
                /// and success message
                return(Created(_localizer["Success"].Value, newRole));
            }
            catch (Exception) // DbUpdateException, DbUpdateConcurrencyException
            {
                /// Add the error below to the error list and return bad request
                AppFunc.Error(ref ErrorsList, AppConst.CommonErrors.ServerError);
                return(StatusCode(417, ErrorsList));
            }
        }
Exemple #3
0
        //[Authorize(AppConst.AccessPolicies.Secret)]  /// First Level Test Pass
        public async Task <IActionResult> Put([FromBody] User modifiedUser)
        {
            try
            {
                int langId = AppFunc.GetLanguageId();
                /// Try to validate the model
                TryValidateModel(modifiedUser);
                /// remove the passwordHash and confrimPassword since
                /// the password update gets handled by another method in this class
                ModelState.Remove("PasswordHash");
                if (!ModelState.IsValid)
                {
                    /// extract the errors and return bad request containing the errors
                    AppFunc.ExtractErrors(ModelState, ref ErrorsList);
                    return(UnprocessableEntity(ErrorsList));
                }
                /// if the user record with the same id is not found
                if (!AppDbContext.Users.Any(u => u.Id == modifiedUser.Id))
                {
                    AppFunc.Error(ref ErrorsList, _localizer["User not found."].Value);
                    return(StatusCode(412, ErrorsList));
                }
                /// find the current user details from the database
                User userDetails = AppDbContext.Users.Find(modifiedUser.Id);
                userDetails.UserTranslates = await AppDbContext.UserTranslate.AsTracking().Where(ut => ut.User.Id == userDetails.Id)
                                             .ToListAsync().ConfigureAwait(false);

                UserTranslate userTranslate = userDetails.UserTranslates.SingleOrDefault(ut => ut.LangId == langId);

                /// update the user details with the new details
                userTranslate.FirstName = modifiedUser.FirstName;
                userTranslate.Surname   = modifiedUser.Surname;
                userDetails.Email       = modifiedUser.Email;
                userDetails.PhoneNumber = modifiedUser.PhoneNumber;
                userDetails.Role        = modifiedUser.Role;
                /// thus update user in the context
                AppDbContext.Users.Update(userDetails);
                /// save the changes to the database
                await AppDbContext.SaveChangesAsync().ConfigureAwait(false);

                /// thus return 200 ok status with the updated object
                return(Ok(userDetails));
            }
            catch (Exception) // DbUpdateException, DbUpdateConcurrencyException
            {
                /// Add the error below to the error list and return bad request
                AppFunc.Error(ref ErrorsList, AppConst.CommonErrors.ServerError);
                return(StatusCode(417, ErrorsList));
            }
        }
Exemple #4
0
        // [Authorize(AppConst.AccessPolicies.Secret)]  /// Done
        public async Task <IActionResult> Put([FromBody] Role modifiedRole)
        {
            try
            {
                int langId = AppFunc.GetLanguageId();
                /// if model validation failed
                if (!TryValidateModel(modifiedRole))
                {
                    AppFunc.ExtractErrors(ModelState, ref ErrorsList);
                    /// return Unprocessable Entity with all the errors
                    return(UnprocessableEntity(ErrorsList));
                }

                /// check the database to see if a Category with the same name exists
                if (await AppDbContext.Roles.Include(r => r.RoleTranslates).Select(p => new Role
                {
                    Name = p.RoleTranslates.FirstOrDefault(e => e.LangId == langId).Name,
                    AccessClaim = p.AccessClaim,
                    Id = p.Id
                }).AnyAsync(d => d.Name == modifiedRole.Name &&
                            d.AccessClaim.Equals(modifiedRole.AccessClaim) &&
                            d.Id != modifiedRole.Id).ConfigureAwait(false))
                {
                    /// extract the errors and return bad request containing the errors
                    AppFunc.Error(ref ErrorsList, _localizer["Role already exists."].Value);
                    return(StatusCode(412, ErrorsList));
                }
                modifiedRole.RoleTranslates = await AppDbContext.RolesTranslate
                                              .Where(rt => rt.Role.Id == modifiedRole.Id).ToListAsync().ConfigureAwait(false);

                modifiedRole.RoleTranslates.SingleOrDefault(rt => rt.LangId == langId).Name = modifiedRole.Name;
                /// else Role object is made without any errors
                /// Update the current Role on EF context
                AppDbContext.Roles.Update(modifiedRole);

                /// save the changes to the data base
                await AppDbContext.SaveChangesAsync().ConfigureAwait(false);

                /// return 200 OK (Update) status with the modified object
                /// and success message
                return(Ok(modifiedRole));
            }
            catch (Exception) // DbUpdateException, DbUpdateConcurrencyException
            {
                /// Add the error below to the error list and return bad request
                AppFunc.Error(ref ErrorsList, AppConst.CommonErrors.ServerError);
                return(StatusCode(417, ErrorsList));
            }
        }
Exemple #5
0
        [HttpPut("PutMyPassword/{currentPassword}/{password}")] /// Ready For Test
        public async Task <IActionResult> PutMyPassword(string currentPassword, string password)
        {
            try
            {
                int.TryParse(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value, out int userId);
                User user = AppDbContext.Users.Find(userId);

                IdentityResult result = await _UserManager.ChangePasswordAsync(user, currentPassword, password);

                if (!result.Succeeded)
                {
                    AppFunc.ExtractErrors(result.Errors, ref ErrorsList);
                    return(StatusCode(412, ErrorsList));
                }
                return(Ok(result));
            }
            catch (Exception) // DbUpdateException, DbUpdateConcurrencyException
            {
                /// Add the error below to the error list and return bad request
                AppFunc.Error(ref ErrorsList, AppConst.CommonErrors.ServerError);
                return(StatusCode(417, ErrorsList));
            }
        }
Exemple #6
0
        /// <summary>
        ///     Create a new User
        /// </summary>
        private async Task <IActionResult> CreateUser(User newUser)
        {
            try
            {
                newUser.PasswordHash = newUser.TempPassword;
                if (newUser.RegistrationMethod.Type != CoreConst.RegistrationTypes.Application)
                {
                    newUser.PasswordHash = CoreFunc.PasswordGenerator(20, 5, 5, 5, 5);
                }
                ModelState.Clear();
                /// if model validation failed
                if (!TryValidateModel(newUser))
                {
                    AppFunc.ExtractErrors(ModelState, ref ErrorsList);
                    /// return bad request with all the errors
                    return(UnprocessableEntity(ErrorsList));
                }
                /// check the database to see if a user with the same email exists
                if (_DbContext.Users.Any(d => d.Email == newUser.Email))
                {
                    /// extract the errors and return bad request containing the errors
                    AppFunc.Error(ref ErrorsList, "Email already exists.");
                    return(StatusCode(412, ErrorsList));
                }
                /// Create the new user
                IdentityResult newUserResult = await _UserManager.CreateAsync(newUser, newUser.PasswordHash)
                                               .ConfigureAwait(false);

                /// If result failed
                if (!newUserResult.Succeeded)
                {
                    /// Add the error below to the error list and return bad request
                    foreach (var error in newUserResult.Errors)
                    {
                        AppFunc.Error(ref ErrorsList, error.Description, error.Code);
                    }
                    return(StatusCode(417, ErrorsList));
                }
                /// else result is successful the try to add the access claim for the user
                IdentityResult addedClaimResult = await _UserManager.AddClaimAsync(
                    newUser,
                    new Claim(AppConst.AccessClaims.Type, newUser.Role.AccessClaim)
                    ).ConfigureAwait(false);

                /// if claim failed to be created
                if (!addedClaimResult.Succeeded)
                {
                    /// remove the user account and return appropriate error
                    _DbContext.Users.Remove(newUser);
                    await _DbContext.SaveChangesAsync().ConfigureAwait(false);

                    AppFunc.Error(ref ErrorsList, AppConst.CommonErrors.ServerError);
                    return(StatusCode(417, ErrorsList));
                }

                isUserCreated = true;
                /// return 201 created status with the new object
                /// and success message
                return(Created("Success", newUser));
            }
            catch (Exception ee) // DbUpdateException, DbUpdateConcurrencyException
            {
                /// Add the error below to the error list and return bad request
                AppFunc.Error(ref ErrorsList, AppConst.CommonErrors.ServerError);
                return(StatusCode(417, ErrorsList));
            }
        }
        public async Task <IActionResult> LoginAsync([FromBody] LoginInfo loginInfo)
        {
            try
            {
                ///// If email parameter is empty
                ///// return "unauthorized" response (stop code execution)
                //if (string.IsNullOrWhiteSpace(loginInfo.UserName))
                //   /// in the case any exceptions return the following error
                //   AppFunc.Error(ref ErrorsList, "UserName is required!", "UserName");
                //if (string.IsNullOrWhiteSpace(loginInfo.Password))
                //   AppFunc.Error(ref ErrorsList, "Password is required!", "Password");
                //if (ErrorsList.Count > 0)
                //   return BadRequest(ErrorsList);

                /// if model validation failed
                if (!TryValidateModel(loginInfo))
                {
                    AppFunc.ExtractErrors(ModelState, ref ErrorsList);
                    /// return Unprocessable Entity with all the errors
                    return(UnprocessableEntity(ErrorsList));
                }
                /// Find the user with the provided email address
                User user = await _UserManager
                            .FindByNameAsync(loginInfo.UserName).ConfigureAwait(false);

                /// if no user is found on the database
                // return "unauthorized" response (stop code execution)
                if (user == null)
                {
                    /// in the case any exceptions return the following error
                    AppFunc.Error(ref ErrorsList, "UserName not registered", "UserName");
                    return(BadRequest(ErrorsList));
                }

                /// Check if user's account is locked
                if (user.LockoutEnabled)
                {
                    /// get the current lockout end dateTime
                    var currentLockoutDate =
                        await _UserManager.GetLockoutEndDateAsync(user).ConfigureAwait(false);

                    /// if the user's lockout is not expired (stop code execution)
                    if (user.LockoutEnd > DateTimeOffset.UtcNow)
                    {
                        /// in the case any exceptions return the following error
                        AppFunc.Error(ref ErrorsList, string.Format("Account Locked for {0}"
                                                                    , AppFunc.CompareWithCurrentTime(user.LockoutEnd)));
                        return(BadRequest(ErrorsList));
                    }
                    /// else lockout time has expired
                    // disable user lockout
                    await _UserManager.SetLockoutEnabledAsync(user, false).ConfigureAwait(false);

                    await _UserManager.ResetAccessFailedCountAsync(user).ConfigureAwait(false);
                }

                /// else user account is not locked
                // Attempt to sign in the user
                var SignInResult = await _SignInManager
                                   .PasswordSignInAsync(user,
                                                        loginInfo.Password,
                                                        loginInfo.RememberMe,
                                                        false).ConfigureAwait(false);

                /// If password sign-in succeeds
                // responded ok 200 status code with
                //the user's role attached (stop code execution)
                if (!SignInResult.Succeeded)
                {
                    /// else login attempt failed
                    /// increase and update the user's failed login attempt by 1
                    await _UserManager.AccessFailedAsync(user).ConfigureAwait(false);

                    /// if failed login attempt is less than/ equal to 5 (stop code execution)
                    if (user.AccessFailedCount <= 5)
                    {
                        /// in the case any exceptions return the following error
                        AppFunc.Error(ref ErrorsList, "Incorrect Password!", "password");
                        return(Unauthorized(ErrorsList));
                    }

                    /// else user has tried their password more than 15 times
                    // lock the user and ask them to reset their password
                    user.LockoutEnabled = true;
                    user.LockoutEnd     = DateTimeOffset.UtcNow.AddMinutes(user.AccessFailedCount);

                    /// in the case any exceptions return the following error
                    AppFunc.Error(ref ErrorsList, string.Format("Account Locked for {0}"
                                                                , AppFunc.CompareWithCurrentTime(user.LockoutEnd)));
                    return(Unauthorized(ErrorsList));
                }
                user.Role = (await AppDbContext.Users.Include(u => u.Role)
                             .FirstOrDefaultAsync(u => u.Id == user.Id)
                             .ConfigureAwait(false))
                            ?.Role;
                return(Ok(user));
            }
            catch (Exception)
            {
                /// Add the error below to the error list and return bad request
                AppFunc.Error(ref ErrorsList, AppConst.CommonErrors.ServerError);
                return(StatusCode(417, ErrorsList));
            }
        }
Exemple #8
0
        /// <summary>
        ///     Create a new User
        /// </summary>
        private async Task <IActionResult> CreateUser(User newUser)
        {
            try
            {
                newUser.PasswordHash = newUser.TempPassword;
                newUser.TempPassword = string.Empty;
                ModelState.Clear();
                TryValidateModel(newUser);
                ModelState.Remove("Role.Name");
                /// if model validation failed
                if (!ModelState.IsValid)
                {
                    AppFunc.ExtractErrors(ModelState, ref ErrorsList);
                    /// return bad request with all the errors
                    return(UnprocessableEntity(ErrorsList));
                }
                /// check the database to see if a user with the same email exists
                if (AppDbContext.Users.AsNoTracking().Any(d => d.UserName == newUser.UserName))
                {
                    /// extract the errors and return bad request containing the errors
                    AppFunc.Error(ref ErrorsList, _localizer["UserName already exists."].Value, "UserName");
                    return(StatusCode(412, ErrorsList));
                }
                /// Create the new user
                IdentityResult newUserResult = await _UserManager.CreateAsync(newUser, newUser.PasswordHash)
                                               .ConfigureAwait(false);

                /// If result failed
                if (!newUserResult.Succeeded)
                {
                    /// Add the error below to the error list and return bad request
                    foreach (var error in newUserResult.Errors)
                    {
                        AppFunc.Error(ref ErrorsList, error.Description, error.Code);
                    }
                    return(StatusCode(417, ErrorsList));
                }
                /// else result is successful the try to add the access claim for the user
                IdentityResult addedClaimResult = await _UserManager.AddClaimAsync(
                    newUser,
                    new Claim(AppConst.AccessClaimType, newUser.Role.AccessClaim)
                    ).ConfigureAwait(false);

                /// if claim failed to be created
                if (!addedClaimResult.Succeeded)
                {
                    /// remove the user account and return appropriate error
                    AppDbContext.Users.Remove(newUser);
                    await AppDbContext.SaveChangesAsync().ConfigureAwait(false);

                    AppFunc.Error(ref ErrorsList, AppConst.CommonErrors.ServerError);
                    return(StatusCode(417, ErrorsList));
                }
                foreach (string lang in AppConst.SupportLanguages)
                {
                    await AppDbContext.UserTranslate.AddAsync(new UserTranslate()
                    {
                        LangId    = AppFunc.GetLanguageId(lang),
                        User      = newUser,
                        FirstName = newUser.FirstName,
                        Surname   = newUser.Surname
                    });
                }
                /// save the changes to the data base
                await AppDbContext.SaveChangesAsync().ConfigureAwait(false);

                isUserCreated = true;
                /// return 201 created status with the new object
                /// and success message
                return(Created(_localizer["Success"].Value, newUser));
            }
            catch (Exception) // DbUpdateException, DbUpdateConcurrencyException
            {
                /// Add the error below to the error list and return bad request
                AppFunc.Error(ref ErrorsList, AppConst.CommonErrors.ServerError);
                return(StatusCode(417, ErrorsList));
            }
        }