device code done
This commit is contained in:
parent
7b42d97b45
commit
2e50f7f71b
2 changed files with 49 additions and 3 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue