* [pve-devel] [PATCH manager/proxmox{_dart_api_client, _login_manager} 0/3] fix #4281
@ 2025-04-29 15:07 Alexander Abraham
2025-04-29 15:07 ` [pve-devel] [PATCH proxmox_dart_api_client 1/1] fix #4281: dart_api_client: Added functions for login with Open ID Alexander Abraham
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Alexander Abraham @ 2025-04-29 15:07 UTC (permalink / raw)
To: pve-devel
This patch series fixes the login with Open ID for the mobile
Flutter app and the mobile (web) frontend for PVE manager. A user
reported that they could not login using Open ID on the PVE mobile
(web) frontend and in the PVE Flutter app.
proxmox_dart_api_client:
Alexander Abraham (1):
fix #4281: dart_api_client: Added functions for login with Open ID.
lib/src/client.dart | 4 +-
lib/src/oidc.dart | 148 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 150 insertions(+), 2 deletions(-)
create mode 100644 lib/src/oidc.dart
proxmox_login_manager:
Alexander Abraham (1):
fix #4281: login_manager: UI changes for enabling login with Open ID
lib/proxmox_login_form.dart | 222 +++++++++++++++++++++++++++++++-----
1 file changed, 192 insertions(+), 30 deletions(-)
manager:
Alexander Abraham (1):
fix #4281: manager: Enabled logging in with Open ID
www/mobile/Login.js | 148 ++++++++++++++++++++++++++++++++++----------
1 file changed, 116 insertions(+), 32 deletions(-)
Summary over all repositories:
4 files changed, 458 insertions(+), 64 deletions(-)
--
Generated by git-murpp 0.8.1
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 5+ messages in thread
* [pve-devel] [PATCH proxmox_dart_api_client 1/1] fix #4281: dart_api_client: Added functions for login with Open ID.
2025-04-29 15:07 [pve-devel] [PATCH manager/proxmox{_dart_api_client, _login_manager} 0/3] fix #4281 Alexander Abraham
@ 2025-04-29 15:07 ` Alexander Abraham
2025-04-29 15:07 ` [pve-devel] [PATCH proxmox_login_manager 1/1] fix #4281: login_manager: UI changes for enabling " Alexander Abraham
2025-04-29 15:07 ` [pve-devel] [PATCH manager 1/1] fix #4281: manager: Enabled logging in " Alexander Abraham
2 siblings, 0 replies; 5+ messages in thread
From: Alexander Abraham @ 2025-04-29 15:07 UTC (permalink / raw)
To: pve-devel
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@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
^ permalink raw reply [flat|nested] 5+ messages in thread
* [pve-devel] [PATCH proxmox_login_manager 1/1] fix #4281: login_manager: UI changes for enabling login with Open ID
2025-04-29 15:07 [pve-devel] [PATCH manager/proxmox{_dart_api_client, _login_manager} 0/3] fix #4281 Alexander Abraham
2025-04-29 15:07 ` [pve-devel] [PATCH proxmox_dart_api_client 1/1] fix #4281: dart_api_client: Added functions for login with Open ID Alexander Abraham
@ 2025-04-29 15:07 ` Alexander Abraham
2025-04-29 15:07 ` [pve-devel] [PATCH manager 1/1] fix #4281: manager: Enabled logging in " Alexander Abraham
2 siblings, 0 replies; 5+ messages in thread
From: Alexander Abraham @ 2025-04-29 15:07 UTC (permalink / raw)
To: pve-devel
This commit adds an authorization flow for logging a user in
with Open ID in the Flutter App's UI. An authorization URL
is obtained and opened in a webview. From there, the user
types in their credentials and the login is processed and
the user is logged in to the PVE app.
Signed-off-by: Alexander Abraham <a.abraham@proxmox.com>
---
lib/proxmox_login_form.dart | 222 +++++++++++++++++++++++++++++++-----
1 file changed, 192 insertions(+), 30 deletions(-)
diff --git a/lib/proxmox_login_form.dart b/lib/proxmox_login_form.dart
index 735bd42..7dfba9f 100644
--- a/lib/proxmox_login_form.dart
+++ b/lib/proxmox_login_form.dart
@@ -1,6 +1,7 @@
import 'dart:io';
import 'dart:async';
-
+import 'dart:convert';
+import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:collection/collection.dart';
import 'package:proxmox_dart_api_client/proxmox_dart_api_client.dart'
@@ -12,6 +13,12 @@ import 'package:proxmox_login_manager/proxmox_login_model.dart';
import 'package:proxmox_login_manager/proxmox_tfa_form.dart';
import 'package:proxmox_login_manager/extension.dart';
import 'package:proxmox_login_manager/proxmox_password_store.dart';
+import 'package:flutter_inappwebview/flutter_inappwebview.dart';
+
+typedef AuthCallBack = Future<void> Function(
+ InAppWebViewController controller,
+ NavigationAction navAction
+);
class ProxmoxProgressModel {
int inProgress = 0;
@@ -42,9 +49,12 @@ class ProxmoxLoginForm extends StatefulWidget {
final Function? onSavePasswordChanged;
final bool? canSavePassword;
final bool? passwordSaved;
+ final bool isOIDC;
+ final bool showOIDCAuth;
const ProxmoxLoginForm({
super.key,
+ required this.isOIDC,
required this.originController,
required this.usernameController,
required this.passwordController,
@@ -57,6 +67,7 @@ class ProxmoxLoginForm extends StatefulWidget {
this.onSavePasswordChanged,
this.canSavePassword,
this.passwordSaved,
+ required this.showOIDCAuth
});
@override
@@ -97,7 +108,8 @@ class _ProxmoxLoginFormState extends State<ProxmoxLoginForm> {
controller: widget.originController,
enabled: false,
),
- TextFormField(
+
+ if (widget.isOIDC == false) TextFormField(
decoration: const InputDecoration(
icon: Icon(Icons.person),
labelText: 'Username',
@@ -123,11 +135,11 @@ class _ProxmoxLoginFormState extends State<ProxmoxLoginForm> {
))
.toList(),
onChanged: widget.onDomainChanged,
- selectedItemBuilder: (context) =>
- widget.accessDomains!.map((e) => Text(e!.realm)).toList(),
+ selectedItemBuilder: (context) => widget.accessDomains!.map((e) =>
+ Text(e!.realm)).toList(),
value: widget.selectedDomain,
),
- Stack(
+ if (widget.isOIDC == false) Stack(
children: [
TextFormField(
decoration: const InputDecoration(
@@ -150,14 +162,18 @@ class _ProxmoxLoginFormState extends State<ProxmoxLoginForm> {
Align(
alignment: Alignment.bottomRight,
child: IconButton(
- constraints: BoxConstraints.tight(const Size(58, 58)),
+ constraints: BoxConstraints.tight(const Size(58,
+ 58)),
iconSize: 24,
tooltip: _obscure ? "Show password" : "Hide password",
icon:
- Icon(_obscure ? Icons.visibility : Icons.visibility_off),
- onPressed: () => setState(() {
- _obscure = !_obscure;
- }),
+ Icon(_obscure ? Icons.visibility : Icons.visibility_off),
+ onPressed: () => setState(
+ () {
+
+ _obscure = !_obscure;
+ }
+ ),
),
)
],
@@ -169,12 +185,12 @@ class _ProxmoxLoginFormState extends State<ProxmoxLoginForm> {
onChanged: (value) {
if (widget.onSavePasswordChanged != null) {
widget.onSavePasswordChanged!(value!);
- }
- setState(() {
- _savePwCheckbox = value!;
- });
- },
- )
+ }
+ setState(() {
+ _savePwCheckbox = value!;
+ });
+ },
+ )
],
),
);
@@ -215,6 +231,11 @@ class _ProxmoxLoginPageState extends State<ProxmoxLoginPage> {
bool _submittButtonEnabled = true;
bool _canSavePassword = false;
bool _savePasswordCB = false;
+ bool isOIDC = false;
+ bool showOIDCAuth = false;
+ late String oidcUserName;
+ late String oidcTicket;
+ late String oidcCRSF;
@override
void initState() {
@@ -327,6 +348,7 @@ class _ProxmoxLoginPageState extends State<ProxmoxLoginPage> {
child: FutureBuilder<List<PveAccessDomainModel?>?>(
future: _accessDomains,
builder: (context, snapshot) {
+
return Form(
key: _formKey,
onChanged: () {
@@ -338,7 +360,7 @@ class _ProxmoxLoginPageState extends State<ProxmoxLoginPage> {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
- Expanded(
+ Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
@@ -350,6 +372,7 @@ class _ProxmoxLoginPageState extends State<ProxmoxLoginPage> {
),
),
ProxmoxLoginForm(
+ showOIDCAuth: showOIDCAuth,
originController: _originController,
originValidator: (value) {
if (value == null || value.isEmpty) {
@@ -364,6 +387,7 @@ class _ProxmoxLoginPageState extends State<ProxmoxLoginPage> {
return 'Invalid URI: $e';
}
},
+ isOIDC: isOIDC,
usernameController: _usernameController,
passwordController: _passwordController,
accessDomains: snapshot.data,
@@ -376,6 +400,16 @@ class _ProxmoxLoginPageState extends State<ProxmoxLoginPage> {
onDomainChanged: (value) {
setState(() {
_selectedDomain = value;
+ if (_selectedDomain!.comment.toString() == "null"){
+ setState((){
+ isOIDC = true;
+ _submittButtonEnabled = true;
+ _canSavePassword = false;
+ });
+ }
+ else {
+ setState(() => isOIDC = false);
+ }
});
},
onOriginSubmitted: () {
@@ -392,6 +426,7 @@ class _ProxmoxLoginPageState extends State<ProxmoxLoginPage> {
},
onPasswordSubmitted: _submittButtonEnabled
? () {
+
final isValid =
_formKey.currentState!.validate();
setState(() {
@@ -411,6 +446,46 @@ class _ProxmoxLoginPageState extends State<ProxmoxLoginPage> {
child: TextButton(
onPressed: _submittButtonEnabled
? () {
+ if (isOIDC) {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) =>
+ OIDCAuthWidget(
+ realm:_selectedDomain!.realm,
+ redirectUrl: _originController.text,
+ host:_originController.text,
+ authHandler: (controller,navAction) async {
+ Map<String,
+ String> creds = parseUrl(
+ navAction
+ .request
+ .url
+ .toString()
+ );
+
+ String pveAuth = await fetchOIDCCredentials(
+ creds["code"]!,
+ creds["state"]!,
+ creds["host"]!
+ );
+ Map<String,dynamic> serverCreds = jsonDecode(
+ pveAuth
+ )["data"]!;
+ String username = serverCreds["username"]!
+ .split("@")[0];
+ String ticket = serverCreds["ticket"]!;
+ setState((){
+ _usernameController.text = username;
+ _passwordController.text = ticket;
+ });
+ _onLoginButtonPressed();
+ }
+ )
+ )
+ );
+ }
+ else {
final isValid = _formKey
.currentState!
.validate();
@@ -428,17 +503,19 @@ class _ProxmoxLoginPageState extends State<ProxmoxLoginPage> {
});
}
}
- }
+ }}
: null,
child: const Text('Continue'),
),
),
- ),
- ),
+ ),
+ ),
],
),
);
- }),
+
+ }
+ ),
),
),
),
@@ -460,19 +537,15 @@ class _ProxmoxLoginPageState extends State<ProxmoxLoginPage> {
});
try {
- final settings = await ProxmoxGeneralSettingsModel.fromLocalStorage();
- //cleaned form fields
final origin = normalizeUrl(_originController.text.trim());
- final username = _usernameController.text.trim();
final String enteredPassword = _passwordController.text.trim();
final String? savedPassword = widget.password;
-
+ final settings = await ProxmoxGeneralSettingsModel.fromLocalStorage();
+ final username = _usernameController.text.trim();
final password = ticket.isNotEmpty ? ticket : enteredPassword;
final realm = _selectedDomain?.realm ?? mRealm;
-
var client = await proxclient.authenticate(
- '$username@$realm', password, origin, settings.sslValidation!);
-
+ '$username@$realm', password, origin, settings.sslValidation!);
if (client.credentials.tfa != null &&
client.credentials.tfa!.kinds().isNotEmpty) {
if (!mounted) return;
@@ -566,7 +639,6 @@ class _ProxmoxLoginPageState extends State<ProxmoxLoginPage> {
Navigator.of(context).pop(client);
}
} on proxclient.ProxmoxApiException catch (e) {
- print(e);
if (!mounted) return;
if (e.message.contains('No ticket')) {
showDialog(
@@ -703,8 +775,12 @@ class _ProxmoxLoginPageState extends State<ProxmoxLoginPage> {
setState(() {
_progressModel.inProgress -= 1;
+ if(response![0]!.comment == null){
+ isOIDC = true;
+ }
+ else {}
_selectedDomain = selection;
- });
+ });
return response;
}
@@ -847,3 +923,89 @@ Uri normalizeUrl(String urlText) {
return Uri.https(urlText, '');
}
+
+
+class OIDCAuthWidget extends StatefulWidget {
+ final String host;
+ final String realm;
+ final String redirectUrl;
+ final AuthCallBack authHandler;
+
+ OIDCAuthWidget(
+ {
+ required this.host,
+ required this.realm,
+ required this.authHandler,
+ required this.redirectUrl
+ }
+ );
+
+ OIDCAuthWidgetState createState() => OIDCAuthWidgetState();
+}
+class OIDCAuthWidgetState extends State<OIDCAuthWidget>{
+ final GlobalKey webViewKey = GlobalKey();
+ late InAppWebViewController webController;
+ late Future<String> authUrl;
+ InAppWebViewSettings settings = InAppWebViewSettings(
+ useShouldOverrideUrlLoading: true
+ );
+
+ void initState(){
+ super.initState();
+ authUrl = fetchOIDCAuthUrl(
+ widget.realm,
+ widget.host,
+ widget.redirectUrl
+ );
+ }
+
+ Widget build(BuildContext context){
+ return FutureBuilder<String>(
+ future: this.authUrl,
+ builder: (context, snapshot) {
+ if (snapshot.connectionState == ConnectionState.done){
+ String data = snapshot.data!;
+ if (data == ""){
+ return Scaffold(
+ body: Center(
+ child: Text(
+ "Data could not be loaded."
+ )
+ )
+ );
+ }
+ else {
+ String fetchedUrl = snapshot.data!;
+ return Scaffold(body:InAppWebView(
+ key: webViewKey,
+ initialUrlRequest: URLRequest(
+ url: WebUri(
+ fetchedUrl
+ )
+ ),
+ initialSettings: settings,
+ onWebViewCreated: (controller){
+ webController = controller;
+ },
+ shouldOverrideUrlLoading: (controller, navAction) async{
+ await widget.authHandler(controller, navAction);
+ Navigator.pop(context);
+ }
+ ));
+ }
+ }
+ return Scaffold(
+ body: Center(
+ child: Text(
+ "Loading..",
+ style: TextStyle(
+ fontSize: (MediaQuery.of(context).size.width/100.0)*5,
+ fontWeight: FontWeight.bold,
+ )
+ )
+ )
+ );
+ }
+ );
+ }
+}
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 5+ messages in thread
* [pve-devel] [PATCH manager 1/1] fix #4281: manager: Enabled logging in with Open ID
2025-04-29 15:07 [pve-devel] [PATCH manager/proxmox{_dart_api_client, _login_manager} 0/3] fix #4281 Alexander Abraham
2025-04-29 15:07 ` [pve-devel] [PATCH proxmox_dart_api_client 1/1] fix #4281: dart_api_client: Added functions for login with Open ID Alexander Abraham
2025-04-29 15:07 ` [pve-devel] [PATCH proxmox_login_manager 1/1] fix #4281: login_manager: UI changes for enabling " Alexander Abraham
@ 2025-04-29 15:07 ` Alexander Abraham
2025-04-30 8:32 ` Christoph Heiss
2 siblings, 1 reply; 5+ messages in thread
From: Alexander Abraham @ 2025-04-29 15:07 UTC (permalink / raw)
To: pve-devel
This commit adds an authorization flow for logging
in a user using Open ID on the PVE web frontend in
the mobile view.
Signed-off-by: Alexander Abraham <a.abraham@proxmox.com>
---
www/mobile/Login.js | 148 ++++++++++++++++++++++++++++++++++----------
1 file changed, 116 insertions(+), 32 deletions(-)
diff --git a/www/mobile/Login.js b/www/mobile/Login.js
index 06c8b3d4..05038036 100644
--- a/www/mobile/Login.js
+++ b/www/mobile/Login.js
@@ -1,8 +1,10 @@
+/ https://git.proxmox.com/?p=pve-manager.git;a=blob;f=www/manager6/Workspace.js;h=922e01df86718e8fc89ce5835f81d21f6d849b81;hb=HEAD
+
Ext.define('PVE.Login', {
extend: 'Ext.form.Panel',
alias: "widget.pveLogin",
-
- handleTFA: function(username, ticketResponse) {
+ id: 'loginFormPanel',
+ handleTFA: function(username, ticketResponse) {
let me = this;
let errlabel = me.down('#signInFailedLabel');
@@ -32,8 +34,7 @@ Ext.define('PVE.Login', {
} else {
me.mask({
xtype: 'loadmask',
- message: 'Loading...',
- });
+ message: 'Loading...', });
Proxmox.Utils.API2Request({
url: '/api2/extjs/access/ticket',
params: {
@@ -57,16 +58,16 @@ Ext.define('PVE.Login', {
Proxmox.Utils.authClear();
errlabel.show();
},
- });
+ })
}
},
});
}
},
-
config: {
title: 'Login',
padding: 10,
+ itemId: 'loginForm',
appUrl: 'login',
items: [
{
@@ -78,7 +79,7 @@ Ext.define('PVE.Login', {
{
xtype: 'fieldset',
title: 'Proxmox VE Login',
- items: [
+ items:[
{
xtype: 'textfield',
placeHolder: gettext('User name'),
@@ -97,8 +98,19 @@ Ext.define('PVE.Login', {
xtype: 'pveRealmSelector',
itemId: 'realmSelectorField',
name: 'realm',
+ listeners: {
+ change: function(field, newValue){
+ let record = field.record;
+ let realmType = record.data.type;
+ let currForm = this.up("formpanel");
+ let usernameField = currForm.down("#userNameTextField");
+ let passwordField = currForm.down("#passwordTextField");
+ usernameField.setHidden(realmType === "openid");
+ passwordField.setHidden(realmType === "openid");
+ }
+ }
},
- ],
+ ],
},
{
xtype: 'label',
@@ -124,35 +136,107 @@ Ext.define('PVE.Login', {
errlabel.hide();
+
var username = usernameField.getValue();
var password = passwordField.getValue();
- var realm = realmField.getValue();
+ var realm = realmField.getValue();
- Proxmox.Utils.API2Request({
- url: '/access/ticket',
- method: 'POST',
- waitMsgTarget: form,
- params: { username: username, password: password, realm: realm },
- failure: function(response, options) {
- errlabel.show();
- },
- success: function(response, options) {
- passwordField.setValue('');
- let data = response.result.data;
- if (Ext.isDefined(data.NeedTFA)) {
- form.handleTFA(username, data);
- } else {
- PVE.Workspace.updateLoginData(data);
- }
- },
- });
- },
- },
- ],
- },
-});
+ if (realmField.record.data.type === "openid"){
+ const redirectUrl = location.origin;
+ const realmName = realmField.record.data.realm;
+ Proxmox.Utils.API2Request(
+ {
+ url: '/access/openid/auth-url',
+ method: 'POST',
+ waitMsgTarget: form,
+ params: {
+ realm: realmName,
+ "redirect-url": redirectUrl
+ },
+ success: (resp, opts) => {
+ window.location = resp.result.data;
+ },
+ failure: (resp, opts) => {
+ Proxmox.Utils.authClear();
+ form.unmask();
+ Ext.Msg.alert(
+ gettext('Error'),
+ gettext('OpenID redirect failed.') + `<br>${resp.htmlStatus}`,
+ );
+ }
+ }
+ );
+ return;
+ }
+ else {
+ Proxmox.Utils.API2Request({
+ url: '/access/ticket',
+ method: 'POST',
+ waitMsgTarget: form,
+ params: { username: username, password: password, realm: realm },
+ failure: function(response, options) {
+ errlabel.show();
+ },
+ success: function(response, options) {
+ passwordField.setValue('');
+ let data = response.result.data;
+ if (Ext.isDefined(data.NeedTFA)) {
+ form.handleTFA(username, data);
+ } else {
+ PVE.Workspace.updateLoginData(data);
+ }
+ },
+ });
+ }
+ },
+ },
+ ],
+ },
+ show: function(){
+ let auth = Proxmox.Utils.getOpenIDRedirectionAuthorization();
+ let lForm = this.callParent();
+ if (auth !== undefined){
+ let state = auth.state;
+ let code = auth.code;
+ Proxmox.Utils.authClear()
+ lForm.setMasked(
+ {
+ xtype: 'loadmask',
+ message: gettext('OpenID login - please wait..')
+ }
+ );
+ const redirectUrl = location.origin;
+ Proxmox.Utils.API2Request({
+ url: '/access/openid/login',
+ params: {
+ "state": auth.state,
+ "code": auth.code,
+ "redirect-url": redirectUrl,
+ },
+ method: 'POST',
+ failure: function(response) {
+ lForm.unmask();
+ let error = response.htmlStatus;
+ Ext.Msg.alert(
+ gettext('Error'),
+ gettext('OpenID login failed, please try again') + `<br>${error}`,
+ () => { window.location = redirectUrl; },
+ );
+ },
+ success: function(response, options) {
+ lForm.unmask();
+ let data = response.result.data;
+ history.replaceState(null, '', redirectUrl);
+ lForm.success(data)
+ PVE.Workspace.updateLoginData(data);
+ },
+ });
+ }
+ }
+});
+
Ext.define('PVE.field.TFACode', {
extend: 'Ext.field.Text',
xtype: 'tfacode',
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [pve-devel] [PATCH manager 1/1] fix #4281: manager: Enabled logging in with Open ID
2025-04-29 15:07 ` [pve-devel] [PATCH manager 1/1] fix #4281: manager: Enabled logging in " Alexander Abraham
@ 2025-04-30 8:32 ` Christoph Heiss
0 siblings, 0 replies; 5+ messages in thread
From: Christoph Heiss @ 2025-04-30 8:32 UTC (permalink / raw)
To: Alexander Abraham; +Cc: Proxmox VE development discussion
The commit message title should always be in present tense (handy
shortcut to remember: the commit/patch will *change* it, but it hasn't
been changed *before* the commit/patch).
Applies to the other patches in the series as well - see also our
developer documentation on that matter [0].
On Tue Apr 29, 2025 at 5:07 PM CEST, Alexander Abraham wrote:
> This commit adds an authorization flow for logging
> in a user using Open ID on the PVE web frontend in
> the mobile view.
"This commit [..]" is redundant, since the context is already clear :^)
Didn't really review the patch further, so if there's some other
important detail, it should be mentioned as well.
[0] https://pve.proxmox.com/wiki/Developer_Documentation#Commits_and_Commit_Messages
>
> Signed-off-by: Alexander Abraham <a.abraham@proxmox.com>
> ---
> www/mobile/Login.js | 148 ++++++++++++++++++++++++++++++++++----------
> 1 file changed, 116 insertions(+), 32 deletions(-)
>
> diff --git a/www/mobile/Login.js b/www/mobile/Login.js
> index 06c8b3d4..05038036 100644
> --- a/www/mobile/Login.js
> +++ b/www/mobile/Login.js
> @@ -1,8 +1,10 @@
> +/ https://git.proxmox.com/?p=pve-manager.git;a=blob;f=www/manager6/Workspace.js;h=922e01df86718e8fc89ce5835f81d21f6d849b81;hb=HEAD
> +
Unintentional copy-paste I assume?
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-04-30 8:32 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-04-29 15:07 [pve-devel] [PATCH manager/proxmox{_dart_api_client, _login_manager} 0/3] fix #4281 Alexander Abraham
2025-04-29 15:07 ` [pve-devel] [PATCH proxmox_dart_api_client 1/1] fix #4281: dart_api_client: Added functions for login with Open ID Alexander Abraham
2025-04-29 15:07 ` [pve-devel] [PATCH proxmox_login_manager 1/1] fix #4281: login_manager: UI changes for enabling " Alexander Abraham
2025-04-29 15:07 ` [pve-devel] [PATCH manager 1/1] fix #4281: manager: Enabled logging in " Alexander Abraham
2025-04-30 8:32 ` Christoph Heiss
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal