exchange method
Exchanges a valid authorization code for an AuthToken
.
If the authorization code has not expired, has not been used, matches the client ID,
and the client secret is correct, it will return a valid AuthToken
. Otherwise,
it will throw an appropriate AuthRequestError.
Implementation
Future<AuthToken> exchange(
String? authCodeString, String? clientID, String? clientSecret,
{int expirationInSeconds = 3600}) async {
if (clientID == null) {
throw AuthServerException(AuthRequestError.invalidClient, null);
}
final AuthClient? client = await getClient(clientID);
if (client == null) {
throw AuthServerException(AuthRequestError.invalidClient, null);
}
if (authCodeString == null) {
throw AuthServerException(AuthRequestError.invalidRequest, null);
}
if (clientSecret == null) {
throw AuthServerException(AuthRequestError.invalidClient, client);
}
if (client.hashedSecret != hashPassword(clientSecret, client.salt!)) {
throw AuthServerException(AuthRequestError.invalidClient, client);
}
final AuthCode? authCode = await delegate.getCode(this, authCodeString);
if (authCode == null) {
throw AuthServerException(AuthRequestError.invalidGrant, client);
}
// check if valid still
if (authCode.isExpired) {
await delegate.removeCode(this, authCode.code!);
throw AuthServerException(AuthRequestError.invalidGrant, client);
}
// check that client ids match
if (authCode.clientID != client.id) {
throw AuthServerException(AuthRequestError.invalidGrant, client);
}
// check to see if has already been used
if (authCode.hasBeenExchanged!) {
await delegate.removeToken(this, authCode);
throw AuthServerException(AuthRequestError.invalidGrant, client);
}
final token = _generateToken(
authCode.resourceOwnerIdentifier!, client.id!, expirationInSeconds,
scopes: authCode.requestedScopes!);
await delegate.addToken(this, token, issuedFrom: authCode);
return token;
}