This commit is contained in:
thosakwe 2016-12-07 18:09:21 -05:00
parent 0de70bfc72
commit feaab715da
18 changed files with 92 additions and 521 deletions

View file

@ -0,0 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Callback Tests" type="DartTestRunConfigurationType" factoryName="Dart Test" singleton="true">
<option name="filePath" value="$PROJECT_DIR$/test/callback_test.dart" />
<method />
</configuration>
</component>

View file

@ -1,6 +1,6 @@
# angel_auth
![version 1.1.0-dev+12](https://img.shields.io/badge/version-1.1.0--dev+12-red.svg)
![version 1.1.0-dev+13](https://img.shields.io/badge/version-1.1.0--dev+13-red.svg)
![build status](https://travis-ci.org/angel-dart/auth.svg?branch=master)
A complete authentication plugin for Angel. Inspired by Passport.

View file

@ -1,10 +1,18 @@
import 'package:angel_framework/angel_framework.dart';
import 'auth_token.dart';
typedef AngelAuthCallback(
RequestContext req, ResponseContext res, AuthToken token);
class AngelAuthOptions {
AngelAuthCallback callback;
bool canRespondWithJson;
String successRedirect;
String failureRedirect;
AngelAuthOptions(
{this.canRespondWithJson: true,
{this.callback,
this.canRespondWithJson: true,
this.successRedirect,
String this.failureRedirect});
}

View file

@ -237,6 +237,10 @@ class AngelAuth extends AngelPlugin {
if (allowCookie) req.cookies.add(new Cookie("token", jwt));
if (options?.callback != null) {
return await options.callback(req, res, jwt);
}
if (options?.canRespondWithJson != false &&
req.headers.value("accept") != null &&
(req.headers.value("accept").contains("application/json") ||

View file

@ -1,68 +0,0 @@
import 'dart:async';
import 'package:angel_framework/angel_framework.dart';
import 'package:oauth2/oauth2.dart' as Oauth2;
import '../options.dart';
import '../strategy.dart';
/// Logs a user in based on an incoming OAuth access and refresh token.
typedef Future OAuth2AuthVerifier(String accessToken, String refreshToken,
Map profile);
class OAuth2AuthStrategy extends AuthStrategy {
@override
String name = "oauth2";
OAuth2AuthVerifier verifier;
Uri authEndPoint;
Uri tokenEndPoint;
String clientId;
String clientSecret;
Uri callbackUri;
List<String> scopes;
@override
Future authenticate(RequestContext req, ResponseContext res,
[AngelAuthOptions options_]) async {
Oauth2.Client client = await makeGrant().handleAuthorizationResponse(req.query);
// Remember: Do stuff
}
@override
Future<bool> canLogout(RequestContext req, ResponseContext res) async {
return true;
}
OAuth2AuthStrategy(String this.name, OAuth2AuthVerifier this.verifier,
{Uri this.authEndPoint,
Uri this.tokenEndPoint,
String this.clientId,
String this.clientSecret,
Uri this.callbackUri,
List<String> this.scopes: const[]}) {
if (this.authEndPoint == null)
throw new ArgumentError.notNull('authEndPoint');
if (this.tokenEndPoint == null)
throw new ArgumentError.notNull('tokenEndPoint');
if (this.clientId == null || this.clientId.isEmpty)
throw new ArgumentError.notNull('clientId');
}
call(RequestContext req, ResponseContext res) async {
var grant = makeGrant();
Uri to = grant.getAuthorizationUrl(callbackUri, scopes: scopes);
return res.redirect(to.path);
}
Oauth2.AuthorizationCodeGrant makeGrant() {
return new Oauth2.AuthorizationCodeGrant(
clientId, authEndPoint, tokenEndPoint, secret: clientSecret);
}
}
class OAuth2AuthorizationError extends AngelHttpException {
OAuth2AuthorizationError({String message: "OAuth2 Authorization Error",
List<String> errors: const []})
: super.NotAuthenticated(message: message) {
this.errors = errors;
}
}

View file

@ -1,3 +1 @@
export 'local.dart';
export 'oauth2.dart';
export 'token.dart';

View file

@ -1,16 +0,0 @@
import 'dart:async';
import 'package:angel_framework/angel_framework.dart';
import '../options.dart';
import '../strategy.dart';
class JwtAuthStrategy extends AuthStrategy {
@override
Future authenticate(RequestContext req, ResponseContext res,
[AngelAuthOptions options]) async {
}
@override
Future<bool> canLogout(RequestContext req, ResponseContext res) async => false;
}

View file

@ -1,12 +1,11 @@
name: angel_auth
description: A complete authentication plugin for Angel.
version: 1.0.0-dev+12
version: 1.0.0-dev+13
author: Tobe O <thosakwe@gmail.com>
homepage: https://github.com/angel-dart/angel_auth
dependencies:
angel_framework: ">=1.0.0-dev <2.0.0"
crypto: ">=2.0.0 <3.0.0"
oauth2: ">= 1.0.2 < 2.0.0"
dev_dependencies:
http: ">= 0.11.3 < 0.12.0"
test: ">= 0.12.13 < 0.13.0"

View file

@ -1,61 +0,0 @@
import 'dart:io';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_auth/angel_auth.dart';
import 'package:http/http.dart' as http;
import 'package:test/test.dart';
import 'auth_token_test.dart' as authToken;
import 'local_test.dart' as local;
wireAuth(Angel app) async {
}
main() async {
group('everything', () {
Angel app;
http.Client client;
String url;
setUp(() async {
client = new http.Client();
app = new Angel();
await app.configure(wireAuth);
HttpServer server = await app.startServer(
InternetAddress.LOOPBACK_IP_V4, 0);
url = "http://${server.address.host}:${server.port}";
});
tearDown(() async {
await app.httpServer.close(force: true);
client = null;
url = null;
});
group("JWT (de)serialization", authToken.main);
group("local", local.main);
test('can use login as middleware', () async {
});
test('successRedirect', () async {
});
test('failureRedirect', () async {
});
test('allow everything', () async {
});
test('force everything', () async {
});
test('logout', () async {
});
});
}

70
test/callback_test.dart Normal file
View file

@ -0,0 +1,70 @@
import 'dart:io';
import 'package:angel_auth/angel_auth.dart';
import 'package:angel_framework/angel_framework.dart';
import 'package:http/http.dart' as http;
import 'package:test/test.dart';
class User extends MemoryModel {
String username, password;
User({this.username, this.password});
}
main() {
Angel app;
AngelAuth auth;
http.Client client;
HttpServer server;
String url;
setUp(() async {
app = new Angel();
app.use('/users', new MemoryService<User>());
await app
.service('users')
.create({'username': 'jdoe1', 'password': 'password'});
await app.configure(auth = new AngelAuth());
auth.serializer = (User user) async => user.id;
auth.deserializer = app.service('users').read;
auth.strategies.add(new LocalAuthStrategy((username, password) async {
final List<User> users = await app.service('users').index();
final found = users.firstWhere(
(user) => user.username == username && user.password == password,
orElse: () => null);
return found != null ? found : false;
}));
app.post(
'/login',
auth.authenticate('local',
new AngelAuthOptions(callback: (req, res, token) {
return res
..write('Hello!')
..end();
})));
client = new http.Client();
server = await app.startServer();
url = 'http://${server.address.address}:${server.port}';
});
tearDown(() async {
client.close();
await server.close(force: true);
app = null;
client = null;
url = null;
});
test('login', () async {
final response = await client.post('$url/login',
body: {'username': 'jdoe1', 'password': 'password'});
print('Response: ${response.body}');
expect(response.body, equals('Hello!'));
});
}

View file

@ -1,52 +0,0 @@
import 'dart:io';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_auth/angel_auth.dart';
import 'package:http/http.dart' as http;
import 'package:test/test.dart';
wireAuth(Angel app) async {
}
main() async {
group('digest', () {
Angel app;
http.Client client;
String url;
setUp(() async {
client = new http.Client();
app = new Angel();
await app.configure(wireAuth);
HttpServer server = await app.startServer(
InternetAddress.LOOPBACK_IP_V4, 0);
url = "http://${server.address.host}:${server.port}";
});
tearDown(() async {
await app.httpServer.close(force: true);
client = null;
url = null;
});
test('can use login as middleware', () async {
});
test('successRedirect', () async {
});
test('failureRedirect', () async {
});
test('allow digest', () async {
});
test('force digest', () async {
});
});
}

View file

@ -3,7 +3,6 @@ import 'dart:io';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_auth/angel_auth.dart';
import 'package:http/http.dart' as http;
import 'package:merge_map/merge_map.dart';
import 'package:test/test.dart';
final AngelAuth Auth = new AngelAuth();
@ -43,10 +42,6 @@ main() async {
app.get('/success', "yep", middleware: ['auth']);
app.get('/failure', "nope");
app
..normalize()
..dumpTree();
HttpServer server =
await app.startServer(InternetAddress.LOOPBACK_IP_V4, 0);
url = "http://${server.address.host}:${server.port}";

View file

@ -1,52 +0,0 @@
import 'dart:io';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_auth/angel_auth.dart';
import 'package:http/http.dart' as http;
import 'package:test/test.dart';
wireAuth(Angel app) async {
}
main() async {
group('oauth1', () {
Angel app;
http.Client client;
String url;
setUp(() async {
client = new http.Client();
app = new Angel();
await app.configure(wireAuth);
HttpServer server = await app.startServer(
InternetAddress.LOOPBACK_IP_V4, 0);
url = "http://${server.address.host}:${server.port}";
});
tearDown(() async {
await app.httpServer.close(force: true);
client = null;
url = null;
});
test('can use login as middleware', () async {
});
test('successRedirect', () async {
});
test('failureRedirect', () async {
});
test('allow oauth1', () async {
});
test('force oauth1', () async {
});
});
}

View file

@ -1,52 +0,0 @@
import 'dart:io';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_auth/angel_auth.dart';
import 'package:http/http.dart' as http;
import 'package:test/test.dart';
wireAuth(Angel app) async {
}
main() async {
group('oauth2', () {
Angel app;
http.Client client;
String url;
setUp(() async {
client = new http.Client();
app = new Angel();
await app.configure(wireAuth);
HttpServer server = await app.startServer(
InternetAddress.LOOPBACK_IP_V4, 0);
url = "http://${server.address.host}:${server.port}";
});
tearDown(() async {
await app.httpServer.close(force: true);
client = null;
url = null;
});
test('can use login as middleware', () async {
});
test('successRedirect', () async {
});
test('failureRedirect', () async {
});
test('allow oauth2', () async {
});
test('force oauth2', () async {
});
});
}

View file

@ -1,52 +0,0 @@
import 'dart:io';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_auth/angel_auth.dart';
import 'package:http/http.dart' as http;
import 'package:test/test.dart';
wireAuth(Angel app) async {
}
main() async {
group('oauth2 in-house', () {
Angel app;
http.Client client;
String url;
setUp(() async {
client = new http.Client();
app = new Angel();
await app.configure(wireAuth);
HttpServer server = await app.startServer(
InternetAddress.LOOPBACK_IP_V4, 0);
url = "http://${server.address.host}:${server.port}";
});
tearDown(() async {
await app.httpServer.close(force: true);
client = null;
url = null;
});
test('can use login as middleware', () async {
});
test('successRedirect', () async {
});
test('failureRedirect', () async {
});
test('allow oauth2 in-house', () async {
});
test('force oauth2 in-house', () async {
});
});
}

View file

@ -1,52 +0,0 @@
import 'dart:io';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_auth/angel_auth.dart';
import 'package:http/http.dart' as http;
import 'package:test/test.dart';
wireAuth(Angel app) async {
}
main() async {
group('openid', () {
Angel app;
http.Client client;
String url;
setUp(() async {
client = new http.Client();
app = new Angel();
await app.configure(wireAuth);
HttpServer server = await app.startServer(
InternetAddress.LOOPBACK_IP_V4, 0);
url = "http://${server.address.host}:${server.port}";
});
tearDown(() async {
await app.httpServer.close(force: true);
client = null;
url = null;
});
test('can use login as middleware', () async {
});
test('successRedirect', () async {
});
test('failureRedirect', () async {
});
test('allow openid', () async {
});
test('force openid', () async {
});
});
}

View file

@ -1,52 +0,0 @@
import 'dart:io';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_auth/angel_auth.dart';
import 'package:http/http.dart' as http;
import 'package:test/test.dart';
wireAuth(Angel app) async {
}
main() async {
group('token', () {
Angel app;
http.Client client;
String url;
setUp(() async {
client = new http.Client();
app = new Angel();
await app.configure(wireAuth);
HttpServer server = await app.startServer(
InternetAddress.LOOPBACK_IP_V4, 0);
url = "http://${server.address.host}:${server.port}";
});
tearDown(() async {
await app.httpServer.close(force: true);
client = null;
url = null;
});
test('can use login as middleware', () async {
});
test('successRedirect', () async {
});
test('failureRedirect', () async {
});
test('allow token', () async {
});
test('force token', () async {
});
});
}

View file

@ -1,52 +0,0 @@
import 'dart:io';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_auth/angel_auth.dart';
import 'package:http/http.dart' as http;
import 'package:test/test.dart';
wireAuth(Angel app) async {
}
main() async {
group('websocket', () {
Angel app;
http.Client client;
String url;
setUp(() async {
client = new http.Client();
app = new Angel();
await app.configure(wireAuth);
HttpServer server = await app.startServer(
InternetAddress.LOOPBACK_IP_V4, 0);
url = "http://${server.address.host}:${server.port}";
});
tearDown(() async {
await app.httpServer.close(force: true);
client = null;
url = null;
});
test('can use login as middleware', () async {
});
test('successRedirect', () async {
});
test('failureRedirect', () async {
});
test('allow websocket', () async {
});
test('force websocket', () async {
});
});
}