Skip to content
This repository has been archived by the owner on Mar 18, 2021. It is now read-only.

Fixed issue #20. Added x-www-form-urlencoded ContentType to default o… #21

Merged
merged 1 commit into from
Nov 28, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 21 additions & 40 deletions lib/auth/auth_controller.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
part of monadart;

class AuthController<ResourceOwner extends Authenticatable, TokenType extends Tokenizable> extends HttpController {
static String get RoutePattern => "/auth/token/[:action(refresh)]";
static String get RoutePattern => "/auth/token";

AuthenticationServer<ResourceOwner, TokenType> authenticationServer;

Expand All @@ -11,59 +11,40 @@ class AuthController<ResourceOwner extends Authenticatable, TokenType extends To
}

@httpPost
Future<Response> refreshToken(String _) async {
var authorizationHeader = request.innerRequest.headers[HttpHeaders
.AUTHORIZATION]?.first;
Future<Response> create({String grant_type, String username, String password, String refresh_token}) async {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great.

var authorizationHeader = request.innerRequest.headers[HttpHeaders.AUTHORIZATION]?.first;

var rec = new AuthorizationBasicParser(authorizationHeader);
if (rec.errorResponse != null) {
return rec.errorResponse;
}

var grantType = requestBody["grant_type"];
if (grantType != "refresh_token") {
return new Response.badRequest(body: {"error" : "grant_type must be refresh_token"});
}

var refreshToken = requestBody["refresh_token"];
var token = await authenticationServer.refresh(refreshToken, rec.username, rec.password);
if (grant_type == "password") {
if (username == null || password == null) {
return new Response.badRequest(body: {"error" : "username and password required"});
}

return AuthController.tokenResponse(token);
}
var token = await authenticationServer.authenticate(username, password, rec.username, rec.password);
return AuthController.tokenResponse(token);
} else if (grant_type == "refresh") {
if (refresh_token == null) {
return new Response.badRequest(body: {"error" : "missing refresh_token"});
}

@httpPost
Future<Response> createToken() async {
var authorizationHeader = request.innerRequest.headers[HttpHeaders
.AUTHORIZATION]?.first;

var rec = new AuthorizationBasicParser(authorizationHeader);
if (rec.errorResponse != null) {
return rec.errorResponse;
}

if (requestBody["grant_type"] != "password") {
return new Response.badRequest(body: {"error" : "grant_type must be password"});
var token = await authenticationServer.refresh(refresh_token, rec.username, rec.password);
return AuthController.tokenResponse(token);
}

var username = requestBody["username"];
var password = requestBody["password"];
if (username == null || password == null) {
return new Response.badRequest(body: {"error" : "username and password required"});
}

var token = await authenticationServer.authenticate(
username, password, rec.username, rec.password);

return AuthController.tokenResponse(token);
return new Response.badRequest(body: {"error": "invalid grant_type"});
}

static Response tokenResponse(Tokenizable token) {
var jsonToken = {
"access_token" : token.accessToken,
"token_type" : token.type,
"expires_in" : token.expirationDate.difference(new DateTime.now().toUtc()).inSeconds,
"refresh_token" : token.refreshToken
"access_token": token.accessToken,
"token_type": token.type,
"expires_in": token.expirationDate.difference(new DateTime.now().toUtc()).inSeconds,
"refresh_token": token.refreshToken
};
return new Response(200, {"Cache-Control" : "no-store", "Pragma" : "no-cache"}, jsonToken);
return new Response(200, {"Cache-Control": "no-store", "Pragma": "no-cache"}, jsonToken);
}
}
8 changes: 3 additions & 5 deletions lib/auth/authentication_server.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
part of monadart;


class AuthenticationServer<ResourceOwner extends Authenticatable, TokenType extends Tokenizable> {
AuthenticationServerDelegate<ResourceOwner, TokenType> delegate;
Map<String, Client> _clientCache = {};

AuthenticationServer(this.delegate) {
}
AuthenticationServer(this.delegate) {}

Authenticator authenticator({List<String> strategies: const [Authenticator.StrategyResourceOwner]}) {
return new Authenticator(this, strategies);
Expand Down Expand Up @@ -70,7 +68,7 @@ class AuthenticationServer<ResourceOwner extends Authenticatable, TokenType exte
}

TokenType t = await delegate.tokenForRefreshToken(this, refreshToken);
if(t == null || t.clientID != clientID) {
if (t == null || t.clientID != clientID) {
throw new HttpResponseException(401, "Invalid client_id for token");
}

Expand Down Expand Up @@ -130,4 +128,4 @@ class AuthenticationServer<ResourceOwner extends Authenticatable, TokenType exte

return CryptoUtils.bytesToBase64(salt);
}
}
}
2 changes: 1 addition & 1 deletion lib/auth/authenticator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class Authenticator extends RequestHandler {

Future<RequestHandlerResult> processResourceOwnerRequest(ResourceRequest req) async {
var parser = new AuthorizationBearerParser(req.innerRequest.headers[HttpHeaders.AUTHORIZATION]?.first);
if(parser.errorResponse != null) {
if (parser.errorResponse != null) {
return parser.errorResponse;
}

Expand Down
15 changes: 7 additions & 8 deletions lib/auth/authorization_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ abstract class AuthorizationFailable {
Response errorResponse;
}

class AuthorizationBearerParser extends AuthorizationFailable{
class AuthorizationBearerParser extends AuthorizationFailable {
String bearerToken;

AuthorizationBearerParser(String authorizationHeader) {
Expand All @@ -13,7 +13,7 @@ class AuthorizationBearerParser extends AuthorizationFailable{

Response parse(String authorizationHeader) {
if (authorizationHeader == null) {
return new Response.unauthorized(body: {"error" : "No authorization header."});
return new Response.unauthorized(body: {"error": "No authorization header."});
}

var matcher = new RegExp("Bearer (.*)");
Expand All @@ -38,7 +38,7 @@ class AuthorizationBasicParser extends AuthorizationFailable {

Response parse(String authorizationHeader) {
if (authorizationHeader == null) {
return new Response.unauthorized(body: {"error" : "No authorization header."});
return new Response.unauthorized(body: {"error": "No authorization header."});
}

var matcher = new RegExp("Basic (.*)");
Expand All @@ -50,20 +50,19 @@ class AuthorizationBasicParser extends AuthorizationFailable {
var base64String = match[1];
var decodedCredentials = null;
try {
decodedCredentials = new String.fromCharCodes(
CryptoUtils.base64StringToBytes(base64String));
decodedCredentials = new String.fromCharCodes(CryptoUtils.base64StringToBytes(base64String));
} catch (e) {
return new Response.badRequest(body: {"error" : "Improper authorization header."});
return new Response.badRequest(body: {"error": "Improper authorization header."});
}

var splitCredentials = decodedCredentials.split(":");
if (splitCredentials.length != 2) {
return new Response.badRequest(body: {"error" : "Improper client credentials."});
return new Response.badRequest(body: {"error": "Improper client credentials."});
}

username = splitCredentials.first;
password = splitCredentials.last;

return null;
}
}
}
2 changes: 1 addition & 1 deletion lib/auth/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ class Client {
String salt;

Client(this.id, this.hashedSecret, this.salt);
}
}
2 changes: 1 addition & 1 deletion lib/auth/protocols.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ abstract class AuthenticationServerDelegate<ResourceOwner extends Authenticatabl
Future storeToken(AuthenticationServer server, TokenType t);

Future pruneTokensForResourceOwnerID(AuthenticationServer server, dynamic id);
}
}
2 changes: 1 addition & 1 deletion lib/auth/token_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ String randomStringOfLength(int length) {
}

return buff.toString();
}
}
62 changes: 20 additions & 42 deletions lib/base/application.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ class ApplicationInstanceConfiguration {
ApplicationInstanceConfiguration();

/// A copy constructor
ApplicationInstanceConfiguration.fromConfiguration(
ApplicationInstanceConfiguration config)
ApplicationInstanceConfiguration.fromConfiguration(ApplicationInstanceConfiguration config)
: this.address = config.address,
this.port = config.port,
this.isIpv6Only = config.isIpv6Only,
Expand Down Expand Up @@ -79,7 +78,9 @@ abstract class ApplicationPipeline extends RequestHandler {
/// of this pipeline to be set. Initialization that does not require the use of [options]
/// should take place in the constructor.
/// This method will be executed prior to the start of the [HttpServer].
Future willOpen() { return null; }
Future willOpen() {
return null;
}

/// Executed after the pipeline is attached to an [HttpServer].
///
Expand All @@ -94,7 +95,9 @@ abstract class ApplicationPipeline extends RequestHandler {
/// This method will run prior to each request being [deliver]ed to this
/// pipeline's [initialHandler]. Use this method to provide additional
/// context to the request prior to it being handled.
Future willReceiveRequest(ResourceRequest request) { return null; }
Future willReceiveRequest(ResourceRequest request) {
return null;
}
}

/// A container for web server applications.
Expand All @@ -109,8 +112,7 @@ class Application<PipelineType extends ApplicationPipeline> {
/// The configuration for the HTTP(s) server this application is running.
///
/// This must be configured prior to [start]ing the [Application].
ApplicationInstanceConfiguration configuration =
new ApplicationInstanceConfiguration();
ApplicationInstanceConfiguration configuration = new ApplicationInstanceConfiguration();

/// Starts the application by spawning Isolates that listen for HTTP(s) requests.
///
Expand All @@ -129,8 +131,7 @@ class Application<PipelineType extends ApplicationPipeline> {
configuration._shared = numberOfInstances > 1;

for (int i = 0; i < numberOfInstances; i++) {
var config =
new ApplicationInstanceConfiguration.fromConfiguration(configuration);
var config = new ApplicationInstanceConfiguration.fromConfiguration(configuration);

var serverRecord = await _spawn(config, i + 1);
servers.add(serverRecord);
Expand All @@ -143,20 +144,15 @@ class Application<PipelineType extends ApplicationPipeline> {
await Future.wait(futures);
}

Future<_ServerRecord> _spawn(
ApplicationInstanceConfiguration config, int identifier) async {
Future<_ServerRecord> _spawn(ApplicationInstanceConfiguration config, int identifier) async {
var receivePort = new ReceivePort();

var pipelineTypeMirror = reflectType(PipelineType);
var pipelineLibraryURI = (pipelineTypeMirror.owner as LibraryMirror).uri;
var pipelineTypeName = MirrorSystem.getName(pipelineTypeMirror.simpleName);

var initialMessage = new _InitialServerMessage(
pipelineTypeName,
pipelineLibraryURI,
config, identifier, receivePort.sendPort);
var isolate =
await Isolate.spawn(_Server.entry, initialMessage, paused: true);
var initialMessage = new _InitialServerMessage(pipelineTypeName, pipelineLibraryURI, config, identifier, receivePort.sendPort);
var isolate = await Isolate.spawn(_Server.entry, initialMessage, paused: true);
isolate.addErrorListener(receivePort.sendPort);

return new _ServerRecord(isolate, receivePort, identifier);
Expand All @@ -172,11 +168,7 @@ class _Server {
ApplicationPipeline pipeline;
int identifier;

_Server(this.pipeline,
this.configuration, this.identifier,
this.supervisingApplicationPort);


_Server(this.pipeline, this.configuration, this.identifier, this.supervisingApplicationPort);

ResourceRequest createRequest(HttpRequest req) {
return new ResourceRequest(req);
Expand Down Expand Up @@ -209,37 +201,24 @@ class _Server {
if (configuration.serverCertificateName != null) {
HttpServer
.bindSecure(configuration.address, configuration.port,
certificateName: configuration.serverCertificateName,
v6Only: configuration.isIpv6Only,
shared: configuration._shared)
certificateName: configuration.serverCertificateName, v6Only: configuration.isIpv6Only, shared: configuration._shared)
.then(onBind);
} else if (configuration.isUsingClientCertificate) {
HttpServer
.bindSecure(configuration.address, configuration.port,
requestClientCertificate: true,
v6Only: configuration.isIpv6Only,
shared: configuration._shared)
requestClientCertificate: true, v6Only: configuration.isIpv6Only, shared: configuration._shared)
.then(onBind);
} else {
HttpServer
.bind(configuration.address, configuration.port,
v6Only: configuration.isIpv6Only, shared: configuration._shared)
.then(onBind);
HttpServer.bind(configuration.address, configuration.port, v6Only: configuration.isIpv6Only, shared: configuration._shared).then(onBind);
}
}

static void entry(_InitialServerMessage params) {
var pipelineSourceLibraryMirror =
currentMirrorSystem().libraries[params.pipelineLibraryURI];
var pipelineTypeMirror = pipelineSourceLibraryMirror.declarations[
new Symbol(params.pipelineTypeName)] as ClassMirror;
var pipelineSourceLibraryMirror = currentMirrorSystem().libraries[params.pipelineLibraryURI];
var pipelineTypeMirror = pipelineSourceLibraryMirror.declarations[new Symbol(params.pipelineTypeName)] as ClassMirror;

var app = pipelineTypeMirror.newInstance(new Symbol(""), []).reflectee;
var server = new _Server(
app,
params.configuration,
params.identifier,
params.parentMessagePort);
var server = new _Server(app, params.configuration, params.identifier, params.parentMessagePort);

server.start();
}
Expand Down Expand Up @@ -271,6 +250,5 @@ class _InitialServerMessage {
SendPort parentMessagePort;
int identifier;

_InitialServerMessage(this.pipelineTypeName, this.pipelineLibraryURI,
this.configuration, this.identifier, this.parentMessagePort);
_InitialServerMessage(this.pipelineTypeName, this.pipelineLibraryURI, this.configuration, this.identifier, this.parentMessagePort);
}
Loading