Added getParameters

This commit is contained in:
Tobe O 2018-03-30 12:44:15 -04:00
parent 3944a3f482
commit ed3cb579ae
8 changed files with 73 additions and 43 deletions

View file

@ -5,8 +5,6 @@
<excludeFolder url="file://$MODULE_DIR$/.pub" />
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/example/packages" />
<excludeFolder url="file://$MODULE_DIR$/packages" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>

View file

@ -1,6 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Github Auth Server" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application" singleton="true">
<option name="filePath" value="$PROJECT_DIR$/example/github.dart" />
<option name="filePath" value="$PROJECT_DIR$/example/main.dart" />
<option name="workingDirectory" value="$PROJECT_DIR$" />
<method />
</configuration>

2
CHANGELOG.md Normal file
View file

@ -0,0 +1,2 @@
# 1.0.2
Added `getParameters` to `AngelOAuth2Options`.

View file

@ -1,6 +1,6 @@
# auth_oauth2
[![version 1.0.1](https://img.shields.io/badge/pub-1.0.1-brightgreen.svg)](https://pub.dartlang.org/packages/angel_auth_oauth2)
[![Pub](https://img.shields.io/pub/v/angel_auth_oauth2.svg)](https://pub.dartlang.org/packages/angel_auth_oauth2)
`package:angel_auth` strategy for OAuth2 login, i.e. Facebook or Github.
@ -13,7 +13,7 @@ configureServer(Angel app) async {
var opts = new AngelOAuth2Options.fromJson(map);
// Create in-place:
const AngelAuthOAuth2Options OAUTH2_CONFIG = const AngelAuthOAuth2Options(
var opts = const AngelAuthOAuth2Options(
callback: '<callback-url>',
key: '<client-id>',
secret: '<client-secret>',
@ -98,9 +98,31 @@ you can add it in the `AngelOAuth2Options` constructor:
```dart
configureServer(Angel app) async {
const AngelOAuth2Options OPTS = const AngelOAuth2Options(
var opts = const AngelOAuth2Options(
// ...
delimiter: ','
);
}
```
## Handling non-JSON responses
Many OAuth2 providers do not follow the specification, and do not return
`application/json` responses.
You can add a `getParameters` callback to parse the contents of any arbitrary
response:
```dart
var opts = const AngelOAuth2Options(
// ...
getParameters: (contentType, body) {
if (contentType.type == 'application') {
if (contentType.subtype == 'x-www-form-urlencoded')
return Uri.splitQueryString(body);
else if (contentType.subtype == 'json') return JSON.decode(body);
}
throw new FormatException('Invalid content-type $contentType; expected application/x-www-form-urlencoded or application/json.');
}
);
```

View file

@ -1,31 +1,43 @@
import 'dart:convert';
import 'dart:io';
import 'package:angel_auth/angel_auth.dart';
import 'package:angel_diagnostics/angel_diagnostics.dart';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_framework/common.dart';
import 'package:angel_auth_oauth2/angel_auth_oauth2.dart';
import 'package:logging/logging.dart';
import 'package:oauth2/oauth2.dart' as oauth2;
const AngelAuthOAuth2Options OAUTH2_CONFIG = const AngelAuthOAuth2Options(
final AngelAuthOAuth2Options oAuth2Config = new AngelAuthOAuth2Options(
callback: 'http://localhost:3000/auth/github/callback',
key: '6caeaf5d4c04936ec34f',
secret: '178360518cf9de4802e2346a4b6ebec525dc4427',
authorizationEndpoint: 'http://github.com/login/oauth/authorize',
tokenEndpoint: 'https://github.com/login/oauth/access_token');
tokenEndpoint: 'https://github.com/login/oauth/access_token',
getParameters: (contentType, body) {
if (contentType.type == 'application') {
if (contentType.subtype == 'x-www-form-urlencoded')
return Uri.splitQueryString(body);
else if (contentType.subtype == 'json') return JSON.decode(body);
}
throw new FormatException('Invalid content-type $contentType; expected application/x-www-form-urlencoded or application/json.');
});
main() async {
var app = new Angel();
app.lazyParseBodies = true;
app.use('/users', new MapService());
var auth = new AngelAuth(jwtKey: 'oauth2 example secret', allowCookie: false);
var auth =
new AngelAuth<User>(jwtKey: 'oauth2 example secret', allowCookie: false);
auth.deserializer =
(id) => app.service('users').read(id).then((u) => User.parse(u));
auth.deserializer = app.service('users').read;
auth.serializer = (User user) async => user.id;
auth.strategies.add(
new OAuth2Strategy('github', OAUTH2_CONFIG, (oauth2.Client client) async {
new OAuth2Strategy('github', oAuth2Config, (oauth2.Client client) async {
var response = await client.get('https://api.github.com/user');
var ghUser = JSON.decode(response.body);
var id = ghUser['id'];
@ -41,7 +53,7 @@ main() async {
// Otherwise,create a user
return await app
.service('users')
.create({'githubId': id}).then(User.parse);
.create({'githubId': id}).then((u) => User.parse(u));
}
}));
@ -57,10 +69,12 @@ main() async {
res.write('Your JWT: $jwt');
})));
await app.configure(auth);
await app.configure(logRequests());
await app.configure(auth.configureServer);
var server = await app.startServer(InternetAddress.LOOPBACK_IP_V4, 3000);
app.logger = new Logger('angel')..onRecord.listen(print);
var http = new AngelHttp(app);
var server = await http.startServer(InternetAddress.LOOPBACK_IP_V4, 3000);
var url = 'http://${server.address.address}:${server.port}';
print('Listening on $url');
print('View user listing: $url/users');

View file

@ -2,21 +2,18 @@ library angel_auth_oauth2;
import 'dart:async';
import 'package:angel_auth/angel_auth.dart';
import 'package:angel_framework/src/http/response_context.dart';
import 'package:angel_framework/src/http/request_context.dart';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_validate/angel_validate.dart';
import 'package:http_parser/http_parser.dart';
import 'package:oauth2/oauth2.dart' as oauth2;
/// Loads a user profile via OAuth2.
typedef Future OAuth2Verifier(oauth2.Client client);
final Validator OAUTH2_OPTIONS_SCHEMA = new Validator({
'key*': isString,
'secret*': isString,
'authorizationEndpoint*': isString,
'tokenEndpoint*': isString,
'authorizationEndpoint*': anyOf(isString, const isInstanceOf<Uri>()),
'tokenEndpoint*': anyOf(isString, const isInstanceOf<Uri>()),
'callback*': isString,
'scopes': new isInstanceOf<Iterable<String>>()
'scopes': const isInstanceOf<Iterable<String>>()
}, defaultValues: {
'scopes': <String>[]
}, customErrorMessages: {
@ -32,10 +29,10 @@ class AngelAuthOAuth2Options {
final String secret;
/// The remote endpoint that prompts external users for authentication credentials.
final String authorizationEndpoint;
final authorizationEndpoint;
/// The remote endpoint that exchanges auth codes for access tokens.
final String tokenEndpoint;
final tokenEndpoint;
/// The callback URL that the OAuth2 server should redirect authenticated users to.
final String callback;
@ -44,6 +41,8 @@ class AngelAuthOAuth2Options {
final String delimiter;
final Iterable<String> scopes;
final Map<String, String> Function(MediaType, String) getParameters;
const AngelAuthOAuth2Options(
{this.key,
this.secret,
@ -51,7 +50,8 @@ class AngelAuthOAuth2Options {
this.tokenEndpoint,
this.callback,
this.delimiter: ' ',
this.scopes: const []});
this.scopes: const [],
this.getParameters});
factory AngelAuthOAuth2Options.fromJson(Map json) =>
new AngelAuthOAuth2Options(
@ -62,7 +62,7 @@ class AngelAuthOAuth2Options {
callback: json['callback'],
scopes: json['scopes'] ?? <String>[]);
Map<String, String> toJson() {
Map<String, dynamic> toJson() {
return {
'key': key,
'secret': secret,
@ -74,19 +74,14 @@ class AngelAuthOAuth2Options {
}
}
class OAuth2Strategy implements AuthStrategy {
String _name;
class OAuth2Strategy<T> implements AuthStrategy {
final FutureOr<T> Function(oauth2.Client) verifier;
String name;
AngelAuthOAuth2Options _options;
final OAuth2Verifier verifier;
@override
String get name => _name;
@override
set name(String value) => _name = name;
/// [options] can be either a `Map` or an instance of [AngelAuthOAuth2Options].
OAuth2Strategy(this._name, options, this.verifier) {
OAuth2Strategy(this.name, options, this.verifier) {
if (options is AngelAuthOAuth2Options)
_options = options;
else if (options is Map)
@ -102,7 +97,8 @@ class OAuth2Strategy implements AuthStrategy {
Uri.parse(_options.authorizationEndpoint),
Uri.parse(_options.tokenEndpoint),
secret: _options.secret,
delimiter: _options.delimiter ?? ' ');
delimiter: _options.delimiter ?? ' ',
getParameters: _options.getParameters);
@override
Future authenticate(RequestContext req, ResponseContext res,

View file

@ -1,6 +1,6 @@
name: angel_auth_oauth2
description: angel_auth strategy for OAuth2 login, i.e. Facebook.
version: 1.0.1
version: 1.0.2
author: Tobe O <thosakwe@gmail.com>
environment:
sdk: ">=1.19.0"
@ -8,6 +8,4 @@ homepage: https://github.com/angel-dart/auth_oauth2.git
dependencies:
angel_auth: ^1.0.0-dev
angel_validate: ^1.0.0-beta
oauth2: ^1.0.0
dev_dependencies:
angel_diagnostics: ^1.0.0-dev
oauth2: ^1.0.0