From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 9626F74969 for ; Tue, 22 Jun 2021 10:57:05 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 0B9662403A for ; Tue, 22 Jun 2021 10:56:35 +0200 (CEST) Received: from dev7.proxmox.com (unknown [94.136.29.99]) by firstgate.proxmox.com (Proxmox) with ESMTP id E233523E6E for ; Tue, 22 Jun 2021 10:56:28 +0200 (CEST) Received: by dev7.proxmox.com (Postfix, from userid 0) id 96A5D80F5B; Tue, 22 Jun 2021 10:56:22 +0200 (CEST) From: Dietmar Maurer To: pbs-devel@lists.proxmox.com Date: Tue, 22 Jun 2021 10:56:17 +0200 Message-Id: <20210622085620.1551677-10-dietmar@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210622085620.1551677-1-dietmar@proxmox.com> References: <20210622085620.1551677-1-dietmar@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.676 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RDNS_NONE 0.793 Delivered to internal network by a host with no rDNS SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [access.rs] Subject: [pbs-devel] [PATH proxmox-backup v1 09/12] ui: implement OpenId login X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 22 Jun 2021 08:57:05 -0000 --- src/api2/access.rs | 6 +-- www/Application.js | 8 +++- www/LoginView.js | 100 ++++++++++++++++++++++++++++++++++++++++++++- www/Utils.js | 8 ++++ 4 files changed, 116 insertions(+), 6 deletions(-) diff --git a/src/api2/access.rs b/src/api2/access.rs index 5abb5cb4..e95db88b 100644 --- a/src/api2/access.rs +++ b/src/api2/access.rs @@ -18,7 +18,7 @@ use crate::api2::types::*; use crate::auth_helpers::*; use crate::server::ticket::ApiTicket; use crate::tools::ticket::{self, Empty, Ticket}; -use crate::config::domains::OpenIdRealmConfig; +use crate::config::domains::{OPENID_STATE_DIR, OpenIdRealmConfig};) use crate::config::acl as acl_config; use crate::config::acl::{PRIVILEGES, PRIV_PERMISSIONS_MODIFY, PRIV_SYS_AUDIT}; @@ -288,10 +288,8 @@ pub fn openid_login( ) -> Result { let user_info = CachedUserInfo::new()?; - let backup_user = crate::backup::backup_user()?; - let (realm, private_auth_state) = - OpenIdAuthenticator::verify_public_auth_state(&state, backup_user.uid)?; + OpenIdAuthenticator::verify_public_auth_state(OPENID_STATE_DIR, &state)?; let (domains, _digest) = crate::config::domains::config()?; let config: OpenIdRealmConfig = domains.lookup("openid", &realm)?; diff --git a/www/Application.js b/www/Application.js index c4df600e..20ae26bd 100644 --- a/www/Application.js +++ b/www/Application.js @@ -49,9 +49,15 @@ Ext.define('PBS.Application', { var provider = new Ext.state.LocalStorageProvider({ prefix: 'ext-pbs-' }); Ext.state.Manager.setProvider(provider); + let openid_login = false; + let param = PBS.Utils.openid_login_param(); + if (param !== undefined) { + openid_login = true; + } + // show login window if not loggedin var loggedin = Proxmox.Utils.authOK(); - if (!loggedin) { + if (openid_login || !loggedin) { me.changeView('loginview', true); } else { me.changeView('mainview', true); diff --git a/www/LoginView.js b/www/LoginView.js index 6dd09646..f2fc5370 100644 --- a/www/LoginView.js +++ b/www/LoginView.js @@ -2,6 +2,21 @@ Ext.define('PBS.LoginView', { extend: 'Ext.container.Container', xtype: 'loginview', + 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', @@ -15,8 +30,33 @@ Ext.define('PBS.LoginView', { return; } + let redirect_url = location.origin; + let params = loginForm.getValues(); + if (this.getViewModel().data.openid === true) { + let realm = params.realm; + try { + let resp = await PBS.Async.api2({ + url: '/api2/extjs/access/domains', + params: { + realm: realm, + "redirect-url": redirect_url, + }, + method: 'POST', + }); + window.location = resp.result.data; + } catch (error) { + Proxmox.Utils.authClear(); + loginForm.unmask(); + Ext.MessageBox.alert( + gettext('Error'), + gettext('OpenId redirect failed. Please try again
Error: ' + error), + ); + } + return; + } + params.username = params.username + '@' + params.realm; delete params.realm; @@ -98,6 +138,14 @@ Ext.define('PBS.LoginView', { window.location.reload(); }, }, + '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: 'submitForm', }, @@ -116,6 +164,43 @@ Ext.define('PBS.LoginView', { var pwField = this.lookupReference('passwordField'); pwField.focus(); } + + let param = PBS.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
Error: ' + response.htmlStatus), + function() { + window.location = redirect_url; + }, + ); + }, + success: function(response, options) { + loginForm.unmask(); + let data = response.result.data; + PBS.Utils.updateLoginData(data); + PBS.app.changeView('mainview'); + history.replaceState(null, '', redirect_url + '#pbsDashboard'); + }, + }); + } }, }, }, @@ -191,6 +276,10 @@ Ext.define('PBS.LoginView', { itemId: 'usernameField', reference: 'usernameField', stateId: 'login-username', + bind: { + visible: "{!openid}", + disabled: "{openid}", + }, }, { xtype: 'textfield', @@ -199,6 +288,10 @@ Ext.define('PBS.LoginView', { name: 'password', itemId: 'passwordField', reference: 'passwordField', + bind: { + visible: "{!openid}", + disabled: "{openid}", + }, }, { xtype: 'pmxRealmComboBox', @@ -223,9 +316,14 @@ Ext.define('PBS.LoginView', { labelWidth: 250, labelAlign: 'right', submitValue: false, + bind: { + visible: "{!openid}", + }, }, { - text: gettext('Login'), + bind: { + text: "{button_text}", + }, reference: 'loginButton', formBind: true, }, diff --git a/www/Utils.js b/www/Utils.js index 6b378355..677f2204 100644 --- a/www/Utils.js +++ b/www/Utils.js @@ -326,6 +326,14 @@ Ext.define('PBS.Utils', { }; }, + openid_login_param: function() { + let param = Ext.Object.fromQueryString(window.location.search); + if (param.state !== undefined && param.code !== undefined) { + return param; + } + return undefined; + }, + calculate_dedup_factor: function(gcstatus) { let dedup = 1.0; if (gcstatus['disk-bytes'] > 0) { -- 2.30.2