[pve-devel] [PATCH proxmox_dart_api_client 1/1] fix #4281: dart_api_client: Added functions for login with Open ID.
Alexander Abraham
a.abraham at proxmox.com
Tue Apr 29 17:07:55 CEST 2025
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.abraham at 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
More information about the pve-devel
mailing list