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));
        }
Ejemplo n.º 2
0
        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));
        }
Ejemplo n.º 3
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);
            }
        }
        private async Task <bool> HandleCallbackAsync(
            IOwinEnvironment context,
            IClient client,
            IApplication application,
            IJwt jwt,
            string nextPath,
            CancellationToken cancellationToken)
        {
            var isNewSubscriber = false;

            if (jwt.Body.ContainsClaim("isNewSub"))
            {
                isNewSubscriber = (bool)jwt.Body.GetClaim("isNewSub");
            }

            var status = jwt.Body.GetClaim("status").ToString();

            var isLogin        = status.Equals("authenticated", StringComparison.OrdinalIgnoreCase);
            var isLogout       = status.Equals("logout", StringComparison.OrdinalIgnoreCase);
            var isRegistration = isNewSubscriber || status.Equals("registered", StringComparison.OrdinalIgnoreCase);

            if (isRegistration)
            {
                var grantResult = await ExchangeTokenAsync(application, jwt, cancellationToken);

                var registrationExecutor = new RegisterExecutor(client, _configuration, _handlers, _logger);
                var account = await(await grantResult.GetAccessTokenAsync(cancellationToken)).GetAccountAsync(cancellationToken);
                await registrationExecutor.HandlePostRegistrationAsync(context, account, cancellationToken);

                return(await LoginAndRedirectAsync(
                           context,
                           client,
                           grantResult,
                           true,
                           nextPath,
                           cancellationToken));
            }

            if (isLogin)
            {
                var grantResult = await ExchangeTokenAsync(application, jwt, cancellationToken);

                return(await LoginAndRedirectAsync(
                           context,
                           client,
                           grantResult,
                           false,
                           nextPath,
                           cancellationToken));
            }

            if (isLogout)
            {
                var executor = new LogoutExecutor(client, _configuration, _handlers, _logger);

                await executor.HandleLogoutAsync(context, cancellationToken);

                await executor.HandleRedirectAsync(context);

                return(true);
            }

            // json response
            throw new ArgumentException($"Unknown assertion status '{status}'");
        }