[pve-devel] [PATCH manager 1/1] dc/TFAEdit: rewrite enabling/disabling logic using userid/tfa api call

Dominik Csapak d.csapak at proxmox.com
Thu Apr 18 12:46:49 CEST 2019


with the new /access/users/{userid}/tfa api call, we do not need
to pass the tfa_type from the userview anymore

but the whole binding/formula handling was not really nice and
unnecessary since we set a viewmodel, which triggered a formula, which
triggered an enabling/disabling of one component

instead of that, simply enable or disable the component directly
(especially since this was only called once anyway)

keep the viewmodel for things that can change dynamically, e.g. the
tab or the validity

Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
---
 www/manager6/dc/TFAEdit.js  | 163 +++++++++++++++++++++-----------------------
 www/manager6/dc/UserView.js |   1 -
 2 files changed, 77 insertions(+), 87 deletions(-)

diff --git a/www/manager6/dc/TFAEdit.js b/www/manager6/dc/TFAEdit.js
index c57c5339..91b14007 100644
--- a/www/manager6/dc/TFAEdit.js
+++ b/www/manager6/dc/TFAEdit.js
@@ -99,48 +99,66 @@ Ext.define('PVE.window.TFAEdit', {
     viewModel: {
 	data: {
 	    in_totp_tab: true,
-	    tfa_required: false,
-	    tfa_type: undefined,
-	    valid: false,
-	    u2f_available: true
-	},
-	formulas: {
-	    canDeleteTFA: function(get) {
-		return (get('tfa_type') !== undefined && !get('tfa_required'));
-	    },
-	    canSetupTOTP: function(get) {
-		var tfa = get('tfa_type');
-		return (tfa === undefined || tfa === 'totp' || tfa === 1);
-	    },
-	    canSetupU2F: function(get) {
-		var tfa = get('tfa_type');
-		return (get('u2f_available') && (tfa === undefined || tfa === 'u2f' || tfa === 1));
-	    }
+	    valid: false
 	}
     },
 
-    afterLoadingRealm: function(realm_tfa_type) {
+    afterLoading: function(realm_type, user_type) {
 	var me = this;
-	var viewmodel = me.getViewModel();
-	if (!realm_tfa_type) {
-	    // There's no TFA enforced by the realm, everything works.
-	    viewmodel.set('u2f_available', true);
-	    viewmodel.set('tfa_required', false);
-	} else if (realm_tfa_type === 'oath') {
-	    // The realm explicitly requires TOTP
-	    viewmodel.set('tfa_required', true);
-	    viewmodel.set('u2f_available', false);
-	} else {
+	var controller = me.getController();
+
+	// exit early
+	if (realm_type && realm_type !== 'oath') {
 	    // The realm enforces some other TFA type (yubico)
 	    me.close();
 	    Ext.Msg.alert(
 		gettext('Error'),
 		Ext.String.format(
 		    gettext("Custom 2nd factor configuration is not supported on realms with '{0}' TFA."),
-		    realm_tfa_type
+		    realm_type
 		)
 	    );
+	    return;
+	}
+
+	var can_setup_totp = (realm_type === 'oath' || !user_type || user_type === 'oath');
+	var can_setup_u2f = (!realm_type && (!user_type || user_type === 'u2f'));
+	var can_delete = (!realm_type && !!user_type);
+
+	// disable tabs/buttons/labels
+	me.lookup('totp_panel').setDisabled(!can_setup_totp);
+	me.lookup('u2f_panel').setDisabled(!can_setup_u2f);
+	me.lookup('delete_button').setDisabled(!can_delete);
+	me.lookup('register_button').setDisabled(user_type === 'u2f');
+	me.lookup('delete_label').setVisible(user_type === 'u2f');
+	me.lookup('register_label').setVisible(user_type !== 'u2f');
+
+	me.qrdiv = document.createElement('center');
+	me.qrcode = new QRCode(me.qrdiv, {
+	    width: 256,
+	    height: 256,
+	    correctLevel: QRCode.CorrectLevel.M
+	});
+	me.down('#qrbox').getEl().appendChild(me.qrdiv);
+
+	if (!user_type || (user_type !== 'oath' && realm_type === 'oath')) {
+	    controller.randomizeSecret();
+	} else {
+	    me.down('#qrbox').setVisible(false);
+	    me.lookup('challenge').setVisible(false);
+	}
+
+	// change tab if totp is not available but u2f is
+	if (!can_setup_totp && can_setup_u2f) {
+	    var u2f_panel = me.lookup('u2f_panel');
+	    me.lookup('tfatabs').setActiveTab(u2f_panel);
+	}
+
+	if (Proxmox.UserName === 'root at pam') {
+	    me.lookup('password').setVisible(false);
+	    me.lookup('password').setDisabled(true);
 	}
+
     },
 
     controller: {
@@ -162,41 +180,10 @@ Ext.define('PVE.window.TFAEdit', {
 		    viewModel.set('valid', form.isValid() && challenge.isValid() && password.isValid());
 		}
 	    },
-	    '#': {
-		show: function() {
-		    var me = this.getView();
-		    var viewmodel = this.getViewModel();
-
-		    me.qrdiv = document.createElement('center');
-		    me.qrcode = new QRCode(me.qrdiv, {
-			width: 256,
-			height: 256,
-			correctLevel: QRCode.CorrectLevel.M
-		    });
-		    me.down('#qrbox').getEl().appendChild(me.qrdiv);
-
-		    viewmodel.set('tfa_type', me.tfa_type);
-		    if (!me.tfa_type) {
-			this.randomizeSecret();
-		    } else {
-			me.down('#qrbox').setVisible(false);
-			me.lookup('challenge').setVisible(false);
-			if (me.tfa_type === 'u2f') {
-			    var u2f_panel = me.lookup('u2f_panel');
-			    me.lookup('tfatabs').setActiveTab(u2f_panel);
-			}
-		    }
-
-		    if (Proxmox.UserName === 'root at pam') {
-			me.lookup('password').setVisible(false);
-			me.lookup('password').setDisabled(true);
-		    }
-		}
-	    },
 	    '#tfatabs': {
 		tabchange: function(panel, newcard) {
 		    var viewmodel = this.getViewModel();
-		    viewmodel.set('in_totp_tab', newcard.itemId === 'totp-panel');
+		    viewmodel.set('in_totp_tab', newcard.reference === 'totp_panel');
 		}
 	    }
 	},
@@ -317,12 +304,9 @@ Ext.define('PVE.window.TFAEdit', {
 		{
 		    xtype: 'panel',
 		    title: 'TOTP',
-		    itemId: 'totp-panel',
+		    reference: 'totp_panel',
 		    tfa_type: 'totp',
 		    border: false,
-		    bind: {
-			disabled: '{!canSetupTOTP}'
-		    },
 		    layout: {
 			type: 'vbox',
 			align: 'stretch'
@@ -422,7 +406,6 @@ Ext.define('PVE.window.TFAEdit', {
 		},
 		{
 		    title: 'U2F',
-		    itemId: 'u2f-panel',
 		    reference: 'u2f_panel',
 		    tfa_type: 'u2f',
 		    border: false,
@@ -431,14 +414,19 @@ Ext.define('PVE.window.TFAEdit', {
 			type: 'vbox',
 			align: 'middle'
 		    },
-		    bind: {
-			disabled: '{!canSetupU2F}'
-		    },
 		    items: [
 			{
 			    xtype: 'label',
+			    reference: 'register_label',
 			    width: 500,
 			    text: gettext('To register a U2F device, connect the device, then click the button and follow the instructions.')
+			},
+			{
+			    xtype: 'label',
+			    hidden: true,
+			    reference: 'delete_label',
+			    width: 500,
+			    text: gettext('To register a new U2F device, first delete the Information of the old one.')
 			}
 		    ]
 		}
@@ -472,41 +460,44 @@ Ext.define('PVE.window.TFAEdit', {
 	},
 	{
 	    xtype: 'button',
+	    reference: 'register_button',
 	    text: gettext('Register U2F Device'),
 	    handler: 'startU2FRegistration',
 	    bind: {
-		hidden: '{in_totp_tab}',
-		disabled: '{tfa_type}'
+		hidden: '{in_totp_tab}'
 	    }
 	},
 	{
 	    text: gettext('Delete'),
 	    reference: 'delete_button',
 	    disabled: true,
-	    handler: 'deleteTFA',
-	    bind: {
-		disabled: '{!canDeleteTFA}'
-	    }
+	    handler: 'deleteTFA'
 	}
     ],
 
     initComponent: function() {
 	var me = this;
 
-	var store = new Ext.data.Store({
-	    model: 'pve-domains',
-	    autoLoad: true
-	});
+	if (!me.userid) {
+	    throw "no userid given";
+	}
 
-	store.on('load', function() {
-	    var user_realm = me.userid.split('@')[1];
-	    var realm = me.store.findRecord('realm', user_realm);
-	    me.afterLoadingRealm(realm && realm.data && realm.data.tfa);
-	}, me);
+	me.callParent();
 
-	Ext.apply(me, { store: store });
+	Proxmox.Utils.setErrorMask(me.down('#tfatabs'), true);
 
-	me.callParent();
+	Proxmox.Utils.API2Request({
+	    url: '/access/users/' + encodeURIComponent(me.userid) + '/tfa',
+	    method: 'GET',
+	    success: function(response, opts) {
+		var data = response.result.data;
+		Proxmox.Utils.setErrorMask(me.down('#tfatabs'), false);
+		me.afterLoading(data.realm, data.user);
+	    },
+	    failure: function(response, opts) {
+		Proxmox.Utils.setErrorMask(me, response.htmlStatus);
+	    }
+	});
 
 	Ext.GlobalEvents.fireEvent('proxmoxShowHelp', 'pveum_tfa_auth');
     }
diff --git a/www/manager6/dc/UserView.js b/www/manager6/dc/UserView.js
index 8918fb2b..3c6d1a93 100644
--- a/www/manager6/dc/UserView.js
+++ b/www/manager6/dc/UserView.js
@@ -87,7 +87,6 @@ Ext.define('PVE.dc.UserView', {
 		var d = rec.data;
 		var tfa_type = PVE.Parser.parseTfaType(d.keys);
 		var win = Ext.create('PVE.window.TFAEdit',{
-		    tfa_type: tfa_type,
 		    userid: d.userid
 		});
 		win.on('destroy', reload);
-- 
2.11.0





More information about the pve-devel mailing list