예제 #1
0
        /// <summary>
        ///     Attempts to sign in the specified <paramref name="principal"/>.
        /// </summary>
        /// <param name="principal">The principal to sign in.</param>
        /// <returns>Instance of <see cref="TokenContext"/>.</returns>
        public virtual ValueTask <TokenContext> SignInAsync(ClaimsPrincipal principal)
        {
            if (principal is null)
            {
                throw new ArgumentNullException(nameof(principal));
            }

            var(user, tenant) = PrincipalProvider.GetUserAndTenant <User, Organization>(principal);
            if (user is null || tenant is null)
            {
                throw new AuthenticationException();
            }

            Claim claim = principal.FindFirst(FunderMapsAuthenticationClaimTypes.TenantRole);

            if (claim is null)
            {
                throw new AuthenticationException();
            }

            Logger.LogTrace($"User '{user}' sign in was successful.");

            principal = PrincipalProvider.CreateTenantUserPrincipal(user, tenant,
                                                                    Enum.Parse <OrganizationRole>(claim.Value),
                                                                    JwtBearerDefaults.AuthenticationScheme);
            return(new(TokenProvider.GetTokenContext(principal)));
        }
예제 #2
0
        /// <summary>
        ///     Attempts to sign in the specified <paramref name="email"/> and <paramref name="password"/> combination.
        /// </summary>
        /// <param name="email">The user email to sign in.</param>
        /// <param name="password">The password to attempt to authenticate.</param>
        /// <returns>Instance of <see cref="TokenContext"/>.</returns>
        public virtual async Task <TokenContext> PasswordSignInAsync(string email, string password)
        {
            if (await UserRepository.GetByEmailAsync(email) is not IUser user)
            {
                throw new AuthenticationException();
            }

            // FUTURE: Single call?
            var organizationId = await OrganizationUserRepository.GetOrganizationByUserIdAsync(user.Id);

            if (await CheckPasswordAsync(user.Id, password))
            {
                if (await UserRepository.GetAccessFailedCount(user.Id) > 10)
                {
                    Logger.LogWarning($"User '{user}' locked out.");

                    throw new AuthenticationException();
                }

                await UserRepository.ResetAccessFailed(user.Id);

                await UserRepository.RegisterAccess(user.Id);

                Logger.LogInformation($"User '{user}' password sign in was successful.");

                Organization organization = await OrganizationRepository.GetByIdAsync(organizationId);

                OrganizationRole organizationRole = await OrganizationUserRepository.GetOrganizationRoleByUserIdAsync(user.Id);

                ClaimsPrincipal principal = PrincipalProvider.CreateTenantUserPrincipal(user, organization,
                                                                                        organizationRole,
                                                                                        JwtBearerDefaults.AuthenticationScheme);
                return(TokenProvider.GetTokenContext(principal));
            }

            Logger.LogWarning($"User '{user}' failed to provide the correct password.");

            await UserRepository.BumpAccessFailed(user.Id);

            throw new AuthenticationException();
        }