Skip to content
This repository has been archived by the owner on Oct 19, 2022. It is now read-only.

Commit

Permalink
Expose form data to pre-registration handler (closes #68)
Browse files Browse the repository at this point in the history
  • Loading branch information
nbarbettini committed Jan 5, 2017
1 parent f74a4d2 commit 5acaa96
Show file tree
Hide file tree
Showing 4 changed files with 251 additions and 5 deletions.
13 changes: 12 additions & 1 deletion src/Stormpath.Owin.Middleware/PreRegistrationContext.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using Stormpath.Owin.Abstractions;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Stormpath.Owin.Abstractions;
using Stormpath.SDK.Account;
using Stormpath.SDK.Directory;

Expand All @@ -12,8 +14,17 @@ public PreRegistrationContext(IOwinEnvironment environment, IAccount account)
Account = account;
}

public PreRegistrationContext(IOwinEnvironment environment, IAccount account, IDictionary<string, string> postData)
: base(environment)
{
Account = account;
PostData = new ReadOnlyDictionary<string, string>(postData);
}

public IAccount Account { get; }

public IReadOnlyDictionary<string, string> PostData { get; }

public IDirectory AccountStore { get; set; }

public IAccountCreationOptions Options { get; set; }
Expand Down
4 changes: 3 additions & 1 deletion src/Stormpath.Owin.Middleware/RegisterExecutor.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Stormpath.Configuration.Abstractions.Immutable;
Expand Down Expand Up @@ -35,13 +36,14 @@ public RegisterExecutor(
public async Task<IAccount> HandleRegistrationAsync(
IOwinEnvironment environment,
IApplication application,
IDictionary<string, string> formData,
IAccount newAccount,
Func<string, CancellationToken, Task> errorHandler,
CancellationToken cancellationToken)
{
var defaultAccountStore = await application.GetDefaultAccountStoreAsync(cancellationToken);

var preRegisterHandlerContext = new PreRegistrationContext(environment, newAccount)
var preRegisterHandlerContext = new PreRegistrationContext(environment, newAccount, formData)
{
AccountStore = defaultAccountStore as IDirectory
};
Expand Down
22 changes: 20 additions & 2 deletions src/Stormpath.Owin.Middleware/Route/RegisterRoute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,16 @@ protected override async Task<bool> PostHtmlAsync(IOwinEnvironment context, ICli
return true; // Some error occurred and the handler was invoked
}

var createdAccount = await executor.HandleRegistrationAsync(context, application, newAccount, htmlErrorHandler, cancellationToken);
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
Expand Down Expand Up @@ -254,7 +263,16 @@ protected override async Task<bool> PostJsonAsync(IOwinEnvironment context, ICli
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, jsonErrorHandler, cancellationToken);
var formDataForHandler = formData
.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
Expand Down
217 changes: 216 additions & 1 deletion test/Stormpath.Owin.IntegrationTest/PreRegistrationHandlerShould.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using FluentAssertions;
using Newtonsoft.Json;
using Stormpath.Configuration.Abstractions;
using Stormpath.Owin.Abstractions;
using Stormpath.Owin.Middleware;
using Stormpath.SDK;
using Xunit;
Expand Down Expand Up @@ -217,5 +220,217 @@ public async Task ReturnCustomErrorMessageDuringJsonPost()
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
(await response.Content.ReadAsStringAsync()).Should().Contain("\"message\": \"Nice try, rebel scum!\"");
}

[Fact]
public async Task AccessPostDataDuringFormPost()
{
var handlerRun = false;

// Arrange
var fixture = new OwinTestFixture
{
Options = new StormpathOwinOptions
{
PreRegistrationHandler = (ctx, ct) =>
{
handlerRun = true;
ctx.PostData["email"].Should().Be("[email protected]");
ctx.PostData["custom"].Should().Be("foobar!");

// Don't actually create an account
ctx.Result = new PreRegistrationResult
{
Success = false
};

return Task.FromResult(0);
},
Configuration = new StormpathConfiguration()
{
Web = new WebConfiguration()
{
Register = new WebRegisterRouteConfiguration()
{
Form = new WebRegisterRouteFormConfiguration()
{
Fields = new Dictionary<string, WebFieldConfiguration>()
{
["custom"] = new WebFieldConfiguration()
{
Required = true,
Enabled = true,
Label = "custom",
Placeholder = "custom",
Type = "text",
Visible = true
}
}
}
}
}
}
},
};
var server = Helpers.CreateServer(fixture);
var csrfToken = await CsrfToken.GetTokenForRoute(server, "/register");

// Act
var payload = new Dictionary<string, string>()
{
["email"] = "[email protected]",
["password"] = "Changeme123!!",
["givenName"] = "Chewbacca",
["surname"] = "Wookie",
["custom"] = "foobar!",
["st"] = csrfToken,
};

var request = new HttpRequestMessage(HttpMethod.Post, "/register")
{
Content = new FormUrlEncodedContent(payload)
};
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/html"));

await server.SendAsync(request);

handlerRun.Should().BeTrue();
}

[Fact]
public async Task AccessPostDataDuringJsonPost()
{
var handlerRun = false;

// Arrange
var fixture = new OwinTestFixture
{
Options = new StormpathOwinOptions
{
PreRegistrationHandler = (ctx, ct) =>
{
handlerRun = true;
ctx.PostData["email"].Should().Be("[email protected]");
ctx.PostData["custom"].Should().Be("foobar!");

// Don't actually create an account
ctx.Result = new PreRegistrationResult
{
Success = false
};

return Task.FromResult(0);
},
Configuration = new StormpathConfiguration()
{
Web = new WebConfiguration()
{
Register = new WebRegisterRouteConfiguration()
{
Form = new WebRegisterRouteFormConfiguration()
{
Fields = new Dictionary<string, WebFieldConfiguration>()
{
["custom"] = new WebFieldConfiguration()
{
Required = true,
Enabled = true,
Label = "custom",
Placeholder = "custom",
Type = "text",
Visible = true
}
}
}
}
}
}
},
};
var server = Helpers.CreateServer(fixture);

// Act
var payload = new
{
email = "[email protected]",
password = "Changeme123!!",
givenName = "Chewbacca",
surname = "Wookiee",
custom = "foobar!"
};

await server.PostAsync("/register", new StringContent(JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/json"));

handlerRun.Should().BeTrue();
}

[Fact]
public async Task AccessPostDataDuringJsonPostWithCustomDataSubobject()
{
var handlerRun = false;

// Arrange
var fixture = new OwinTestFixture
{
Options = new StormpathOwinOptions
{
PreRegistrationHandler = (ctx, ct) =>
{
handlerRun = true;
ctx.PostData["email"].Should().Be("[email protected]");
ctx.PostData["custom"].Should().Be("foobar!");

// Don't actually create an account
ctx.Result = new PreRegistrationResult
{
Success = false
};

return Task.FromResult(0);
},
Configuration = new StormpathConfiguration()
{
Web = new WebConfiguration()
{
Register = new WebRegisterRouteConfiguration()
{
Form = new WebRegisterRouteFormConfiguration()
{
Fields = new Dictionary<string, WebFieldConfiguration>()
{
["custom"] = new WebFieldConfiguration()
{
Required = true,
Enabled = true,
Label = "custom",
Placeholder = "custom",
Type = "text",
Visible = true
}
}
}
}
}
}
},
};
var server = Helpers.CreateServer(fixture);

// Act
var payload = new
{
email = "[email protected]",
password = "Changeme123!!",
givenName = "Chewbacca",
surname = "Wookiee",
customData = new
{
custom = "foobar!"
}
};

await server.PostAsync("/register", new StringContent(JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/json"));

handlerRun.Should().BeTrue();
}
}
}

0 comments on commit 5acaa96

Please sign in to comment.