Update auth

This commit is contained in:
thomashii 2021-07-15 15:57:47 +08:00
parent 62336e0d53
commit fdc909b536
7 changed files with 41 additions and 40 deletions

View file

@ -20,7 +20,7 @@
* Migrated angel_validate to 4.0.0 (7/7 tests passed)
* Migrated json_god to 4.0.0 (13/13 tests passed)
* Migrated angel_client to 4.0.0 (13/13 tests passed)
* Migrated angel_websocket to 4.0.0 (2/3 tests passed)
* Migrated angel_websocket to 4.0.0 (3/3 tests passed)
* Migrated angel_test to 4.0.0 (1/1 test passed)
* Added symbol_table and migrated to 2.0.0 (16/16 tests passed)
* Migrated jael to 4.0.0 (20/20 tests passed)

View file

@ -1,10 +1,15 @@
# Change Log
## 4.0.5
* Added support for verifier function to return an empty Map instead of null
* Fixed `canRespondWithJson` option to return data in the reponse body when set to true
## 4.0.4
* Changed `serializer` and `deserializer` parameters to be required
* Fixed HTTP basic authentication
* Passed all 51 unit tests
* All 31 unit tests passed
## 4.0.3

View file

@ -1,6 +1,6 @@
# Angel3 Anthentication
[![version](https://img.shields.io/badge/pub-v4.0.4-brightgreen)](https://pub.dev/packages/angel3_auth)
[![version](https://img.shields.io/badge/pub-v4.0.5-brightgreen)](https://pub.dev/packages/angel3_auth)
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
[![Gitter](https://img.shields.io/gitter/room/angel_dart/discussion)](https://gitter.im/angel_dart/discussion)
@ -52,9 +52,7 @@ configureServer(Angel app) async {
## Default Authentication Callback
A frequent use case within SPA's is opening OAuth login endpoints in a separate window.
[`angel3_client`](https://github.com/dukefirehawk/angel/tree/angel3/packages/client)
provides a facility for this, which works perfectly with the default callback provided in this package.
A frequent use case within SPA's is opening OAuth login endpoints in a separate window. [`angel3_client`](https://github.com/dukefirehawk/angel/tree/angel3/packages/client) provides a facility for this, which works perfectly with the default callback provided in this package.
```dart
configureServer(Angel app) async {
@ -77,8 +75,7 @@ configureServer(Angel app) async {
}
```
This renders a simple HTML page that fires the user's JWT as a `token` event in `window.opener`.
`angel3_client` [exposes this as a Stream](https://github.com/dukefirehawk/angel/tree/angel3/packages/client#authentication):
This renders a simple HTML page that fires the user's JWT as a `token` event in `window.opener`. `angel3_client` [exposes this as a Stream](https://github.com/dukefirehawk/angel/tree/angel3/packages/client#authentication):
```dart
app.authenticateViaPopup('/auth/google').listen((jwt) {

View file

@ -352,9 +352,12 @@ class AngelAuth<User> {
/// or a `401 Not Authenticated` is thrown, if it is the last one.
///
/// Any other result is considered an authenticated user, and terminates the loop.
RequestHandler authenticate(type, [AngelAuthOptions<User>? options]) {
RequestHandler authenticate(type, [AngelAuthOptions<User>? opt]) {
return (RequestContext req, ResponseContext res) async {
var authOption = opt ?? AngelAuthOptions<User>();
var names = <String>[];
var arr = type is Iterable
? type.map((x) => x.toString()).toList()
: [type.toString()];
@ -386,11 +389,12 @@ class AngelAuth<User> {
var hasExisting = reqContainer?.has<User>() ?? false;
var result = hasExisting
? reqContainer?.make<User>()
: await strategy.authenticate(req, res, options);
: await strategy.authenticate(req, res, authOption);
if (result != null && result == true) {
if (result == true) {
return result;
} else if (result != false && result != null) {
} else if (result != null && result != false) {
//} else if (result != null && result is Map && result.isNotEmpty) {
var userId = await serializer(result);
// Create JWT
@ -398,13 +402,13 @@ class AngelAuth<User> {
userId: userId, lifeSpan: _jwtLifeSpan, ipAddress: req.ip);
var jwt = token.serialize(_hs256);
if (options != null && options.tokenCallback != null) {
if (authOption.tokenCallback != null) {
var hasUser = reqContainer?.has<User>() ?? false;
if (!hasUser) {
reqContainer?.registerSingleton<User>(result);
}
var r = await options.tokenCallback!(req, res, token, result);
var r = await authOption.tokenCallback!(req, res, token, result);
if (r != null) return r;
jwt = token.serialize(_hs256);
}
@ -416,24 +420,15 @@ class AngelAuth<User> {
}
// Options is not null
if (options != null) {
if (options.callback != null) {
return await options.callback!(req, res, jwt);
}
if (authOption.callback != null) {
return await authOption.callback!(req, res, jwt);
}
if (options.successRedirect?.isNotEmpty == true) {
await res.redirect(options.successRedirect);
return false;
} else if (options.canRespondWithJson &&
req.accepts('application/json')) {
var user = hasExisting
? result
: await deserializer((await serializer(result)) as Object);
_onLogin.add(user);
return {'data': user, 'token': jwt};
}
// Options is null
} else if (hasExisting && req.accepts('application/json')) {
if (authOption.successRedirect?.isNotEmpty == true) {
await res.redirect(authOption.successRedirect);
return false;
} else if (authOption.canRespondWithJson &&
req.accepts('application/json')) {
var user = hasExisting
? result
: await deserializer((await serializer(result)) as Object);
@ -449,8 +444,8 @@ class AngelAuth<User> {
res.statusCode == 302 ||
res.headers.containsKey('location')) {
return false;
} else if (options != null && options.failureRedirect != null) {
await res.redirect(options.failureRedirect);
} else if (authOption.failureRedirect != null) {
await res.redirect(authOption.failureRedirect);
return false;
} else {
_log.warning('Not authenticated');

View file

@ -86,7 +86,8 @@ class LocalAuthStrategy<User> extends AuthStrategy<User> {
//}
}
if (verificationResult == null) {
if (verificationResult == null ||
(verificationResult is Map && verificationResult.isEmpty)) {
if (options.failureRedirect != null &&
options.failureRedirect!.isNotEmpty) {
await res.redirect(options.failureRedirect, code: 401);
@ -99,7 +100,8 @@ class LocalAuthStrategy<User> extends AuthStrategy<User> {
}
return null;
} else if (verificationResult != false) {
} else if (verificationResult != false ||
(verificationResult is Map && verificationResult.isNotEmpty)) {
return verificationResult;
} else {
_log.info('Not authenticated');

View file

@ -1,6 +1,6 @@
name: angel3_auth
description: A complete authentication plugin for Angel. Includes support for stateless JWT tokens, Basic Auth, and more.
version: 4.0.4
version: 4.0.5
homepage: https://angel3-framework.web.app/
repository: https://github.com/dukefirehawk/angel/tree/angel3/packages/auth
environment:

View file

@ -12,14 +12,16 @@ final AngelAuth<Map<String, String>> auth = AngelAuth<Map<String, String>>(
var headers = <String, String>{'accept': 'application/json'};
var localOpts = AngelAuthOptions<Map<String, String>>(
failureRedirect: '/failure', successRedirect: '/success');
var localOpts2 =
AngelAuthOptions<Map<String, String>>(canRespondWithJson: false);
Map<String, String> sampleUser = {'hello': 'world'};
Future<Map<String, String>?> verifier(
String? username, String? password) async {
Future<Map<String, String>> verifier(String? username, String? password) async {
if (username == 'username' && password == 'password') {
return sampleUser;
} else {
return null;
return {};
}
}
@ -46,7 +48,7 @@ void main() async {
app.get('/hello', (req, res) {
// => 'Woo auth'
return 'Woo auth';
}, middleware: [auth.authenticate('local')]);
}, middleware: [auth.authenticate('local', localOpts2)]);
app.post('/login', (req, res) => 'This should not be shown',
middleware: [auth.authenticate('local', localOpts)]);
app.get('/success', (req, res) => 'yep', middleware: [