コード例 #1
0
        protected override async Task <bool> PostHtmlAsync(IOwinEnvironment context, IClient client, ContentType bodyContentType, CancellationToken cancellationToken)
        {
            var application = await client.GetApplicationAsync(_configuration.Application.Href, cancellationToken);

            try
            {
                var body = await context.Request.GetBodyAsStringAsync(cancellationToken);

                var model    = PostBodyParser.ToModel <ForgotPasswordPostModel>(body, bodyContentType, _logger);
                var formData = FormContentParser.Parse(body, _logger);

                var stateToken       = formData.GetString(StringConstants.StateTokenName);
                var parsedStateToken = new StateTokenParser(client, _configuration.Client.ApiKey, stateToken, _logger);
                if (!parsedStateToken.Valid)
                {
                    var queryString      = QueryStringParser.Parse(context.Request.QueryString, _logger);
                    var viewModelBuilder = new ForgotPasswordFormViewModelBuilder(client, _configuration, queryString);
                    var viewModel        = viewModelBuilder.Build();
                    viewModel.Errors.Add("An error occurred. Please try again.");

                    await RenderViewAsync(context, _configuration.Web.ForgotPassword.View, viewModel, cancellationToken);

                    return(true);
                }

                await application.SendPasswordResetEmailAsync(model.Email, cancellationToken);
            }
            catch (Exception ex)
            {
                _logger.Error(ex, source: "ForgotRoute.PostHtml");
            }

            return(await HttpResponse.Redirect(context, _configuration.Web.ForgotPassword.NextUri));
        }
コード例 #2
0
        protected override async Task <bool> PostHtmlAsync(IOwinEnvironment context, IClient client, ContentType bodyContentType, CancellationToken cancellationToken)
        {
            var htmlErrorHandler = new Func <string, CancellationToken, Task <bool> >(async(error, ct) =>
            {
                var viewModelBuilder     = new VerifyEmailFormViewModelBuilder(client, _configuration);
                var verifyEmailViewModel = viewModelBuilder.Build();
                verifyEmailViewModel.Errors.Add(error);

                await RenderViewAsync(context, _configuration.Web.VerifyEmail.View, verifyEmailViewModel, cancellationToken);
                return(true);
            });

            var body = await context.Request.GetBodyAsStringAsync(cancellationToken);

            var model = PostBodyParser.ToModel <VerifyEmailPostModel>(body, bodyContentType, _logger);

            var formData         = FormContentParser.Parse(body, _logger);
            var stateToken       = formData.GetString(StringConstants.StateTokenName);
            var parsedStateToken = new StateTokenParser(client, _configuration.Client.ApiKey, stateToken, _logger);

            if (!parsedStateToken.Valid)
            {
                await htmlErrorHandler("An error occurred. Please try again.", cancellationToken);

                return(true);
            }

            var htmlSuccessHandler = new Func <CancellationToken, Task <bool> >(
                ct => HttpResponse.Redirect(context, $"{_configuration.Web.Login.Uri}?status=unverified"));

            return(await ResendVerification(
                       model.Email,
                       client,
                       context,
                       htmlErrorHandler,
                       htmlSuccessHandler,
                       cancellationToken));
        }
コード例 #3
0
        protected override async Task <bool> PostHtmlAsync(IOwinEnvironment context, IClient client, ContentType bodyContentType, CancellationToken cancellationToken)
        {
            var queryString = QueryStringParser.Parse(context.Request.QueryString, _logger);

            var body = await context.Request.GetBodyAsStringAsync(cancellationToken);

            var model    = PostBodyParser.ToModel <ChangePasswordPostModel>(body, bodyContentType, _logger);
            var formData = FormContentParser.Parse(body, _logger);

            var stateToken       = formData.GetString(StringConstants.StateTokenName);
            var parsedStateToken = new StateTokenParser(client, _configuration.Client.ApiKey, stateToken, _logger);

            if (!parsedStateToken.Valid)
            {
                var viewModelBuilder        = new ChangePasswordFormViewModelBuilder(client, _configuration);
                var changePasswordViewModel = viewModelBuilder.Build();
                changePasswordViewModel.Errors.Add("An error occurred. Please try again.");

                await RenderViewAsync(context, _configuration.Web.ChangePassword.View, changePasswordViewModel, cancellationToken);

                return(true);
            }

            if (!model.Password.Equals(model.ConfirmPassword, StringComparison.Ordinal))
            {
                var viewModelBuilder        = new ChangePasswordFormViewModelBuilder(client, _configuration);
                var changePasswordViewModel = viewModelBuilder.Build();
                changePasswordViewModel.Errors.Add("Passwords do not match.");

                await RenderViewAsync(context, _configuration.Web.ChangePassword.View, changePasswordViewModel, cancellationToken);

                return(true);
            }

            var spToken     = queryString.GetString("sptoken");
            var application = await client.GetApplicationAsync(_configuration.Application.Href, cancellationToken);

            IAccount account;

            try
            {
                account = await application.VerifyPasswordResetTokenAsync(spToken, cancellationToken);
            }
            catch (ResourceException)
            {
                return(await HttpResponse.Redirect(context, _configuration.Web.ChangePassword.ErrorUri));
            }

            var preChangePasswordContext = new PreChangePasswordContext(context, account);
            await _handlers.PreChangePasswordHandler(preChangePasswordContext, cancellationToken);

            try
            {
                await application.ResetPasswordAsync(spToken, model.Password, cancellationToken);
            }
            catch (ResourceException rex)
            {
                var viewModelBuilder        = new ChangePasswordFormViewModelBuilder(client, _configuration);
                var changePasswordViewModel = viewModelBuilder.Build();
                changePasswordViewModel.Errors.Add(rex.Message);

                await RenderViewAsync(context, _configuration.Web.ChangePassword.View, changePasswordViewModel, cancellationToken);

                return(true);
            }

            var postChangePasswordContext = new PostChangePasswordContext(context, account);
            await _handlers.PostChangePasswordHandler(postChangePasswordContext, cancellationToken);

            // TODO autologin

            return(await HttpResponse.Redirect(context, _configuration.Web.ChangePassword.NextUri));
        }
コード例 #4
0
        protected override async Task <bool> PostAsync(IOwinEnvironment context, IClient client, ContentNegotiationResult contentNegotiationResult, CancellationToken cancellationToken)
        {
            Caching.AddDoNotCacheHeaders(context);

            var rawBodyContentType             = context.Request.Headers.GetString("Content-Type");
            var bodyContentTypeDetectionResult = ContentNegotiation.DetectBodyType(rawBodyContentType);

            var isValidContentType = bodyContentTypeDetectionResult.Success && bodyContentTypeDetectionResult.ContentType == ContentType.FormUrlEncoded;

            if (!isValidContentType)
            {
                await Error.Create <OauthInvalidRequest>(context, cancellationToken);

                return(true);
            }

            var requestBody = await context.Request.GetBodyAsStringAsync(cancellationToken);

            var formData = FormContentParser.Parse(requestBody, _logger);

            var grantType = formData.GetString("grant_type");

            if (string.IsNullOrEmpty(grantType))
            {
                await Error.Create <OauthInvalidRequest>(context, cancellationToken);

                return(true);
            }

            try
            {
                if (grantType.Equals("client_credentials", StringComparison.OrdinalIgnoreCase) &&
                    _configuration.Web.Oauth2.Client_Credentials.Enabled)
                {
                    await ExecuteClientCredentialsFlow(context, client, cancellationToken);

                    return(true);
                }

                if (grantType.Equals("password", StringComparison.OrdinalIgnoreCase) &&
                    _configuration.Web.Oauth2.Password.Enabled)
                {
                    var username = WebUtility.UrlDecode(formData.GetString("username"));
                    var password = WebUtility.UrlDecode(formData.GetString("password"));
                    await ExecutePasswordFlow(context, client, username, password, cancellationToken);

                    return(true);
                }

                if (grantType.Equals("refresh_token", StringComparison.OrdinalIgnoreCase) &&
                    _configuration.Web.Oauth2.Password.Enabled)
                {
                    var refreshToken = WebUtility.UrlDecode(formData.GetString("refresh_token"));
                    await ExecuteRefreshFlow(context, client, refreshToken, cancellationToken);

                    return(true);
                }
            }
            catch (ResourceException rex)
            {
                // Special handling of API errors for the OAuth route
                return(await Error.Create(context, new OauthError(rex.Message, rex.GetProperty("error")), cancellationToken));
            }

            return(await Error.Create <OauthUnsupportedGrant>(context, cancellationToken));
        }
