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)); }
protected override async Task <bool> PostJsonAsync(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 = Serializer.DeserializeDictionary(body); var allNonEmptyFieldNames = formData.Where(f => !string.IsNullOrEmpty(f.Value.ToString())).Select(f => f.Key).ToList(); var providedCustomFields = new Dictionary <string, object>(); foreach (var item in formData.Where(x => !DefaultFields.Contains(x.Key))) { providedCustomFields.Add(item.Key, item.Value); } var customDataObject = formData.Get <IDictionary <string, object> >("customData"); if (customDataObject != null && customDataObject.Any()) { foreach (var item in customDataObject) { providedCustomFields.Add(item.Key, item.Value); } } var jsonErrorHandler = new Func <string, CancellationToken, Task>((message, ct) => Error.Create(context, new BadRequest(message), ct)); var newAccount = await InstantiateLocalAccount( context, model, allNonEmptyFieldNames, providedCustomFields, client, jsonErrorHandler, cancellationToken); if (newAccount == null) { return(true); // Some error occurred and the handler was invoked } var application = await client.GetApplicationAsync(_configuration.Application.Href, cancellationToken); var executor = new RegisterExecutor(client, _configuration, _handlers, _logger); var createdAccount = await executor.HandleRegistrationAsync(context, application, newAccount, cancellationToken); await executor.HandlePostRegistrationAsync(context, createdAccount, cancellationToken); var sanitizer = new AccountResponseSanitizer(); var responseModel = new { account = sanitizer.Sanitize(createdAccount) }; return(await JsonResponse.Ok(context, responseModel)); }
protected override async Task <bool> PostJsonAsync(IOwinEnvironment context, IClient client, ContentType bodyContentType, CancellationToken cancellationToken) { var model = await PostBodyParser.ToModel <LoginPostModel>(context, bodyContentType, _logger, cancellationToken); if (model.ProviderData != null) { return(await HandleSocialLogin(context, client, model, cancellationToken)); } var jsonErrorHandler = new Func <string, CancellationToken, Task>((message, ct) => Error.Create(context, new BadRequest(message), ct)); bool missingLoginOrPassword = string.IsNullOrEmpty(model.Login) || string.IsNullOrEmpty(model.Password); if (missingLoginOrPassword) { await jsonErrorHandler("Missing login or password.", cancellationToken); return(true); } var application = await client.GetApplicationAsync(_configuration.Application.Href, cancellationToken); var executor = new LoginExecutor(client, _configuration, _handlers, _logger); var grantResult = await executor.PasswordGrantAsync( context, application, jsonErrorHandler, model.Login, model.Password, cancellationToken); if (grantResult == null) { return(true); // The error handler was invoked } await executor.HandlePostLoginAsync(context, grantResult, cancellationToken); var token = await grantResult.GetAccessTokenAsync(cancellationToken); var account = await token.GetAccountAsync(cancellationToken); var sanitizer = new AccountResponseSanitizer(); var responseModel = new { account = sanitizer.Sanitize(account) }; return(await JsonResponse.Ok(context, responseModel)); }
protected override async Task <bool> PostJsonAsync(IOwinEnvironment context, IClient client, ContentType bodyContentType, CancellationToken cancellationToken) { var model = await PostBodyParser.ToModel <VerifyEmailPostModel>(context, bodyContentType, _logger, cancellationToken); var jsonSuccessHandler = new Func <CancellationToken, Task <bool> >(ct => JsonResponse.Ok(context)); return(await ResendVerification( email : model.Email, client : client, environment : context, errorHandler : null, // Errors are caught in AbstractRouteMiddleware successHandler : jsonSuccessHandler, cancellationToken : cancellationToken)); }
protected override async Task <bool> PostJsonAsync(IOwinEnvironment context, IClient client, ContentType bodyContentType, CancellationToken cancellationToken) { var application = await client.GetApplicationAsync(_configuration.Application.Href, cancellationToken); try { var model = await PostBodyParser.ToModel <ForgotPasswordPostModel>(context, bodyContentType, _logger, cancellationToken); await application.SendPasswordResetEmailAsync(model.Email, cancellationToken); } catch (Exception ex) { _logger.Error(ex, source: "ForgotRoute.PostJson"); } return(await JsonResponse.Ok(context)); }
protected override async Task <bool> PostJsonAsync(IOwinEnvironment context, IClient client, ContentType bodyContentType, CancellationToken cancellationToken) { var model = await PostBodyParser.ToModel <ChangePasswordPostModel>(context, bodyContentType, _logger, cancellationToken); var application = await client.GetApplicationAsync(_configuration.Application.Href, cancellationToken); var account = await application.VerifyPasswordResetTokenAsync(model.SpToken, cancellationToken); // Errors are caught in AbstractRouteMiddleware var preChangePasswordContext = new PreChangePasswordContext(context, account); await _handlers.PreChangePasswordHandler(preChangePasswordContext, cancellationToken); await application.ResetPasswordAsync(model.SpToken, model.Password, cancellationToken); var postChangePasswordContext = new PostChangePasswordContext(context, account); await _handlers.PostChangePasswordHandler(postChangePasswordContext, cancellationToken); // TODO autologin return(await JsonResponse.Ok(context)); }
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)); }
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)); }
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)); }
protected override async Task <bool> PostJsonAsync(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 = Serializer.DeserializeDictionary(body); var sanitizedFormData = new Dictionary <string, string>(); var customFields = new Dictionary <string, string>(); // Look for a root object called "customData" var customDataObject = formData.Get <IDictionary <string, object> >("customData"); if (customDataObject != null && customDataObject.Any()) { foreach (var field in customDataObject) { TryAdd(formData, field.Key, field.Value); } } foreach (var field in formData) { // The key "customData" is a special case, see above if (field.Key.Equals("customData", StringComparison.Ordinal)) { continue; } if (!DefaultFields.Contains(field.Key)) { TryAdd(customFields, field.Key, field.Value?.ToString()); } TryAdd(sanitizedFormData, field.Key, field.Value?.ToString()); } var allNonEmptyFieldNames = sanitizedFormData .Where(f => !string.IsNullOrEmpty(f.Value.ToString())) .Select(f => f.Key) .Distinct() .ToArray(); var jsonErrorHandler = new Func <string, CancellationToken, Task>((message, ct) => Error.Create(context, new BadRequest(message), ct)); var newAccount = await InstantiateLocalAccount( context, model, allNonEmptyFieldNames, customFields, client, jsonErrorHandler, cancellationToken); if (newAccount == null) { return(true); // Some error occurred and the handler was invoked } var application = await client.GetApplicationAsync(_configuration.Application.Href, cancellationToken); var executor = new RegisterExecutor(client, _configuration, _handlers, _logger); var formDataForHandler = sanitizedFormData .ToDictionary(kv => kv.Key, kv => kv.Value?.ToString()); var createdAccount = await executor.HandleRegistrationAsync( context, application, formDataForHandler, newAccount, jsonErrorHandler, cancellationToken); if (createdAccount == null) { return(true); // Some error occurred and the handler was invoked } await executor.HandlePostRegistrationAsync(context, createdAccount, cancellationToken); var sanitizer = new AccountResponseSanitizer(); var responseModel = new { account = sanitizer.Sanitize(createdAccount) }; return(await JsonResponse.Ok(context, responseModel)); }
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); } }