Example #1
0
 public ApplicationDbContext() : base("DefaultConnection")
 {
     Configuration.AutoDetectChangesEnabled = true;
     Configuration.LazyLoadingEnabled       = false;
     Configuration.ProxyCreationEnabled     = false;
     LastSaveChangesResult = new SaveChangesResult();
 }
Example #2
0
        /// <summary>
        /// Sets two factor enabled of logged in account to <paramref name="enabled"/>.
        /// </summary>
        /// <param name="enabled"></param>
        /// <returns>
        /// <see cref="SetTwoFactorEnabledActionResult.Success"/> if two factor enabled change succeeds.
        /// <see cref="SetTwoFactorEnabledActionResult.AlreadySet"/> if account two factor enabled is already equal to
        /// <paramref name="enabled"/>.
        /// <see cref="SetTwoFactorEnabledActionResult.NoLoggedInAccount"/> if unable to retrieve logged in account.
        /// <see cref="SetTwoFactorEnabledActionResult.EmailUnverified"/> if account email is unverified.
        /// </returns>
        /// <exception cref="Exception">Thrown if database update fails unexpectedly.</exception>
        public virtual async Task <SetTwoFactorEnabledActionResult> SetTwoFactorEnabledActionAsync(bool enabled)
        {
            TAccount account = await GetApplicationAccountAsync();

            if (account == null)
            {
                return(SetTwoFactorEnabledActionResult.NoLoggedInAccount);
            }
            if (!account.EmailVerified)
            {
                await SendTwoFactorCodeEmailAsync(account);

                return(SetTwoFactorEnabledActionResult.EmailUnverified);
            }
            if (account.TwoFactorEnabled == enabled)
            {
                return(SetTwoFactorEnabledActionResult.AlreadySet);
            }

            SaveChangesResult result = await _accountRepository.UpdateTwoFactorEnabledAsync(account,
                                                                                            enabled,
                                                                                            _cancellationToken);

            if (result == SaveChangesResult.ConcurrencyError)
            {
                // Unrecoverable
                throw new Exception();
            }

            return(SetTwoFactorEnabledActionResult.Success);
        }
 protected EntityFrameworkContextBase() : base("DefaultConnection")
 {
     Configuration.AutoDetectChangesEnabled = true;
     Configuration.LazyLoadingEnabled       = false;
     Configuration.ProxyCreationEnabled     = false;
     Configuration.ValidateOnSaveEnabled    = false;
     _lastOPerationResult = new SaveChangesResult();
 }
        public override async Task <int> SaveChangesAsync(
            IReadOnlyList <IUpdateEntry> entries,
            CancellationToken cancellationToken = default)
        {
            SaveChangesResult result = await this.infoCarrierClient.SaveChangesAsync(new SaveChangesRequest(entries), cancellationToken);

            return(result.ApplyTo(entries));
        }
Example #5
0
        protected DbContextBase(string defaultConnection) : base(defaultConnection)
        {
            Configuration.ProxyCreationEnabled     = false;
            Configuration.AutoDetectChangesEnabled = true;
            Configuration.LazyLoadingEnabled       = false;
            Configuration.ValidateOnSaveEnabled    = false;

            _lastOPerationResult = new SaveChangesResult();
        }
 /// <summary>
 ///     Asynchronously saves the updated entities into the actual database.
 /// </summary>
 /// <param name="cancellationToken">
 ///     A <see cref="CancellationToken" /> to observe while waiting for the task to
 ///     complete.
 /// </param>
 /// <returns>
 ///     A task that represents the asynchronous operation.
 ///     The task result contains the save operation result which can either be
 ///     a SaveChangesResult.Success or SaveChangesResult.Error.
 /// </returns>
 public async Task <SaveChangesResult> SaveChangesAsync(CancellationToken cancellationToken = default)
 {
     try
     {
         return(SaveChangesResult.Success(await this.dbContext.SaveChangesAsync(cancellationToken), this.Entries));
     }
     catch (DbUpdateException e)
     {
         return(SaveChangesResult.Error(e, this.Entries));
     }
 }
 /// <summary>
 ///     Saves the updated entities into the actual database.
 /// </summary>
 /// <returns>
 ///     The save operation result which can either be
 ///     a SaveChangesResult.Success or SaveChangesResult.Error.
 /// </returns>
 public SaveChangesResult SaveChanges()
 {
     try
     {
         return(SaveChangesResult.Success(this.dbContext.SaveChanges(), this.Entries));
     }
     catch (DbUpdateException e)
     {
         return(SaveChangesResult.Error(e, this.Entries));
     }
 }
Example #8
0
 public SaveChangesResult Commit()
 {
     try
     {
         _context.SaveChanges();
         return(SaveChangesResult.Success());
     }
     catch (Exception)
     {
         return(SaveChangesResult.Failed());
     }
 }
Example #9
0
        /// <summary>
        /// Resets password for account with email <paramref name="email"/>.
        /// </summary>
        /// <param name="email"></param>
        /// <param name="token"></param>
        /// <param name="newPassword"></param>
        /// <returns>
        /// <see cref="ResetPasswordActionResult.InvalidEmail"/> if email is invalid.
        /// <see cref="ResetPasswordActionResult.InvalidNewPassword"/> if new password is same as old password.
        /// <see cref="ResetPasswordActionResult.InvalidToken"/> if token is invalid.
        /// <see cref="ResetPasswordActionResult.Success"/> if password reset is successful.
        /// </returns>
        /// <exception cref="Exception">Thrown if a database error occurs.</exception>
        public virtual async Task <ResetPasswordActionResult> ResetPasswordActionAsync(string email, string token,
                                                                                       string newPassword)
        {
            if (string.IsNullOrEmpty(email))
            {
                throw new ArgumentException(nameof(email));
            }
            if (string.IsNullOrEmpty(token))
            {
                throw new ArgumentException(nameof(token));
            }
            if (string.IsNullOrEmpty(newPassword))
            {
                throw new ArgumentException(nameof(newPassword));
            }

            TAccount account = await _accountRepository.GetAsync(email, _cancellationToken);

            if (account == null)
            {
                return(ResetPasswordActionResult.InvalidEmail);
            }

            if (_passwordService.ValidatePassword(account.PasswordHash, newPassword))
            {
                return(ResetPasswordActionResult.InvalidNewPassword);
            }

            ValidateTokenResult validateTokenResult = ValidateToken(TokenServiceOptions.DataProtectionTokenService,
                                                                    _options.ResetPasswordTokenPurpose,
                                                                    account,
                                                                    token);

            if (validateTokenResult != ValidateTokenResult.Valid)
            {
                return(ResetPasswordActionResult.InvalidToken);
            }

            SaveChangesResult result = await _accountRepository.UpdatePasswordHashAsync(account,
                                                                                        _passwordService.HashPassword(newPassword),
                                                                                        _cancellationToken);

            if (result == SaveChangesResult.ConcurrencyError)
            {
                // Unrecoverable by calling function.
                throw new Exception();
            }

            return(ResetPasswordActionResult.Success);
        }
Example #10
0
        public void DeleteCustomer_CustomerIsValid_CustomerRepositoryDeleteCustomerIsCalled()
        {
            Customer          customer = new Customer();
            SaveChangesResult result   = new SaveChangesResult()
            {
                Value = SaveChangesResult.Result.Abort
            };

            _customerRepositoryMock.Setup(repository => repository.DeleteCustomer(customer)).Returns(result);

            _sut.DeleteCustomer(customer);

            //Assert
            _customerRepositoryMock.Verify(repository => repository.DeleteCustomer(customer), Times.Once);
        }
Example #11
0
        public void DeleteCustomer_CustomerIsValid_CustomerRepositoryDeleteCustomerReturnsOk_ViewClearControlsIsCalled()
        {
            Customer          customer = new Customer();
            SaveChangesResult result   = new SaveChangesResult()
            {
                Value = SaveChangesResult.Result.Ok
            };

            _customerRepositoryMock.Setup(repository => repository.DeleteCustomer(customer)).Returns(result);

            _sut.DeleteCustomer(customer);

            //Assert
            _viewMock.Verify(view => view.ClearControls(), Times.Once);
        }
