device code done

This commit is contained in:
Tobe O 2018-12-14 02:24:32 -05:00
parent 7b42d97b45
commit 2e50f7f71b
2 changed files with 49 additions and 3 deletions

View file

@ -46,6 +46,28 @@ class ErrorResponse {
/// The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.
static const String temporarilyUnavailable = 'temporarily_unavailable';
/// The authorization request is still pending as the end user hasn't
/// yet completed the user interaction steps (Section 3.3). The
/// client SHOULD repeat the Access Token Request to the token
/// endpoint (a process known as polling). Before each new request
/// the client MUST wait at least the number of seconds specified by
/// the "interval" parameter of the Device Authorization Response (see
/// Section 3.2), or 5 seconds if none was provided, and respect any
/// increase in the polling interval required by the "slow_down"
/// error.
static const String authorizationPending = 'authorization_pending';
/// A variant of "authorization_pending", the authorization request is
/// still pending and polling should continue, but the interval MUST
/// be increased by 5 seconds for this and all subsequent requests.
static const String slowDown = 'slow_down';
/// The "device_code" has expired and the device flow authorization
/// session has concluded. The client MAY commence a new Device
/// Authorization Request but SHOULD wait for user interaction before
/// restarting to avoid unnecessary polling.
static const String expiredToken = 'expired_token';
/// A short string representing the error.
final String code;

View file

@ -173,7 +173,7 @@ abstract class AuthorizationServer<Client, User> {
}
/// Performs a device code grant.
FutureOr<DeviceCodeResponse> deviceCodeGrant(Client client,
FutureOr<DeviceCodeResponse> requestDeviceCode(Client client,
Iterable<String> scopes, RequestContext req, ResponseContext res) async {
var body = await req.parseBody().then((_) => req.bodyAsMap);
throw new AuthorizationException(
@ -186,6 +186,24 @@ abstract class AuthorizationServer<Client, User> {
);
}
/// Produces an authorization token from a given device code.
FutureOr<AuthorizationTokenResponse> exchangeDeviceCodeForToken(
Client client,
String deviceCode,
String state,
RequestContext req,
ResponseContext res) async {
var body = await req.parseBody().then((_) => req.bodyAsMap);
throw new AuthorizationException(
new ErrorResponse(
ErrorResponse.unsupportedResponseType,
'Device code grants are not supported.',
body['state']?.toString() ?? '',
),
statusCode: 400,
);
}
/// A request handler that invokes the correct logic, depending on which type
/// of grant the client is requesting.
Future authorizationEndpoint(RequestContext req, ResponseContext res) async {
@ -320,7 +338,8 @@ abstract class AuthorizationServer<Client, User> {
state = body['state']?.toString() ?? '';
var grantType = await _getParam(req, 'grant_type', state, body: true, throwIfEmpty: false);
var grantType = await _getParam(req, 'grant_type', state,
body: true, throwIfEmpty: false);
if (grantType != 'authorization_code') {
var match =
@ -402,8 +421,13 @@ abstract class AuthorizationServer<Client, User> {
} else if (grantType == null) {
// This is a device code grant.
var scopes = await _getScopes(req, body: true);
var deviceCodeResponse = await deviceCodeGrant(client, scopes, req, res);
var deviceCodeResponse =
await requestDeviceCode(client, scopes, req, res);
return deviceCodeResponse.toJson();
} else if (grantType == 'urn:ietf:params:oauth:grant-type:device_code') {
var deviceCode = await _getParam(req, 'device_code', state, body: true);
response = await exchangeDeviceCodeForToken(
client, deviceCode, state, req, res);
}
if (response != null) {