コード例 #5
0
        protected override async Task <bool> PostHtmlAsync(IOwinEnvironment context, IClient client, ContentType bodyContentType, CancellationToken cancellationToken)
        {
            var body = await context.Request.GetBodyAsStringAsync(cancellationToken);

            var model    = PostBodyParser.ToModel <LoginPostModel>(body, bodyContentType, _logger);
            var formData = FormContentParser.Parse(body, _logger);

            var htmlErrorHandler = new Func <string, CancellationToken, Task>((message, ct) =>
            {
                var queryString = QueryStringParser.Parse(context.Request.QueryString, _logger);
                return(RenderLoginViewAsync(
                           client,
                           context,
                           cancellationToken,
                           queryString,
                           formData,
                           errors: new[] { message }));
            });

            var stateToken       = formData.GetString(StringConstants.StateTokenName);
            var parsedStateToken = new StateTokenParser(client, _configuration.Client.ApiKey, stateToken, _logger);

            if (!parsedStateToken.Valid)
            {
                await htmlErrorHandler("An error occurred. Please try again.", cancellationToken);

                return(true);
            }

            bool missingLoginOrPassword = string.IsNullOrEmpty(model.Login) || string.IsNullOrEmpty(model.Password);

            if (missingLoginOrPassword)
            {
                await htmlErrorHandler("The login and password fields are required.", cancellationToken);

                return(true);
            }

            var application = await client.GetApplicationAsync(_configuration.Application.Href, cancellationToken);

            var executor = new LoginExecutor(client, _configuration, _handlers, _logger);

            try
            {
                var grantResult = await executor.PasswordGrantAsync(
                    context,
                    application,
                    htmlErrorHandler,
                    model.Login,
                    model.Password,
                    cancellationToken);

                if (grantResult == null)
                {
                    return(true); // The error handler was invoked
                }

                await executor.HandlePostLoginAsync(context, grantResult, cancellationToken);
            }
            catch (ResourceException rex)
            {
                await htmlErrorHandler(rex.Message, cancellationToken);

                return(true);
            }

            var nextUri = parsedStateToken.Path; // Might be null

            return(await executor.HandleRedirectAsync(context, nextUri));
        }
コード例 #6
0
        protected override async Task <bool> PostHtmlAsync(IOwinEnvironment context, IClient client, ContentType bodyContentType, CancellationToken cancellationToken)
        {
            var body = await context.Request.GetBodyAsStringAsync(cancellationToken);

            var model    = PostBodyParser.ToModel <RegisterPostModel>(body, bodyContentType, _logger);
            var formData = FormContentParser.Parse(body, _logger);

            var htmlErrorHandler = new Func <string, CancellationToken, Task>((message, ct) =>
            {
                var queryString       = QueryStringParser.Parse(context.Request.QueryString, _logger);
                var viewModelBuilder  = new RegisterFormViewModelBuilder(client, _configuration, queryString, formData, _logger);
                var registerViewModel = viewModelBuilder.Build();
                registerViewModel.Errors.Add(message);

                return(RenderViewAsync(context, _configuration.Web.Register.View, registerViewModel, cancellationToken));
            });

            var stateToken       = formData.GetString(StringConstants.StateTokenName);
            var parsedStateToken = new StateTokenParser(client, _configuration.Client.ApiKey, stateToken, _logger);

            if (!parsedStateToken.Valid)
            {
                await htmlErrorHandler("An error occurred. Please try again.", cancellationToken);

                return(true);
            }

            var allNonEmptyFieldNames = formData
                                        .Where(f => !string.IsNullOrEmpty(string.Join(",", f.Value)))
                                        .Select(f => f.Key)
                                        .Except(new [] { StringConstants.StateTokenName })
                                        .ToList();

            var providedCustomFields = new Dictionary <string, string>();
            var nonCustomFields      = DefaultFields.Concat(new[] { StringConstants.StateTokenName }).ToArray();

            foreach (var item in formData.Where(f => !nonCustomFields.Contains(f.Key)))
            {
                providedCustomFields.Add(item.Key, string.Join(",", item.Value));
            }

            var application = await client.GetApplicationAsync(_configuration.Application.Href, cancellationToken);

            var executor = new RegisterExecutor(client, _configuration, _handlers, _logger);

            try
            {
                var newAccount = await InstantiateLocalAccount(
                    context,
                    model,
                    allNonEmptyFieldNames,
                    providedCustomFields,
                    client,
                    htmlErrorHandler,
                    cancellationToken);

                if (newAccount == null)
                {
                    return(true); // Some error occurred and the handler was invoked
                }

                var formDataForHandler = formData
                                         .ToDictionary(kv => kv.Key, kv => string.Join(",", kv.Value));

                var createdAccount = await executor.HandleRegistrationAsync(
                    context,
                    application,
                    formDataForHandler,
                    newAccount,
                    htmlErrorHandler,
                    cancellationToken);

                if (createdAccount == null)
                {
                    return(true); // Some error occurred and the handler was invoked
                }

                await executor.HandlePostRegistrationAsync(context, createdAccount, cancellationToken);

                return(await executor.HandleRedirectAsync(
                           context,
                           application,
                           createdAccount,
                           model,
                           htmlErrorHandler,
                           stateToken,
                           cancellationToken));
            }
            catch (ResourceException rex)
            {
                await htmlErrorHandler(rex.Message, cancellationToken);

                return(true);
            }
        }