My work is cut out for me.
This commit is contained in:
parent
ff1368c789
commit
21f9181dc0
18 changed files with 770 additions and 0 deletions
60
.gitignore
vendored
60
.gitignore
vendored
|
@ -25,3 +25,63 @@ doc/api/
|
|||
# Don't commit pubspec lock file
|
||||
# (Library packages only! Remove pattern if developing an application package)
|
||||
pubspec.lock
|
||||
### JetBrains template
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff:
|
||||
.idea/workspace.xml
|
||||
.idea/tasks.xml
|
||||
.idea/dictionaries
|
||||
.idea/vcs.xml
|
||||
.idea/jsLibraryMappings.xml
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
.idea/dataSources.ids
|
||||
.idea/dataSources.xml
|
||||
.idea/dataSources.local.xml
|
||||
.idea/sqlDataSources.xml
|
||||
.idea/dynamic.xml
|
||||
.idea/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
.idea/gradle.xml
|
||||
.idea/libraries
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
.idea/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
### Dart template
|
||||
# See https://www.dartlang.org/tools/private-files.html
|
||||
|
||||
# Files and directories created by pub
|
||||
|
||||
# Files created by dart2js
|
||||
# (Most Dart developers will use pub build to compile Dart, use/modify these
|
||||
# rules if you intend to use dart2js directly
|
||||
# Convention is to use extension '.dart.js' for Dart compiled to Javascript to
|
||||
# differentiate from explicit Javascript files)
|
||||
|
||||
# Directory created by dartdoc
|
||||
|
||||
# Don't commit pubspec lock file
|
||||
# (Library packages only! Remove pattern if developing an application package)
|
||||
|
|
6
.idea/runConfigurations/Local_Tests.xml
Normal file
6
.idea/runConfigurations/Local_Tests.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Local Tests" type="DartTestRunConfigurationType" factoryName="Dart Test" singleton="true">
|
||||
<option name="filePath" value="$PROJECT_DIR$/test/local.dart" />
|
||||
<method />
|
||||
</configuration>
|
||||
</component>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
49
lib/angel_auth.dart
Normal file
49
lib/angel_auth.dart
Normal file
|
@ -0,0 +1,49 @@
|
|||
library angel_auth;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'package:angel_framework/angel_framework.dart';
|
||||
|
||||
part 'strategy.dart';
|
||||
|
||||
part 'middleware/require_auth.dart';
|
||||
|
||||
part 'middleware/serialization.dart';
|
||||
|
||||
part 'strategies/local.dart';
|
||||
|
||||
_validateString(String str) {
|
||||
return str != null && str.isNotEmpty;
|
||||
}
|
||||
|
||||
class Auth {
|
||||
static List<AuthStrategy> strategies = [];
|
||||
static UserSerializer serializer;
|
||||
static UserDeserializer deserializer;
|
||||
|
||||
call(Angel app) async {
|
||||
app.registerMiddleware('auth', requireAuth);
|
||||
app.before.add(_serializationMiddleware);
|
||||
}
|
||||
|
||||
static authenticate(String type, [Map options]) {
|
||||
return (RequestContext req, ResponseContext res) async {
|
||||
AuthStrategy strategy =
|
||||
strategies.firstWhere((AuthStrategy x) => x.name == type);
|
||||
var result = await strategy.authenticate(
|
||||
req, res, options: options ?? {});
|
||||
if (result is bool)
|
||||
return result;
|
||||
else {
|
||||
req.session['userId'] = await serializer(result);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Configures an app to use angel_auth. :)
|
||||
Future AngelAuth(Angel app) async {
|
||||
await app.configure(new Auth());
|
||||
}
|
10
lib/middleware/require_auth.dart
Normal file
10
lib/middleware/require_auth.dart
Normal file
|
@ -0,0 +1,10 @@
|
|||
part of angel_auth;
|
||||
|
||||
/// Restricts access to a resource via authentication.
|
||||
Future<bool> requireAuth(RequestContext req, ResponseContext res,
|
||||
{bool throws: true}) async {
|
||||
if (req.session.containsKey('userId'))
|
||||
return true;
|
||||
else if (throws) throw new AngelHttpException.NotAuthenticated();
|
||||
else return false;
|
||||
}
|
15
lib/middleware/serialization.dart
Normal file
15
lib/middleware/serialization.dart
Normal file
|
@ -0,0 +1,15 @@
|
|||
part of angel_auth;
|
||||
|
||||
/// Serializes a user to the session.
|
||||
typedef Future UserSerializer(user);
|
||||
|
||||
/// Deserializes a user from the session.
|
||||
typedef Future UserDeserializer(userId);
|
||||
|
||||
_serializationMiddleware(RequestContext req, ResponseContext res) async {
|
||||
if (await requireAuth(req, res, throws: false)) {
|
||||
req.properties['user'] = await Auth.deserializer(req.session['userId']);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
84
lib/strategies/local.dart
Normal file
84
lib/strategies/local.dart
Normal file
|
@ -0,0 +1,84 @@
|
|||
part of angel_auth;
|
||||
|
||||
/// Determines the validity of an incoming username and password.
|
||||
typedef Future LocalAuthVerifier(String username, String password);
|
||||
|
||||
class LocalAuthStrategy extends AuthStrategy {
|
||||
RegExp _rgxBasic = new RegExp(r'^Basic (.+)$', caseSensitive: false);
|
||||
RegExp _rgxUsrPass = new RegExp(r'^([^:]+):(.+)$');
|
||||
|
||||
@override
|
||||
String name = 'local';
|
||||
LocalAuthVerifier verifier;
|
||||
String usernameField;
|
||||
String passwordField;
|
||||
String invalidMessage;
|
||||
bool allowBasic;
|
||||
bool forceBasic;
|
||||
String basicRealm;
|
||||
|
||||
LocalAuthStrategy(LocalAuthVerifier this.verifier,
|
||||
{String this.usernameField: 'username',
|
||||
String this.passwordField: 'password',
|
||||
String this.invalidMessage:
|
||||
'Please provide a valid username and password.',
|
||||
bool this.allowBasic: true,
|
||||
bool this.forceBasic: false,
|
||||
String this.basicRealm: 'Authentication is required.'}) {}
|
||||
|
||||
@override
|
||||
Future<bool> canLogout(RequestContext req, ResponseContext res) async {
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> authenticate(RequestContext req, ResponseContext res,
|
||||
{Map options: const {}}) async {
|
||||
var verificationResult;
|
||||
|
||||
if (allowBasic) {
|
||||
String authHeader = req.headers.value(HttpHeaders.AUTHORIZATION) ?? "";
|
||||
if (_rgxBasic.hasMatch(authHeader)) {
|
||||
String base64AuthString = _rgxBasic.firstMatch(authHeader).group(1);
|
||||
String authString = new String.fromCharCodes(
|
||||
BASE64.decode(base64AuthString));
|
||||
if (_rgxUsrPass.hasMatch(authString)) {
|
||||
Match usrPassMatch = _rgxUsrPass.firstMatch(authString);
|
||||
verificationResult =
|
||||
await verifier(usrPassMatch.group(1), usrPassMatch.group(2));
|
||||
} else throw new AngelHttpException.BadRequest(
|
||||
errors: [invalidMessage]);
|
||||
}
|
||||
}
|
||||
|
||||
if (verificationResult == null) {
|
||||
if (_validateString(req.body[usernameField]) &&
|
||||
_validateString(req.body[passwordField])) {
|
||||
verificationResult =
|
||||
await verifier(req.body[usernameField], req.body[passwordField]);
|
||||
}
|
||||
}
|
||||
|
||||
if (verificationResult == false || verificationResult == null) {
|
||||
if (options.containsKey('failureRedirect')) {
|
||||
return res.redirect(
|
||||
options['failureRedirect'], code: HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
if (forceBasic) {
|
||||
res
|
||||
..status(401)
|
||||
..header(HttpHeaders.WWW_AUTHENTICATE, 'Basic realm="$basicRealm"')
|
||||
..end();
|
||||
return false;
|
||||
} else throw new AngelHttpException.NotAuthenticated();
|
||||
}
|
||||
|
||||
req.session['user'] = await Auth.serializer(verificationResult);
|
||||
if (options.containsKey('successRedirect')) {
|
||||
return res.redirect(options['successRedirect'], code: HttpStatus.OK);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
12
lib/strategy.dart
Normal file
12
lib/strategy.dart
Normal file
|
@ -0,0 +1,12 @@
|
|||
part of angel_auth;
|
||||
|
||||
/// A function that handles login and signup for an Angel application.
|
||||
abstract class AuthStrategy {
|
||||
String name;
|
||||
|
||||
/// Authenticates or rejects an incoming user.
|
||||
Future authenticate(RequestContext req, ResponseContext res, {Map options: const {}});
|
||||
|
||||
/// Determines whether a signed-in user can log out or not.
|
||||
Future<bool> canLogout(RequestContext req, ResponseContext res);
|
||||
}
|
10
pubspec.yaml
Normal file
10
pubspec.yaml
Normal file
|
@ -0,0 +1,10 @@
|
|||
name: angel_auth
|
||||
description: A complete authentication plugin for Angel.
|
||||
version: 1.0.0-dev
|
||||
author: thosakwe <thosakwe@gmail.com>
|
||||
homepage: https://github.com/angel-dart/angel_auth
|
||||
dependencies:
|
||||
angel_framework: ">=0.0.0-dev < 0.1.0"
|
||||
dev_dependencies:
|
||||
http: ">= 0.11.3 < 0.12.0"
|
||||
test: ">= 0.12.13 < 0.13.0"
|
52
test/digest.dart
Normal file
52
test/digest.dart
Normal file
|
@ -0,0 +1,52 @@
|
|||
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 {
|
||||
|
||||
});
|
||||
});
|
||||
}
|
52
test/everything.dart
Normal file
52
test/everything.dart
Normal file
|
@ -0,0 +1,52 @@
|
|||
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('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;
|
||||
});
|
||||
|
||||
test('can use login as middleware', () async {
|
||||
|
||||
});
|
||||
|
||||
test('successRedirect', () async {
|
||||
|
||||
});
|
||||
|
||||
test('failureRedirect', () async {
|
||||
|
||||
});
|
||||
|
||||
test('allow everything', () async {
|
||||
|
||||
});
|
||||
|
||||
test('force everything', () async {
|
||||
|
||||
});
|
||||
});
|
||||
}
|
102
test/local.dart
Normal file
102
test/local.dart
Normal file
|
@ -0,0 +1,102 @@
|
|||
import 'dart:convert';
|
||||
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';
|
||||
|
||||
Map headers = {HttpHeaders.ACCEPT: ContentType.JSON.mimeType};
|
||||
Map localOpts = {'failureRedirect': '/failure'};
|
||||
Map sampleUser = {'hello': 'world'};
|
||||
|
||||
verifier(username, password) async {
|
||||
if (username == 'username' && password == 'password') {
|
||||
return sampleUser;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
wireAuth(Angel app) async {
|
||||
Auth.serializer = (user) async => 1337;
|
||||
Auth.deserializer = (id) async => sampleUser;
|
||||
|
||||
Auth.strategies.add(new LocalAuthStrategy(verifier));
|
||||
await app.configure(AngelAuth);
|
||||
}
|
||||
|
||||
main() async {
|
||||
group
|
||||
('local', () {
|
||||
Angel app;
|
||||
http.Client client;
|
||||
String url;
|
||||
|
||||
setUp(() async {
|
||||
client = new http.Client();
|
||||
app = new Angel();
|
||||
|
||||
await app.configure(wireAuth);
|
||||
app.get('/hello', 'Woo auth', middleware: [Auth.authenticate('local')]);
|
||||
app.post('/login', 'This should not be shown',
|
||||
middleware: [Auth.authenticate('local', localOpts)]);
|
||||
app.get('/success', "yep", middleware: []);
|
||||
app.get('/failure', "nope");
|
||||
|
||||
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 {
|
||||
var response = await client.get("$url/success");
|
||||
expect(response.statusCode, equals(401));
|
||||
});
|
||||
|
||||
test('successRedirect', () async {
|
||||
Map postData = {
|
||||
'username': 'username',
|
||||
'password': 'password'
|
||||
};
|
||||
var response = await client.post(
|
||||
"$url/login", body: JSON.encode(postData),
|
||||
headers: {HttpHeaders.CONTENT_TYPE: ContentType.JSON.mimeType});
|
||||
expect(response.statusCode, equals(200));
|
||||
expect(response.headers[HttpHeaders.LOCATION], equals('/success'));
|
||||
});
|
||||
|
||||
test('failureRedirect', () async {
|
||||
Map postData = {
|
||||
'username': 'password',
|
||||
'password': 'username'
|
||||
};
|
||||
var response = await client.post(
|
||||
"$url/login", body: JSON.encode(postData),
|
||||
headers: {HttpHeaders.CONTENT_TYPE: ContentType.JSON.mimeType});
|
||||
expect(response.statusCode, equals(401));
|
||||
expect(response.headers[HttpHeaders.LOCATION], equals('/failure'));
|
||||
});
|
||||
|
||||
test('allow basic', () async {
|
||||
String authString = BASE64.encode("username:password".runes.toList());
|
||||
Map auth = {HttpHeaders.AUTHORIZATION: 'Basic $authString'};
|
||||
var response = await client.get(
|
||||
"$url/hello", headers: mergeMap([auth, headers]));
|
||||
expect(response.body, equals('"Woo auth"'));
|
||||
});
|
||||
|
||||
test('force basic', () async {
|
||||
Auth.strategies.clear();
|
||||
Auth.strategies.add(new LocalAuthStrategy(
|
||||
verifier, forceBasic: true, basicRealm: 'test'));
|
||||
var response = await client.get("$url/hello", headers: headers);
|
||||
expect(response.headers[HttpHeaders.WWW_AUTHENTICATE],
|
||||
equals('Basic realm="test"'));
|
||||
});
|
||||
});
|
||||
}
|
52
test/oauth1.dart
Normal file
52
test/oauth1.dart
Normal file
|
@ -0,0 +1,52 @@
|
|||
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 {
|
||||
|
||||
});
|
||||
});
|
||||
}
|
52
test/oauth2.dart
Normal file
52
test/oauth2.dart
Normal file
|
@ -0,0 +1,52 @@
|
|||
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 {
|
||||
|
||||
});
|
||||
});
|
||||
}
|
52
test/oauth_in_house.dart
Normal file
52
test/oauth_in_house.dart
Normal file
|
@ -0,0 +1,52 @@
|
|||
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 {
|
||||
|
||||
});
|
||||
});
|
||||
}
|
52
test/openid.dart
Normal file
52
test/openid.dart
Normal file
|
@ -0,0 +1,52 @@
|
|||
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 {
|
||||
|
||||
});
|
||||
});
|
||||
}
|
52
test/token.dart
Normal file
52
test/token.dart
Normal file
|
@ -0,0 +1,52 @@
|
|||
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 {
|
||||
|
||||
});
|
||||
});
|
||||
}
|
52
test/websocket.dart
Normal file
52
test/websocket.dart
Normal file
|
@ -0,0 +1,52 @@
|
|||
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 {
|
||||
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Reference in a new issue