device code done
This commit is contained in:
parent
7b42d97b45
commit
2e50f7f71b
2 changed files with 49 additions and 3 deletions
lib/src
|
@ -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.
|
/// 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';
|
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.
|
/// A short string representing the error.
|
||||||
final String code;
|
final String code;
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,7 @@ abstract class AuthorizationServer<Client, User> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Performs a device code grant.
|
/// Performs a device code grant.
|
||||||
FutureOr<DeviceCodeResponse> deviceCodeGrant(Client client,
|
FutureOr<DeviceCodeResponse> requestDeviceCode(Client client,
|
||||||
Iterable<String> scopes, RequestContext req, ResponseContext res) async {
|
Iterable<String> scopes, RequestContext req, ResponseContext res) async {
|
||||||
var body = await req.parseBody().then((_) => req.bodyAsMap);
|
var body = await req.parseBody().then((_) => req.bodyAsMap);
|
||||||
throw new AuthorizationException(
|
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
|
/// A request handler that invokes the correct logic, depending on which type
|
||||||
/// of grant the client is requesting.
|
/// of grant the client is requesting.
|
||||||
Future authorizationEndpoint(RequestContext req, ResponseContext res) async {
|
Future authorizationEndpoint(RequestContext req, ResponseContext res) async {
|
||||||
|
@ -320,7 +338,8 @@ abstract class AuthorizationServer<Client, User> {
|
||||||
|
|
||||||
state = body['state']?.toString() ?? '';
|
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') {
|
if (grantType != 'authorization_code') {
|
||||||
var match =
|
var match =
|
||||||
|
@ -402,8 +421,13 @@ abstract class AuthorizationServer<Client, User> {
|
||||||
} else if (grantType == null) {
|
} else if (grantType == null) {
|
||||||
// This is a device code grant.
|
// This is a device code grant.
|
||||||
var scopes = await _getScopes(req, body: true);
|
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();
|
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) {
|
if (response != null) {
|
||||||
|
|
Loading…
Reference in a new issue