diff --git a/CHANGELOG.md b/CHANGELOG.md index adeb958e..d5baa05a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ * Updated: angel3_container_generator * Updated: angel3_mock_request * Updated: angel3_framework -* Updated: angel3_auth (4 failed test cases) +* Updated: angel3_auth (1 failed test cases) * Updated: angel3_configuration * Updated: angel3_validate * 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_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_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) ## 7.0.0 diff --git a/packages/auth/CHANGELOG.md b/packages/auth/CHANGELOG.md index 45549833..be11b041 100644 --- a/packages/auth/CHANGELOG.md +++ b/packages/auth/CHANGELOG.md @@ -4,6 +4,10 @@ * Require Dart >= 3.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 diff --git a/packages/auth/example/client/example1.http b/packages/auth/example/client/example1.http new file mode 100644 index 00000000..36bb9f52 --- /dev/null +++ b/packages/auth/example/client/example1.http @@ -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 + diff --git a/packages/auth/example/client/example2.http b/packages/auth/example/client/example2.http new file mode 100644 index 00000000..6a4ddc51 --- /dev/null +++ b/packages/auth/example/client/example2.http @@ -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 + diff --git a/packages/auth/example/example1.dart b/packages/auth/example/example1.dart new file mode 100644 index 00000000..a39cd25b --- /dev/null +++ b/packages/auth/example/example1.dart @@ -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 map) { + return User( + username: map['username'], + password: map['password'], + ); + } + + Map 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( + 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((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()) { + req.container!.registerSingleton( + User(username: req.params['name']?.toString())); + } + return true; + } + ]).post( + '/existing/:name', + auth.authenticate('local'), + ); + + await angelHttp.startServer('127.0.0.1', 3000); +} diff --git a/packages/auth/example/example2.dart b/packages/auth/example/example2.dart new file mode 100644 index 00000000..5b1e0dde --- /dev/null +++ b/packages/auth/example/example2.dart @@ -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 sampleUser = {'hello': 'world'}; + +final AngelAuth> auth = AngelAuth>( + serializer: (user) async => '1337', deserializer: (id) async => sampleUser); +//var headers = {'accept': 'application/json'}; +var localOpts = AngelAuthOptions>( + failureRedirect: '/failure', successRedirect: '/success'); +var localOpts2 = + AngelAuthOptions>(canRespondWithJson: false); + +Future> 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>(), + ]); + + 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); +} diff --git a/packages/auth/lib/src/strategies/local.dart b/packages/auth/lib/src/strategies/local.dart index a0407153..b8e1b721 100644 --- a/packages/auth/lib/src/strategies/local.dart +++ b/packages/auth/lib/src/strategies/local.dart @@ -66,7 +66,8 @@ class LocalAuthStrategy extends AuthStrategy { return null; } - return verificationResult; + // Allow non-null to pass through + //return verificationResult; } } diff --git a/packages/auth/test/callback_test.dart b/packages/auth/test/callback_test.dart index 9609fcd1..1030a2bf 100644 --- a/packages/auth/test/callback_test.dart +++ b/packages/auth/test/callback_test.dart @@ -16,7 +16,7 @@ class User extends Model { User({this.username, this.password}); - static User parse(Map map) { + static User parse(Map map) { return User( username: map['username'] as String?, password: map['password'] as String?, @@ -41,6 +41,7 @@ void main() { http.Client? client; HttpServer server; String? url; + String? encodedAuth; setUp(() async { hierarchicalLoggingEnabled = true; @@ -54,7 +55,7 @@ void main() { return oldErrorHandler(e, req, res); }; - app.logger = Logger('angel_auth') + app.logger = Logger('angel3_auth') ..level = Level.FINEST ..onRecord.listen((rec) { print(rec); @@ -86,7 +87,7 @@ void main() { var users = await app .findService('users') ?.index() - .then((it) => it.map((m) => User.parse(m as Map)).toList()); + .then((it) => it.map((m) => User.parse(m)).toList()); var result = users?.firstWhereOrNull( (user) => user.username == username && user.password == password); @@ -116,6 +117,8 @@ void main() { auth.authenticate('local'), ); + encodedAuth = base64.encode(utf8.encode('jdoe1:password')); + client = http.Client(); server = await angelHttp.startServer(); url = 'http://${server.address.address}:${server.port}'; @@ -131,7 +134,7 @@ void main() { test('login', () async { final response = await client!.post(Uri.parse('$url/login'), - body: {'username': 'jdoe1', 'password': 'password'}); + headers: {'Authorization': 'Basic $encodedAuth'}); print('Response: ${response.body}'); expect(response.body, equals('Hello!')); }, diff --git a/packages/auth/test/local_test.dart b/packages/auth/test/local_test.dart index 9b92f29b..303e6d7b 100644 --- a/packages/auth/test/local_test.dart +++ b/packages/auth/test/local_test.dart @@ -1,5 +1,6 @@ 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 'dart:convert'; @@ -9,7 +10,7 @@ import 'package:test/test.dart'; final AngelAuth> auth = AngelAuth>( serializer: (user) async => '1337', deserializer: (id) async => sampleUser); -var headers = {'accept': 'application/json'}; +//var headers = {'accept': 'application/json'}; var localOpts = AngelAuthOptions>( failureRedirect: '/failure', successRedirect: '/success'); var localOpts2 = @@ -42,7 +43,7 @@ void main() async { setUp(() async { client = http.Client(); - app = Angel(); + app = Angel(reflector: MirrorsReflector()); angelHttp = AngelHttp(app, useZone: false); await app.configure(wireAuth); app.get('/hello', (req, res) { @@ -88,19 +89,22 @@ void main() 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'), - body: json.encode(postData), - headers: {'content-type': 'application/json'}); + headers: {'Authorization': 'Basic $encodedAuth'}); expect(response.statusCode, equals(302)); expect(response.headers['location'], equals('/success')); }); 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'), - body: json.encode(postData), - headers: {'content-type': 'application/json'}); + //body: json.encode(postData), + headers: {'Authorization': 'Basic $encodedAuth'}); print('Status Code: ${response.statusCode}'); print(response.headers); print(response.body); diff --git a/packages/framework/lib/src/core/map_service.dart b/packages/framework/lib/src/core/map_service.dart index 00a89a23..ab7bf928 100644 --- a/packages/framework/lib/src/core/map_service.dart +++ b/packages/framework/lib/src/core/map_service.dart @@ -79,11 +79,6 @@ class MapService extends Service> { @override Future> create(Map data, [Map? params]) { - //if (data is! Map) { - // throw AngelHttpException.badRequest( - // message: - // 'MapService does not support `create` with ${data.runtimeType}.'); - //} var now = DateTime.now().toIso8601String(); var result = Map.from(data); diff --git a/packages/markdown/pubspec.yaml b/packages/markdown/pubspec.yaml index 9bcaeea3..fc3f0531 100644 --- a/packages/markdown/pubspec.yaml +++ b/packages/markdown/pubspec.yaml @@ -7,7 +7,7 @@ environment: sdk: '>=3.0.0 <4.0.0' dependencies: angel3_framework: ^8.0.0 - file: ^6.1.2 + file: ^7.0.0 markdown: ^7.1.0 dev_dependencies: angel3_test: ^8.0.0