Example #12
0
        /// <summary>
        /// Sets email of logged in account to <paramref name="newEmail"/>.
        /// </summary>
        /// <param name="password"></param>
        /// <param name="newEmail"></param>
        /// <returns>
        /// <see cref="SetEmailActionResult.Success"/> if email change succeeds.
        /// <see cref="SetEmailActionResult.AlreadySet"/> if account email is already equal to
        /// <paramref name="newEmail"/>.
        /// <see cref="SetEmailActionResult.InvalidPassword"/> if <paramref name="password"/> is invalid.
        /// <see cref="SetEmailActionResult.NoLoggedInAccount"/> if unable to retrieve logged in account.
        /// <see cref="SetEmailActionResult.EmailInUse"/> if <paramref name="newEmail"/> is in use.
        /// </returns>
        /// <exception cref="Exception">Thrown if database update fails unexpectedly.</exception>
        public virtual async Task <SetEmailActionResult> SetEmailActionAsync(string password, string newEmail)
        {
            if (string.IsNullOrEmpty(password))
            {
                throw new ArgumentException(nameof(password));
            }
            if (string.IsNullOrEmpty(newEmail))
            {
                throw new ArgumentException(nameof(newEmail));
            }

            TAccount account = await GetApplicationAccountAsync();

            if (account == null)
            {
                return(SetEmailActionResult.NoLoggedInAccount);
            }
            if (account.Email == newEmail)
            {
                return(SetEmailActionResult.AlreadySet);
            }
            if (_passwordService.ValidatePassword(account.PasswordHash, password))
            {
                SaveChangesResult result = await _accountRepository.UpdateEmailAsync(account,
                                                                                     newEmail,
                                                                                     _cancellationToken);

                if (result == SaveChangesResult.ConcurrencyError)
                {
                    // Unrecoverable
                    throw new Exception();
                }
                if (result == SaveChangesResult.UniqueIndexViolation)
                {
                    return(SetEmailActionResult.EmailInUse);
                }

                // Security stamp has changed
                await RefreshApplicationLogInAsync(account);

                return(SetEmailActionResult.Success);
            }
            else
            {
                return(SetEmailActionResult.InvalidPassword);
            }
        }
Example #13
0
        /// <summary>
        /// Sets email verified and two factor enabled of logged in account to true if <paramref name="code"/> is valid.
        /// </summary>
        /// <param name="code"></param>
        /// <returns>
        /// <see cref="TwoFactorVerifyEmailActionResult.Success"/> if email verified change succeeds.
        /// <see cref="TwoFactorVerifyEmailActionResult.AlreadySet"/> if account email verified is already true.
        /// <see cref="TwoFactorVerifyEmailActionResult.NoLoggedInAccount"/> if unable to retrieve logged in account.
        /// <see cref="TwoFactorVerifyEmailActionResult.InvalidCode"/> if code is invalid.
        /// </returns>
        /// <exception cref="Exception">Thrown if a database update fails unexpectedly.</exception>
        public virtual async Task <TwoFactorVerifyEmailActionResult> TwoFactorVerifyEmailActionAsync(string code)
        {
            if (string.IsNullOrEmpty(code))
            {
                throw new ArgumentException(nameof(code));
            }

            TAccount account = await GetApplicationAccountAsync();

            if (account == null)
            {
                return(TwoFactorVerifyEmailActionResult.NoLoggedInAccount);
            }

            if (account.EmailVerified == true)
            {
                return(TwoFactorVerifyEmailActionResult.AlreadySet);
            }

            ValidateTokenResult validateTokenResult = ValidateToken(TokenServiceOptions.TotpTokenService,
                                                                    _options.TwoFactorTokenPurpose,
                                                                    account,
                                                                    code);

            if (validateTokenResult == ValidateTokenResult.Invalid)
            {
                return(TwoFactorVerifyEmailActionResult.InvalidCode);
            }

            SaveChangesResult result = await _accountRepository.UpdateAsync(account,
                                                                            _cancellationToken,
                                                                            emailVerified : true,
                                                                            twoFactorEnabled : true);

            if (result == SaveChangesResult.ConcurrencyError)
            {
                // Unrecoverable
                throw new Exception();
            }

            return(TwoFactorVerifyEmailActionResult.Success);
        }
Example #14
0
        /// <summary>
        /// Creates a new account.
        /// </summary>
        /// <param name="email"></param>
        /// <param name="passwordHash"></param>
        /// <param name="cancellationToken"></param>
        /// <returns>
        /// New account if account is created successfuly.
        /// Null if email is in use.
        /// </returns>
        public async Task <TAccount> CreateAsync(string email, string passwordHash, CancellationToken cancellationToken)
        {
            TAccount account = new TAccount
            {
                Email               = email,
                PasswordHash        = passwordHash,
                PasswordLastChanged = _timeService.UtcNow,
                SecurityStamp       = Guid.NewGuid()
            };

            await _dbContext.AddAsync(account, cancellationToken);

            SaveChangesResult result = await _dbContext.SaveChangesAndCatchAsync(cancellationToken);

            if (result == SaveChangesResult.UniqueIndexViolation)
            {
                return(null);
            }

            return(account);
        }
