From c89d11b172c842bf13f5ce47632de20012eddd1d Mon Sep 17 00:00:00 2001 From: rikbellens Date: Thu, 29 Dec 2022 16:12:14 +0100 Subject: [PATCH] feat: add support for password flow --- lib/src/openid.dart | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/lib/src/openid.dart b/lib/src/openid.dart index b6a43e1..f0f1058 100644 --- a/lib/src/openid.dart +++ b/lib/src/openid.dart @@ -335,7 +335,8 @@ enum FlowType { implicit, authorizationCode, proofKeyForCodeExchange, - jwtBearer + jwtBearer, + password, } class Flow { @@ -379,6 +380,20 @@ class Flow { }; } + /// Creates a new [Flow] for the password flow. + /// + /// This flow can be used for active authentication by highly-trusted + /// applications. Call [Flow.loginWithPassword] to authenticate a user with + /// their username and password. + Flow.password(Client client, + {List scopes = const ['openid', 'profile', 'email']}) + : this._( + FlowType.password, + '', + client, + scopes: scopes, + ); + Flow.authorizationCode(Client client, {String? state, String? prompt, @@ -495,6 +510,26 @@ class Flow { return TokenResponse.fromJson(json); } + /// Login with username and password + /// + /// Only allowed for [Flow.password] flows. + Future loginWithPassword( + {required String username, required String password}) async { + if (type != FlowType.password) { + throw UnsupportedError('Flow is not password'); + } + var json = await http.post(client.issuer.tokenEndpoint, + body: { + 'grant_type': 'password', + 'username': username, + 'password': password, + 'scope': scopes.join(' '), + 'client_id': client.clientId, + }, + client: client.httpClient); + return Credential._(client, TokenResponse.fromJson(json), null); + } + Future callback(Map response) async { if (response['state'] != state) { throw ArgumentError('State does not match');