[pve-devel] [PATCH v3 manager] ui: add api token authentication to login window

Tim Marx t.marx at proxmox.com
Mon Jul 6 14:45:43 CEST 2020


Signed-off-by: Tim Marx <t.marx at proxmox.com>
---
changes since v2:
* let/var
* removed checkbox
* autodetect api token on change

 www/manager6/Workspace.js          |   5 ++
 www/manager6/window/LoginWindow.js | 106 +++++++++++++++++++++--------
 2 files changed, 81 insertions(+), 30 deletions(-)

diff --git a/www/manager6/Workspace.js b/www/manager6/Workspace.js
index 8d224f5b..c4917dac 100644
--- a/www/manager6/Workspace.js
+++ b/www/manager6/Workspace.js
@@ -73,6 +73,11 @@ Ext.define('PVE.Workspace', {

 	me.callParent();

+	let storedAuth = Proxmox.Utils.getStoredAuth();
+	if (storedAuth.username) {
+	    Proxmox.UserName = storedAuth.username;
+	}
+
         if (!Proxmox.Utils.authOK()) {
 	    me.showLogin();
 	} else {
diff --git a/www/manager6/window/LoginWindow.js b/www/manager6/window/LoginWindow.js
index 6123c655..7d97cd56 100644
--- a/www/manager6/window/LoginWindow.js
+++ b/www/manager6/window/LoginWindow.js
@@ -12,6 +12,7 @@ Ext.define('PVE.window.LoginWindow', {
 	    var form = this.lookupReference('loginForm');
 	    var unField = this.lookupReference('usernameField');
 	    var saveunField = this.lookupReference('saveunField');
+
 	    var view = this.getView();

 	    if (!form.isValid()) {
@@ -20,38 +21,60 @@ Ext.define('PVE.window.LoginWindow', {

 	    view.el.mask(gettext('Please wait...'), 'x-mask-loading');

-	    // set or clear username
-	    var sp = Ext.state.Manager.getProvider();
-	    if (saveunField.getValue() === true) {
-		sp.set(unField.getStateId(), unField.getValue());
+	    if (Proxmox.Utils.APIToken_match.test(unField.value)) {
+		var splitToken = unField.value.match(/^(.*)=(.*)$/);
+		Proxmox.Utils.API2Request({
+		    url: '/api2/extjs/access/uicapabilities',
+		    headers:{
+			Authorization: 'PVEAPIToken=' + unField.value
+		    },
+		    success: function(response, opts) {
+			var data = {
+			    username: splitToken[1],
+			    token: 'PVEAPIToken=' + unField.value,
+			    cap: response.result.data.cap
+			};
+			me.success(data);
+		    },
+
+		    failure: function(response, opts) {
+			me.failure(response);
+		    }
+		});
 	    } else {
-		sp.clear(unField.getStateId());
-	    }
-	    sp.set(saveunField.getStateId(), saveunField.getValue());
+		// set or clear username
+		var sp = Ext.state.Manager.getProvider();
+		if (saveunField.getValue() === true) {
+		    sp.set(unField.getStateId(), unField.getValue());
+		} else {
+		    sp.clear(unField.getStateId());
+		}
+		sp.set(saveunField.getStateId(), saveunField.getValue());

-	    form.submit({
-		failure: function(f, resp){
-		    me.failure(resp);
-		},
-		success: function(f, resp){
-		    view.el.unmask();
+		form.submit({
+		    failure: function(f, resp){
+			me.failure(resp);
+		    },
+		    success: function(f, resp){
+			view.el.unmask();

-		    var data = resp.result.data;
-		    if (Ext.isDefined(data.NeedTFA)) {
-			// Store first factor login information first:
-			data.LoggedOut = true;
-			Proxmox.Utils.setAuthData(data);
+			var data = resp.result.data;
+			if (Ext.isDefined(data.NeedTFA)) {
+			    // Store first factor login information first:
+			    data.LoggedOut = true;
+			    Proxmox.Utils.setAuthData(data);

-			if (Ext.isDefined(data.U2FChallenge)) {
-			    me.perform_u2f(data);
+			    if (Ext.isDefined(data.U2FChallenge)) {
+				me.perform_u2f(data);
+			    } else {
+				me.perform_otp();
+			    }
 			} else {
-			    me.perform_otp();
+			    me.success(data);
 			}
-		    } else {
-			me.success(data);
 		    }
-		}
-	    });
+		});
+	    }

 	},
 	failure: function(resp) {
@@ -143,6 +166,27 @@ Ext.define('PVE.window.LoginWindow', {
 		}
 	    });
 	},
+	onApiTokenDetected: function(value) {
+	    var usernameField = this.lookupReference('usernameField');
+	    var saveUsernameField = this.lookupReference('saveunField');
+	    var passwordField = this.lookupReference('passwordField');
+	    var realmField = this.lookupReference('realmField');
+	    let label = value ? 'API Token' : gettext('User name');
+	    usernameField.setFieldLabel(label);
+	    saveUsernameField.setDisabled(value);
+	    passwordField.setDisabled(value);
+	    realmField.setDisabled(value);
+
+
+	},
+	detectApiToken: function(field, newValue, oldValue) {
+	    if (Proxmox.Utils.APIToken_match.test(newValue)) {
+		this.onApiTokenDetected(true);
+	    } else {
+		this.onApiTokenDetected(false);
+	    }
+
+	},

 	control: {
 	    'field[name=username]': {
@@ -198,7 +242,6 @@ Ext.define('PVE.window.LoginWindow', {

     defaultFocus: 'usernameField',
     defaultButton: 'loginButton',
-
     items: [{
 	xtype: 'form',
 	layout: 'form',
@@ -209,7 +252,6 @@ Ext.define('PVE.window.LoginWindow', {
 	    labelAlign: 'right',
 	    allowBlank: false
 	},
-
 	items: [
 	    {
 		xtype: 'textfield',
@@ -217,7 +259,10 @@ Ext.define('PVE.window.LoginWindow', {
 		name: 'username',
 		itemId: 'usernameField',
 		reference: 'usernameField',
-		stateId: 'login-username'
+		stateId: 'login-username',
+		listeners: {
+		    change: 'detectApiToken'
+		}
 	    },
 	    {
 		xtype: 'textfield',
@@ -228,7 +273,8 @@ Ext.define('PVE.window.LoginWindow', {
 	    },
 	    {
 		xtype: 'pmxRealmComboBox',
-		name: 'realm'
+		name: 'realm',
+		reference: 'realmField'
 	    },
 	    {
 		xtype: 'proxmoxLanguageSelector',
@@ -246,8 +292,8 @@ Ext.define('PVE.window.LoginWindow', {
 		name: 'saveusername',
 		reference: 'saveunField',
 		stateId: 'login-saveusername',
-		labelWidth: 250,
 		labelAlign: 'right',
+		labelWidth: 250,
 		submitValue: false
 	    },
 	    {
--
2.20.1




More information about the pve-devel mailing list