Example #15
0
        /// <summary>
        /// Sets alt email verified of logged in account to true if <paramref name="token"/> is valid.
        /// </summary>
        /// <param name="token"></param>
        /// <returns>
        /// <see cref="SetAltEmailVerifiedActionResult.Success"/> if alt email verified change succeeds.
        /// <see cref="SetAltEmailVerifiedActionResult.AlreadySet"/> if account alt email verified is already true.
        /// <see cref="SetAltEmailVerifiedActionResult.NoLoggedInAccount"/> if unable to retrieve logged in account.
        /// <see cref="SetAltEmailVerifiedActionResult.InvalidToken"/> if token is invalid.
        /// </returns>
        /// <exception cref="Exception">Thrown if database update fails unexpectedly.</exception>
        public virtual async Task <SetAltEmailVerifiedActionResult> SetAltEmailVerifiedActionAsync(string token)
        {
            if (string.IsNullOrEmpty(token))
            {
                throw new ArgumentException(nameof(token));
            }

            TAccount account = await GetApplicationAccountAsync();

            if (account == null)
            {
                return(SetAltEmailVerifiedActionResult.NoLoggedInAccount);
            }
            if (account.AltEmailVerified == true)
            {
                return(SetAltEmailVerifiedActionResult.AlreadySet);
            }

            ValidateTokenResult validateTokenResult = ValidateToken(TokenServiceOptions.DataProtectionTokenService,
                                                                    _options.ConfirmAltEmailTokenPurpose,
                                                                    account,
                                                                    token);

            if (validateTokenResult != ValidateTokenResult.Valid)
            {
                return(SetAltEmailVerifiedActionResult.InvalidToken);
            }

            SaveChangesResult result = await _accountRepository.UpdateAltEmailVerifiedAsync(account,
                                                                                            true,
                                                                                            _cancellationToken);

            if (result == SaveChangesResult.ConcurrencyError)
            {
                // Unrecoverable
                throw new Exception();
            }

            return(SetAltEmailVerifiedActionResult.Success);
        }
Example #16
0
        /// <summary>
        /// Last SaveChange operation result
        /// </summary>

        public override int SaveChanges()
        {
            try {
                _lastOPerationResult = new SaveChangesResult();
                var createdSourceInfo  = ChangeTracker.Entries().Where(e => e.State == EntityState.Added);
                var modifiedSourceInfo = ChangeTracker.Entries().Where(e => e.State == EntityState.Modified);

                foreach (var entry in createdSourceInfo)
                {
                    if (entry.Entity.GetType().GetInterfaces().Contains(typeof(IAuditable)))
                    {
                        var creationDate = DateTime.Now;
                        entry.Property("CreatedAt").CurrentValue = creationDate;
                        entry.Property("UpdatedAt").CurrentValue = creationDate;

                        string userName = Thread.CurrentPrincipal.Identity?.Name ?? "Anonymous";
                        //entry.Property("CreatedBy").CurrentValue = userName;
                        entry.Property("UpdatedBy").CurrentValue = userName;


                        _lastOPerationResult.AddMessage($"ChangeTracker has new entities: {entry.Entity.GetType()}");
                    }
                }
                foreach (var entry in modifiedSourceInfo)
                {
                    if (entry.Entity.GetType().GetInterfaces().Contains(typeof(IAuditable)))
                    {
                        entry.Property("UpdatedAt").CurrentValue = DateTime.Now;
                    }
                    _lastOPerationResult.AddMessage($"ChangeTracker has modified entities: {entry.Entity.GetType()}");
                }
                return(base.SaveChanges());
            }
            catch (DbUpdateException exception) {
                _lastOPerationResult.Exception = exception;
                return(0);
            }
        }
        public override int SaveChanges(IReadOnlyList <IUpdateEntry> entries)
        {
            SaveChangesResult result = this.infoCarrierClient.SaveChanges(new SaveChangesRequest(entries));

            return(result.ApplyTo(entries));
        }
Example #18
0
 protected DbContextBase(DbContextOptions options) : base(options)
 {
     LastSaveChangesResult = new SaveChangesResult();
 }
 public SaveChangesResponse(SaveChangesResult result)
 {
     this.ToData(result);
 }