This commit contains a module for the Dart API client for the PVE Flutter app focussed on logging in with Open ID. The module provides a function for obtaining an authorization URL from an Open ID provider and a function for obtaining a ticket from the PVE API from the redirect URL an Open ID provider sends the user to once they have logged into their Open ID provider.
Signed-off-by: Alexander Abraham <a.abra...@proxmox.com> --- lib/src/client.dart | 4 +- lib/src/oidc.dart | 148 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 lib/src/oidc.dart diff --git a/lib/src/client.dart b/lib/src/client.dart index f597c28..fdf5395 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -675,10 +675,10 @@ class ProxmoxApiClient extends http.BaseClient { Future<List<PveAccessDomainModel>> getAccessDomainsList() async { final path = '/api2/json/access/domains'; - final response = await _getWithValidation(path, null); + final response = await _getWithValidation(path, null); var data = (json.decode(response.body)['data'] as List).map((f) { return serializers.deserializeWith(PveAccessDomainModel.serializer, f); }); return data.whereType<PveAccessDomainModel>().toList(); - } + } } diff --git a/lib/src/oidc.dart b/lib/src/oidc.dart new file mode 100644 index 0000000..fb42f0b --- /dev/null +++ b/lib/src/oidc.dart @@ -0,0 +1,148 @@ +import 'dart:io'; +import 'dart:convert'; +import 'package:http/io_client.dart'; +import 'package:http/http.dart' as http; + +/// Returns the fetched authentication +/// or an empty string if the request +/// fails for any reason. +Future<String> fetchOIDCAuthUrl( + String realm, + String host, + String redirectUrl +) async { + String result = ""; + Map<String,String> params = { + "realm": realm, + "redirect-url":"https://$redirectUrl" + }; + String urlPath = "https://$host/api2/json/access/openid/auth-url"; + try { + http.Client client = IOClient( + HttpClient() + ..badCertificateCallback = ( + ( + X509Certificate cert, + String host, + int port + ){ + return true; + } + ) + ); + http.Response resp = await client.post( + Uri.parse(urlPath), + headers: { + 'Content-Type': 'application/json' + }, + body: jsonEncode(params) + ); + if (resp.statusCode == 200) { + result = (jsonDecode(resp.body) as Map<String,dynamic>)["data"]; + } + else { + result = resp.body; + } + } + catch(e) { + result = e.toString(); + } + return result; +} + +/// Attempts to fetch the login credentials +/// for Open ID logins from the PVE API. +Future<String> fetchCredsWithPort( + String host, + String port, + String code, + String state, +)async { + var result = ""; + Map<String,String> params = { + "code": code, + "redirect-url":"https://$host:$port", + "state": state + }; + String urlPath = "https://$host:$port/api2/json/access/openid/login"; + http.Client client = IOClient( + HttpClient() + ..badCertificateCallback = ( + ( + X509Certificate cert, + String host, + int port + ){ + return true; + } + ) + ); + http.Response resp = await client.post( + Uri.parse(urlPath), + headers: { + 'Content-Type': 'application/json' + }, + body: jsonEncode(params) + ); + if (resp.statusCode == 200) { + result = resp.body; + } + else { + result = resp.body; + } + return result; +} + +/// Returns the fetched credentials +/// inside a JSON string. An empty +/// string is returned if the +/// request fails for any reason. +Future<String> fetchOIDCCredentials( + String code, + String state, + String redirectUrl +) async { + String result = ""; + try { + result = await fetchCredsWithPort( + redirectUrl, + "8006", + code, + state + ); + } + catch(e) { + try { + result = await fetchCredsWithPort( + redirectUrl, + "443", + code, + state + ); + } + catch(e){ + result = e.toString(); + } + } + return result; +} + +/// Parses the URL an Open ID provider +/// redirects to post-login and returns +/// the parameters extracted from the URL +/// for obtaining a ticket from the PVE +/// API as key-value pairs. +Map<String,String> parseUrl(String url){ + Uri parsed = Uri.parse(url); + Map<String, String> params = parsed.queryParameters; + String redirectUrl = parsed.host; + String stateCode = params["state"]!; + String statusCode = params["code"]!; + Map<String, String> result = Map(); + result["state"] = stateCode; + result["code"] = statusCode; + result["host"] = redirectUrl; + return result; +} + + -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel