From 38cc17e3819fc11dfe74c9323e3a3c7daac12c23 Mon Sep 17 00:00:00 2001 From: thomashii Date: Thu, 15 Jul 2021 16:11:54 +0800 Subject: [PATCH] Updated client --- packages/client/CHANGELOG.md | 5 ++ packages/client/README.md | 4 +- packages/client/lib/angel3_client.dart | 3 ++ packages/client/lib/base_angel_client.dart | 6 +++ packages/client/lib/io.dart | 8 ++- packages/client/pubspec.yaml | 4 +- packages/client/test/all_test.dart | 1 + packages/client/test/auth_test.dart | 59 ++++++++++++++++++++++ 8 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 packages/client/test/auth_test.dart diff --git a/packages/client/CHANGELOG.md b/packages/client/CHANGELOG.md index 5aa8f489..79294476 100644 --- a/packages/client/CHANGELOG.md +++ b/packages/client/CHANGELOG.md @@ -1,6 +1,11 @@ # Change Log +## 4.0.2 + +* Added logging +* Added unit test for authentication + ## 4.0.1 * Updated README diff --git a/packages/client/README.md b/packages/client/README.md index c05116f0..b080b089 100644 --- a/packages/client/README.md +++ b/packages/client/README.md @@ -1,12 +1,12 @@ # Angel3 Client -[![version](https://img.shields.io/badge/pub-v4.0.1-brightgreen)](https://pub.dartlang.org/packages/angel3_client) +[![version](https://img.shields.io/badge/pub-v4.0.2-brightgreen)](https://pub.dartlang.org/packages/angel3_client) [![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) [![License](https://img.shields.io/github/license/dukefirehawk/angel)](https://github.com/dukefirehawk/angel/tree/angel3/packages/client/LICENSE) -A browser, mobile and command line based client that supports querying Angel3 servers +A browser, mobile and command line based client that supports querying Angel3 backend. ## Usage diff --git a/packages/client/lib/angel3_client.dart b/packages/client/lib/angel3_client.dart index 08731ce9..9d4df1de 100644 --- a/packages/client/lib/angel3_client.dart +++ b/packages/client/lib/angel3_client.dart @@ -5,6 +5,7 @@ import 'dart:async'; import 'package:collection/collection.dart'; import 'dart:convert'; import 'package:http/http.dart' as http; +import 'package:logging/logging.dart'; export 'package:angel3_http_exception/angel3_http_exception.dart'; /// A function that configures an [Angel] client in some way. @@ -18,6 +19,8 @@ typedef AngelDeserializer = T? Function(dynamic x); /// Represents an Angel server that we are querying. abstract class Angel extends http.BaseClient { + final _log = Logger('Angel'); + /// A mutable member. When this is set, it holds a JSON Web Token /// that is automatically attached to every request sent. /// diff --git a/packages/client/lib/base_angel_client.dart b/packages/client/lib/base_angel_client.dart index 19858048..30dbb6b3 100644 --- a/packages/client/lib/base_angel_client.dart +++ b/packages/client/lib/base_angel_client.dart @@ -8,6 +8,7 @@ import 'package:http/src/request.dart' as http; import 'package:http/src/response.dart' as http; import 'package:http/src/streamed_response.dart' as http; import 'package:path/path.dart'; +import 'package:logging/logging.dart'; import 'angel3_client.dart'; const Map _readHeaders = {'Accept': 'application/json'}; @@ -47,6 +48,7 @@ AngelHttpException failure(http.Response response, } abstract class BaseAngelClient extends Angel { + final _log = Logger('BaseAngelClient'); final StreamController _onAuthenticated = StreamController(); final List _services = []; @@ -89,6 +91,8 @@ abstract class BaseAngelClient extends Angel { try { //var v = json.decode(response.body); + _log.info(response.headers); + var v = jsonDecode(response.body); if (v is! Map || !v.containsKey('data') || !v.containsKey('token')) { @@ -102,6 +106,7 @@ abstract class BaseAngelClient extends Angel { } on AngelHttpException { rethrow; } catch (e, st) { + _log.severe('Authentication failed'); throw failure(response, error: e, stack: st); } } @@ -147,6 +152,7 @@ abstract class BaseAngelClient extends Angel { request.bodyFields = body.map((k, v) => MapEntry(k, v is String ? v : v.toString())); } else { + _log.severe('Body is not a String, List, or Map'); throw ArgumentError.value(body, 'body', 'must be a String, List, or Map.'); } diff --git a/packages/client/lib/io.dart b/packages/client/lib/io.dart index 30e93d58..752d4d00 100644 --- a/packages/client/lib/io.dart +++ b/packages/client/lib/io.dart @@ -5,12 +5,14 @@ import 'dart:async'; import 'package:http/http.dart' as http; import 'package:angel3_json_god/angel3_json_god.dart' as god; import 'package:path/path.dart' as p; +import 'package:logging/logging.dart'; import 'angel3_client.dart'; import 'base_angel_client.dart'; export 'angel3_client.dart'; /// Queries an Angel server via REST. class Rest extends BaseAngelClient { + //final _log = Logger('REST'); final List _services = []; Rest(String path) : super(http.Client() as http.BaseClient, path); @@ -42,6 +44,8 @@ class Rest extends BaseAngelClient { /// Queries an Angel service via REST. class RestService extends BaseAngelService { + final _log = Logger('RestService'); + final Type? type; RestService(http.BaseClient client, BaseAngelClient app, url, this.type) @@ -49,7 +53,7 @@ class RestService extends BaseAngelService { @override Data? deserialize(x) { - print(x); + _log.info(x); if (type != null) { return x.runtimeType == type ? x as Data? @@ -61,7 +65,7 @@ class RestService extends BaseAngelService { @override String makeBody(x) { - print(x); + _log.info(x); if (type != null) { return super.makeBody(god.serializeObject(x)); } diff --git a/packages/client/pubspec.yaml b/packages/client/pubspec.yaml index d9d78965..d415242b 100644 --- a/packages/client/pubspec.yaml +++ b/packages/client/pubspec.yaml @@ -1,5 +1,5 @@ name: angel3_client -version: 4.0.1 +version: 4.0.2 description: A browser, mobile and command line based client that supports querying Angel3 servers homepage: https://angel3-framework.web.app/ repository: https://github.com/dukefirehawk/angel/tree/angel3/packages/client @@ -12,11 +12,13 @@ dependencies: http: ^0.13.1 meta: ^1.3.0 path: ^1.8.0 + logging: ^1.0.0 dev_dependencies: angel3_framework: ^4.0.0 angel3_model: ^3.0.0 angel3_mock_request: ^2.0.0 angel3_container: ^3.0.0 + angel3_auth: ^4.0.0 async: ^2.6.1 build_runner: ^1.12.2 build_web_compilers: ^2.16.5 diff --git a/packages/client/test/all_test.dart b/packages/client/test/all_test.dart index ad3e8128..4a4e73f9 100644 --- a/packages/client/test/all_test.dart +++ b/packages/client/test/all_test.dart @@ -76,6 +76,7 @@ void main() { test('credentials send right body', () async { await app .authenticate(type: 'local', credentials: {'username': 'password'}); + print(app.client.spec?.headers); expect( await read(app.client.spec!.request.finalize()), json.encode({'username': 'password'}), diff --git a/packages/client/test/auth_test.dart b/packages/client/test/auth_test.dart new file mode 100644 index 00000000..fbb243b2 --- /dev/null +++ b/packages/client/test/auth_test.dart @@ -0,0 +1,59 @@ +import 'package:angel3_auth/angel3_auth.dart'; +import 'package:angel3_client/io.dart' as c; +import 'package:angel3_framework/angel3_framework.dart'; +import 'package:angel3_framework/http.dart'; +import 'package:logging/logging.dart'; +import 'package:test/test.dart'; + +const Map USER = {'username': 'foo', 'password': 'bar'}; +var localOpts = AngelAuthOptions>(canRespondWithJson: true); + +void main() { + late Angel app; + late AngelHttp http; + late c.Angel client; + + setUp(() async { + app = Angel(); + http = AngelHttp(app, useZone: false); + var auth = AngelAuth( + serializer: (_) async => 'baz', deserializer: (_) async => USER); + + auth.strategies['local'] = LocalAuthStrategy( + (username, password) async { + if (username == 'foo' && password == 'bar') { + return USER; + } + + return {}; + }, + ); + + app.post('/auth/local', auth.authenticate('local', localOpts)); + + await app.configure(auth.configureServer); + + app.logger = Logger('auth_test') + ..onRecord.listen((rec) { + print( + '${rec.time}: ${rec.level.name}: ${rec.loggerName}: ${rec.message}'); + }); + + var server = await http.startServer(); + + client = c.Rest('http://${server.address.address}:${server.port}'); + }); + + tearDown(() { + http.close(); + client.close(); + }); + + test('auth event fires', () async { + var localAuth = await client.authenticate(type: 'local', credentials: USER); + print('JWT: ${localAuth.token}'); + print('Data: ${localAuth.data}'); + + expect(localAuth.data, USER); + }); +}