[pve-devel] [PATCH pve-manager] ui: implement OpenId login
Dietmar Maurer
dietmar at proxmox.com
Thu Jun 24 10:17:59 CEST 2021
---
PVE/HTTPServer.pm | 4 +-
www/manager6/Utils.js | 8 +++
www/manager6/window/LoginWindow.js | 105 ++++++++++++++++++++++++++++-
3 files changed, 114 insertions(+), 3 deletions(-)
diff --git a/PVE/HTTPServer.pm b/PVE/HTTPServer.pm
index 636b562b..dabdf7f3 100755
--- a/PVE/HTTPServer.pm
+++ b/PVE/HTTPServer.pm
@@ -68,7 +68,9 @@ sub auth_handler {
# explicitly allow some calls without auth
if (($rel_uri eq '/access/domains' && $method eq 'GET') ||
- ($rel_uri eq '/access/ticket' && ($method eq 'GET' || $method eq 'POST'))) {
+ ($rel_uri eq '/access/ticket' && ($method eq 'GET' || $method eq 'POST')) ||
+ ($rel_uri eq '/access/openid/login' && $method eq 'POST') ||
+ ($rel_uri eq '/access/openid/auth-url' && $method eq 'POST')) {
$require_auth = 0;
}
diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js
index 3415c9eb..c2d139f9 100644
--- a/www/manager6/Utils.js
+++ b/www/manager6/Utils.js
@@ -1742,6 +1742,14 @@ Ext.define('PVE.Utils', {
return true;
},
+
+ openid_login_param: function() {
+ let param = Ext.Object.fromQueryString(window.location.search);
+ if (param.state !== undefined && param.code !== undefined) {
+ return param;
+ }
+ return undefined;
+ },
},
singleton: true,
diff --git a/www/manager6/window/LoginWindow.js b/www/manager6/window/LoginWindow.js
index 72078080..5d3d06b8 100644
--- a/www/manager6/window/LoginWindow.js
+++ b/www/manager6/window/LoginWindow.js
@@ -2,6 +2,21 @@
Ext.define('PVE.window.LoginWindow', {
extend: 'Ext.window.Window',
+ viewModel: {
+ data: {
+ openid: false,
+ },
+ formulas: {
+ button_text: function(get) {
+ if (get("openid") === true) {
+ return gettext("Login (OpenID redirect)");
+ } else {
+ return gettext("Login");
+ }
+ },
+ },
+ },
+
controller: {
xclass: 'Ext.app.ViewController',
@@ -18,6 +33,33 @@ Ext.define('PVE.window.LoginWindow', {
return;
}
+ let redirect_url = location.origin;
+ let params = form.getValues();
+
+ if (this.getViewModel().data.openid === true) {
+ let realm = params.realm;
+ Proxmox.Utils.API2Request({
+ url: '/api2/extjs/access/openid/auth-url',
+ params: {
+ realm: realm,
+ "redirect-url": redirect_url,
+ },
+ method: 'POST',
+ success: function(resp, opts) {
+ window.location = resp.result.data;
+ },
+ failure: function(resp, opts) {
+ Proxmox.Utils.authClear();
+ form.unmask();
+ Ext.MessageBox.alert(
+ gettext('Error'),
+ gettext('OpenId redirect failed. Please try again<br>Error: ' + resp.htmlStatus),
+ );
+ },
+ });
+ return;
+ }
+
view.el.mask(gettext('Please wait...'), 'x-mask-loading');
// set or clear username
@@ -162,11 +204,21 @@ Ext.define('PVE.window.LoginWindow', {
window.location.reload();
},
},
- 'button[reference=loginButton]': {
+ 'field[name=realm]': {
+ change: function(f, value) {
+ let record = f.store.getById(value);
+ if (record === undefined) return;
+ let data = record.data;
+ this.getViewModel().set("openid", data.type === "openid");
+ },
+ },
+ 'button[reference=loginButton]': {
click: 'onLogon',
},
'#': {
show: function() {
+ var me = this;
+
var sp = Ext.state.Manager.getProvider();
var checkboxField = this.lookupReference('saveunField');
var unField = this.lookupReference('usernameField');
@@ -180,6 +232,42 @@ Ext.define('PVE.window.LoginWindow', {
var pwField = this.lookupReference('passwordField');
pwField.focus();
}
+
+ let param = PVE.Utils.openid_login_param();
+ if (param !== undefined) {
+ Proxmox.Utils.authClear();
+
+ let loginForm = this.lookupReference('loginForm');
+ loginForm.mask(gettext('OpenID login - please wait...'), 'x-mask-loading');
+
+ let redirect_url = location.origin;
+
+ Proxmox.Utils.API2Request({
+ url: '/api2/extjs/access/openid/login',
+ params: {
+ state: param.state,
+ code: param.code,
+ "redirect-url": redirect_url,
+ },
+ method: 'POST',
+ failure: function(response) {
+ loginForm.unmask();
+ Ext.MessageBox.alert(
+ gettext('Error'),
+ gettext('Login failed. Please try again<br>Error: ' + response.htmlStatus),
+ function() {
+ window.location = redirect_url;
+ },
+ );
+ },
+ success: function(response, options) {
+ loginForm.unmask();
+ let data = response.result.data;
+ history.replaceState(null, '', redirect_url);
+ me.success(data);
+ },
+ });
+ }
},
},
},
@@ -217,6 +305,10 @@ Ext.define('PVE.window.LoginWindow', {
itemId: 'usernameField',
reference: 'usernameField',
stateId: 'login-username',
+ bind: {
+ visible: "{!openid}",
+ disabled: "{openid}",
+ },
},
{
xtype: 'textfield',
@@ -224,6 +316,10 @@ Ext.define('PVE.window.LoginWindow', {
fieldLabel: gettext('Password'),
name: 'password',
reference: 'passwordField',
+ bind: {
+ visible: "{!openid}",
+ disabled: "{openid}",
+ },
},
{
xtype: 'pmxRealmComboBox',
@@ -248,9 +344,14 @@ Ext.define('PVE.window.LoginWindow', {
labelWidth: 250,
labelAlign: 'right',
submitValue: false,
+ bind: {
+ visible: "{!openid}",
+ },
},
{
- text: gettext('Login'),
+ bind: {
+ text: "{button_text}",
+ },
reference: 'loginButton',
},
],
--
2.30.2
More information about the pve-devel
mailing list