Fixed bug for Auth

This commit is contained in:
thomashii@dukefirehawk.com 2023-05-30 19:49:02 +08:00
parent 7f3eba8538
commit e5743b95e2
11 changed files with 219 additions and 21 deletions

View file

@ -10,7 +10,7 @@
* Updated: angel3_container_generator * Updated: angel3_container_generator
* Updated: angel3_mock_request * Updated: angel3_mock_request
* Updated: angel3_framework * Updated: angel3_framework
* Updated: angel3_auth (4 failed test cases) * Updated: angel3_auth (1 failed test cases)
* Updated: angel3_configuration * Updated: angel3_configuration
* Updated: angel3_validate * Updated: angel3_validate
* Updated: angel3_client (1 failed test cases) * Updated: angel3_client (1 failed test cases)
@ -49,7 +49,7 @@
* Updated: angel3_auth_oauth2 (issue: oauth2 don't support http 1.0.0) * Updated: angel3_auth_oauth2 (issue: oauth2 don't support http 1.0.0)
* Updated: angel3_auth_twitter (issue: oauth2 don't support http 1.0.0) * Updated: angel3_auth_twitter (issue: oauth2 don't support http 1.0.0)
* Updated: angel3_mongo (issue: mongo_dart don't support http 1.0.0) * Updated: angel3_mongo (issue: mongo_dart don't support http 1.0.0)
* Updated: angel3_markdown (issue: markdown don't support file 7.0.0) * Updated: angel3_markdown (issue: basic_utils don't support http 1.0.0)
* Updated: angel3_shelf (issue: 2 failed test cases) * Updated: angel3_shelf (issue: 2 failed test cases)
## 7.0.0 ## 7.0.0

View file

@ -4,6 +4,10 @@
* Require Dart >= 3.0 * Require Dart >= 3.0
* Upgraded `http` to 1.0.0 * Upgraded `http` to 1.0.0
* Fixed bug causing `successRedirect` test case to fail
* Fixed bug causing `failureRedirect` test case to fail
* Fixed bug causing `login` test case to fail
* Added `example1` and `example2`
## 7.0.1 ## 7.0.1

View file

@ -0,0 +1,8 @@
### Load landing page
GET http://localhost:3000/ HTTP/1.1
### Success redirect
POST http://localhost:3000/login HTTP/1.1
Content-Type: application/json
Authorization: Basic jdoe1:password

View file

@ -0,0 +1,8 @@
### Load landing page
GET http://localhost:3000/ HTTP/1.1
### Failure redirect
POST http://localhost:3000/login HTTP/1.1
Content-Type: application/json
Authorization: Basic password:username

View file

@ -0,0 +1,113 @@
import 'package:angel3_auth/angel3_auth.dart';
import 'package:angel3_container/mirrors.dart';
import 'package:angel3_framework/angel3_framework.dart';
import 'package:angel3_framework/http.dart';
import 'package:collection/collection.dart' show IterableExtension;
import 'package:io/ansi.dart';
import 'package:logging/logging.dart';
import 'package:collection/collection.dart';
class User extends Model {
String? username, password;
User({this.username, this.password});
static User parse(Map<String, dynamic> map) {
return User(
username: map['username'],
password: map['password'],
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'username': username,
'password': password,
'created_at': createdAt?.toIso8601String(),
'updated_at': updatedAt?.toIso8601String()
};
}
}
/*
* Backend for callback test cases
*/
void main() async {
hierarchicalLoggingEnabled = true;
Angel app = Angel(reflector: MirrorsReflector());
AngelHttp angelHttp = AngelHttp(app);
app.use('/users', MapService());
var oldErrorHandler = app.errorHandler;
app.errorHandler = (e, req, res) {
app.logger.severe(e.message, e, e.stackTrace ?? StackTrace.current);
return oldErrorHandler(e, req, res);
};
app.logger = Logger('angel3_auth')
..level = Level.FINEST
..onRecord.listen((rec) {
print(rec);
if (rec.error != null) {
print(yellow.wrap(rec.error.toString()));
}
if (rec.stackTrace != null) {
print(yellow.wrap(rec.stackTrace.toString()));
}
});
await app
.findService('users')
?.create({'username': 'jdoe1', 'password': 'password'});
var auth = AngelAuth<User>(
serializer: (u) => u.id ?? '',
deserializer: (id) async =>
await app.findService('users')?.read(id) as User);
//auth.serializer = (u) => u.id;
//auth.deserializer =
// (id) async => await app.findService('users')!.read(id) as User;
await app.configure(auth.configureServer);
auth.strategies['local'] = LocalAuthStrategy((username, password) async {
var users = await app
.findService('users')
?.index()
.then((it) => it.map<User>((m) => User.parse(m)).toList());
var result = users?.firstWhereOrNull(
(user) => user.username == username && user.password == password);
return Future.value(result);
});
app.post(
'/login',
auth.authenticate('local', AngelAuthOptions(callback: (req, res, token) {
res
..write('Hello!')
..close();
})));
app.get('/', (req, res) => res.write("Hello"));
app.chain([
(req, res) {
if (!req.container!.has<User>()) {
req.container!.registerSingleton<User>(
User(username: req.params['name']?.toString()));
}
return true;
}
]).post(
'/existing/:name',
auth.authenticate('local'),
);
await angelHttp.startServer('127.0.0.1', 3000);
}

View file

@ -0,0 +1,62 @@
import 'dart:async';
import 'package:angel3_auth/angel3_auth.dart';
import 'package:angel3_container/mirrors.dart';
import 'package:angel3_framework/angel3_framework.dart';
import 'package:angel3_framework/http.dart';
import 'package:logging/logging.dart';
final Map<String, String> sampleUser = {'hello': 'world'};
final AngelAuth<Map<String, String>> auth = AngelAuth<Map<String, String>>(
serializer: (user) async => '1337', deserializer: (id) async => sampleUser);
//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);
Future<Map<String, String>> verifier(String? username, String? password) async {
if (username == 'username' && password == 'password') {
return sampleUser;
} else {
return {};
}
}
Future wireAuth(Angel app) async {
auth.strategies['local'] = LocalAuthStrategy(verifier);
await app.configure(auth.configureServer);
}
void main() async {
Angel app = Angel(reflector: MirrorsReflector());
AngelHttp angelHttp = AngelHttp(app, useZone: false);
await app.configure(wireAuth);
app.get('/hello', (req, res) {
// => 'Woo auth'
return 'Woo auth';
}, 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: [
requireAuthentication<Map<String, String>>(),
]);
app.get('/failure', (req, res) => 'nope');
app.logger = Logger('local_test')
..onRecord.listen((rec) {
print(
'${rec.time}: ${rec.level.name}: ${rec.loggerName}: ${rec.message}');
if (rec.error != null) {
print(rec.error);
print(rec.stackTrace);
}
});
await angelHttp.startServer('127.0.0.1', 3000);
}

View file

@ -66,7 +66,8 @@ class LocalAuthStrategy<User> extends AuthStrategy<User> {
return null; return null;
} }
return verificationResult; // Allow non-null to pass through
//return verificationResult;
} }
} }

View file

@ -16,7 +16,7 @@ class User extends Model {
User({this.username, this.password}); User({this.username, this.password});
static User parse(Map map) { static User parse(Map<String, dynamic> map) {
return User( return User(
username: map['username'] as String?, username: map['username'] as String?,
password: map['password'] as String?, password: map['password'] as String?,
@ -41,6 +41,7 @@ void main() {
http.Client? client; http.Client? client;
HttpServer server; HttpServer server;
String? url; String? url;
String? encodedAuth;
setUp(() async { setUp(() async {
hierarchicalLoggingEnabled = true; hierarchicalLoggingEnabled = true;
@ -54,7 +55,7 @@ void main() {
return oldErrorHandler(e, req, res); return oldErrorHandler(e, req, res);
}; };
app.logger = Logger('angel_auth') app.logger = Logger('angel3_auth')
..level = Level.FINEST ..level = Level.FINEST
..onRecord.listen((rec) { ..onRecord.listen((rec) {
print(rec); print(rec);
@ -86,7 +87,7 @@ void main() {
var users = await app var users = await app
.findService('users') .findService('users')
?.index() ?.index()
.then((it) => it.map<User>((m) => User.parse(m as Map)).toList()); .then((it) => it.map<User>((m) => User.parse(m)).toList());
var result = users?.firstWhereOrNull( var result = users?.firstWhereOrNull(
(user) => user.username == username && user.password == password); (user) => user.username == username && user.password == password);
@ -116,6 +117,8 @@ void main() {
auth.authenticate('local'), auth.authenticate('local'),
); );
encodedAuth = base64.encode(utf8.encode('jdoe1:password'));
client = http.Client(); client = http.Client();
server = await angelHttp.startServer(); server = await angelHttp.startServer();
url = 'http://${server.address.address}:${server.port}'; url = 'http://${server.address.address}:${server.port}';
@ -131,7 +134,7 @@ void main() {
test('login', () async { test('login', () async {
final response = await client!.post(Uri.parse('$url/login'), final response = await client!.post(Uri.parse('$url/login'),
body: {'username': 'jdoe1', 'password': 'password'}); headers: {'Authorization': 'Basic $encodedAuth'});
print('Response: ${response.body}'); print('Response: ${response.body}');
expect(response.body, equals('Hello!')); expect(response.body, equals('Hello!'));
}, },

View file

@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:angel3_auth/angel3_auth.dart'; import 'package:angel3_auth/angel3_auth.dart';
import 'package:angel3_container/mirrors.dart';
import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/angel3_framework.dart';
import 'package:angel3_framework/http.dart'; import 'package:angel3_framework/http.dart';
import 'dart:convert'; import 'dart:convert';
@ -9,7 +10,7 @@ import 'package:test/test.dart';
final AngelAuth<Map<String, String>> auth = AngelAuth<Map<String, String>>( final AngelAuth<Map<String, String>> auth = AngelAuth<Map<String, String>>(
serializer: (user) async => '1337', deserializer: (id) async => sampleUser); serializer: (user) async => '1337', deserializer: (id) async => sampleUser);
var headers = <String, String>{'accept': 'application/json'}; //var headers = <String, String>{'accept': 'application/json'};
var localOpts = AngelAuthOptions<Map<String, String>>( var localOpts = AngelAuthOptions<Map<String, String>>(
failureRedirect: '/failure', successRedirect: '/success'); failureRedirect: '/failure', successRedirect: '/success');
var localOpts2 = var localOpts2 =
@ -42,7 +43,7 @@ void main() async {
setUp(() async { setUp(() async {
client = http.Client(); client = http.Client();
app = Angel(); app = Angel(reflector: MirrorsReflector());
angelHttp = AngelHttp(app, useZone: false); angelHttp = AngelHttp(app, useZone: false);
await app.configure(wireAuth); await app.configure(wireAuth);
app.get('/hello', (req, res) { app.get('/hello', (req, res) {
@ -88,19 +89,22 @@ void main() async {
}); });
test('successRedirect', () async { test('successRedirect', () async {
var postData = {'username': 'username', 'password': 'password'}; //var postData = {'username': 'username', 'password': 'password'};
var encodedAuth = base64.encode(utf8.encode('username:password'));
var response = await client.post(Uri.parse('$url/login'), var response = await client.post(Uri.parse('$url/login'),
body: json.encode(postData), headers: {'Authorization': 'Basic $encodedAuth'});
headers: {'content-type': 'application/json'});
expect(response.statusCode, equals(302)); expect(response.statusCode, equals(302));
expect(response.headers['location'], equals('/success')); expect(response.headers['location'], equals('/success'));
}); });
test('failureRedirect', () async { test('failureRedirect', () async {
var postData = {'username': 'password', 'password': 'username'}; //var postData = {'username': 'password', 'password': 'username'};
var encodedAuth = base64.encode(utf8.encode('password:username'));
var response = await client.post(Uri.parse('$url/login'), var response = await client.post(Uri.parse('$url/login'),
body: json.encode(postData), //body: json.encode(postData),
headers: {'content-type': 'application/json'}); headers: {'Authorization': 'Basic $encodedAuth'});
print('Status Code: ${response.statusCode}'); print('Status Code: ${response.statusCode}');
print(response.headers); print(response.headers);
print(response.body); print(response.body);

View file

@ -79,11 +79,6 @@ class MapService extends Service<String?, Map<String, dynamic>> {
@override @override
Future<Map<String, dynamic>> create(Map<String, dynamic> data, Future<Map<String, dynamic>> create(Map<String, dynamic> data,
[Map<String, dynamic>? params]) { [Map<String, dynamic>? params]) {
//if (data is! Map) {
// throw AngelHttpException.badRequest(
// message:
// 'MapService does not support `create` with ${data.runtimeType}.');
//}
var now = DateTime.now().toIso8601String(); var now = DateTime.now().toIso8601String();
var result = Map<String, dynamic>.from(data); var result = Map<String, dynamic>.from(data);

View file

@ -7,7 +7,7 @@ environment:
sdk: '>=3.0.0 <4.0.0' sdk: '>=3.0.0 <4.0.0'
dependencies: dependencies:
angel3_framework: ^8.0.0 angel3_framework: ^8.0.0
file: ^6.1.2 file: ^7.0.0
markdown: ^7.1.0 markdown: ^7.1.0
dev_dependencies: dev_dependencies:
angel3_test: ^8.0.0 angel3_test: ^8.0.0