public async Task <IActionResult> PasswordLoginAsync([FromServices] ILoginRateLimiter loginRateLimiter, string username, string password, string referer)
    {
        var passwordHasher = new PasswordHasher <User>();

        // Already logged in?
        var currentUser = await GetCurrentUserAsync();

        if (currentUser != null)
        {
            return(await ShowRedirectAsync(referer));
        }

        // Find user
        bool success = false;
        var  user    = await _userService.FindUserByMoodleNameAsync(username, HttpContext.RequestAborted);

        if (user != null)
        {
            // Check rate limit
            if (loginRateLimiter.CheckRateLimitHit(user.Id))
            {
                AddStatusMessage(_localizer["PasswordLoginAsync:RateLimited"], StatusMessageTypes.Error);
                ViewData["LoginFormUsername"] = username;
                ViewData["Referer"]           = referer;
                return(await RenderAsync(ViewType.Login));
            }

            // Check password
            var verificationResult = passwordHasher.VerifyHashedPassword(user, user.PasswordHash, password);
            if (verificationResult == PasswordVerificationResult.Success)
            {
                success = true;
            }
            else if (verificationResult == PasswordVerificationResult.SuccessRehashNeeded)
            {
                // Update password hash
                user.PasswordHash = passwordHasher.HashPassword(user, password);
                await _userService.UpdateUserAsync(user, CancellationToken.None);

                success = true;
            }
        }

        // Return to login form, if the login attempt failed
        if (!success)
        {
            AddStatusMessage(_localizer["PasswordLoginAsync:WrongPassword"], StatusMessageTypes.Error);
            ViewData["LoginFormUsername"] = username;
            ViewData["Referer"]           = referer;
            return(await RenderAsync(ViewType.Login));
        }

        // Sign in user
        await DoLoginAsync(user);

        // Reset rate limit
        loginRateLimiter.ResetRateLimit(user.Id);

        // Done
        AddStatusMessage(_localizer["PasswordLoginAsync:Success"], StatusMessageTypes.Success);
        return(await ShowRedirectAsync(referer));
    }
Example #2
0
    public async Task <IActionResult> LoginMoodleAsync([FromServices] IOptions <MoodleLtiOptions> moodleLtiOptions, [FromServices] ILoginRateLimiter loginRateLimiter)
    {
        // Already logged in?
        var currentUser = await GetCurrentUserAsync();

        if (currentUser != null)
        {
            return(await ShowRedirectAsync(null));
        }

        // Parse and check request
        MoodleAuthenticationMessageData authData;

        try
        {
            authData = await MoodleAuthenticationTools.ParseAuthenticationRequestAsync
                       (
                Request,
                moodleLtiOptions.Value.OAuthConsumerKey,
                moodleLtiOptions.Value.OAuthSharedSecret,
                _serviceProvider.GetRequiredService <ILogger <MoodleAuthenticationTools> >()
                       );
        }
        catch (SecurityException)
        {
            AddStatusMessage(_localizer["LoginMoodleAsync:InvalidLogin"], StatusMessageTypes.Error);
            return(await RenderAsync(ViewType.Login));
        }

        // Does the user exist already?
        var user = await _userService.FindUserByMoodleUserIdAsync(authData.UserId, HttpContext.RequestAborted);

        if (user == null)
        {
            bool firstUser = !await _userService.AnyUsers(HttpContext.RequestAborted);

            var newUser = new User
            {
                DisplayName      = authData.FullName,
                MoodleUserId     = authData.UserId,
                MoodleName       = authData.LoginName,
                PasswordHash     = "",
                GroupFindingCode = RandomStringGenerator.GetRandomString(10),
                IsTutor          = firstUser,
                Privileges       = firstUser ? UserPrivileges.All : UserPrivileges.Default
            };
            user = await _userService.CreateUserAsync(newUser, HttpContext.RequestAborted);

            AddStatusMessage(_localizer["LoginMoodleAsync:AccountCreationSuccess"], StatusMessageTypes.Success);
        }

        // Sign in user
        await DoLoginAsync(user);

        // Reset rate limit
        loginRateLimiter.ResetRateLimit(user.Id);

        // Done
        AddStatusMessage(_localizer["LoginMoodleAsync:Success"], StatusMessageTypes.Success);
        return(await ShowRedirectAsync(null));
    }