[pve-devel] [PATCH pve-manager v3] fixes #1503 Add role CRUD to the GUI.

Thomas Lamprecht t.lamprecht at proxmox.com
Tue May 8 16:40:33 CEST 2018


Am 05/08/2018 um 11:32 AM schrieb René Jochum:
> As given in the subject this implements role create/update/delete over
> the manager.
> 
> There's currently no coler highlightning for "special" roles.
> 

applied, thanks!

I added a minimal fixup for the trailing whitespace on top.

A follow up suggestion: You could hide those buttons when the user
cannot possibly have permissions to create/remove/modify roles, i.e.,
if he lacks Sys.Modify on /access

In the UI we use mostly just heuristic to decide if somethings is to be
shown or not, the full access checks are done in the backend, and all
API calls will only return those elements the requesting user has
permissions on, it's probably the best to search for caps, e.g. in a
line like:

var caps = Ext.state.Manager.get('GuiCap');

and look how it gets used. The problem here is that our reduced caps for
the ui - see pve-access-control/PVE/API2/AccessControl.pm the
compute_api_permission submethod - does not include the /access
Sys.Modify (where as has other access caps like User, Group and
Permission ones), so for a neat solution you would need to add a
Sys.Modify check for /access there, this isn't really important now but
if you want to look into it you're welcomed.

cheers,
Thomas

> Signed-off-by: René Jochum <r.jochum at proxmox.com>
> ---
>   www/manager6/Makefile                   |  2 +
>   www/manager6/dc/RoleEdit.js             | 61 ++++++++++++++++++++++++++++
>   www/manager6/dc/RoleView.js             | 72 +++++++++++++++++++++++++++++++--
>   www/manager6/form/PrivilegesSelector.js | 35 ++++++++++++++++
>   4 files changed, 166 insertions(+), 4 deletions(-)
>   create mode 100644 www/manager6/dc/RoleEdit.js
>   create mode 100644 www/manager6/form/PrivilegesSelector.js
> 
> diff --git a/www/manager6/Makefile b/www/manager6/Makefile
> index 81ddcc8d..7e9877b2 100644
> --- a/www/manager6/Makefile
> +++ b/www/manager6/Makefile
> @@ -21,6 +21,7 @@ JSSRC= 				                 	\
>   	form/Boolean.js					\
>   	form/CompressionSelector.js			\
>   	form/PoolSelector.js				\
> +	form/PrivilegesSelector.js			\
>   	form/GroupSelector.js				\
>   	form/UserSelector.js				\
>   	form/RoleSelector.js				\
> @@ -185,6 +186,7 @@ JSSRC= 				                 	\
>   	dc/GroupView.js					\
>   	dc/GroupEdit.js					\
>   	dc/RoleView.js					\
> +	dc/RoleEdit.js					\
>   	dc/ACLView.js					\
>   	dc/AuthView.js					\
>   	dc/AuthEdit.js					\
> diff --git a/www/manager6/dc/RoleEdit.js b/www/manager6/dc/RoleEdit.js
> new file mode 100644
> index 00000000..f38c23ce
> --- /dev/null
> +++ b/www/manager6/dc/RoleEdit.js
> @@ -0,0 +1,61 @@
> +Ext.define('PVE.dc.RoleEdit', {
> +    extend: 'Proxmox.window.Edit',
> +    xtype: 'pveDcRoleEdit',
> +
> +    width: 400,
> +
> +    initComponent : function() {
> +	var me = this;
> +
> +	me.isCreate = !me.roleid;
> +
> +	var url;
> +	var method;
> +
> +	if (me.isCreate) {
> +	    url = '/api2/extjs/access/roles';
> +	    method = 'POST';
> +	} else {
> +	    url = '/api2/extjs/access/roles/' + me.roleid;
> +	    method = 'PUT';
> +	}
> +
> +	Ext.applyIf(me, {
> +	    subject: gettext('Role'),
> +	    url: url,
> +	    method: method,
> +	    items: [
> +		{
> +		    xtype: me.isCreate ? 'proxmoxtextfield' : 'displayfield',
> +		    name: 'roleid',
> +		    value: me.roleid,
> +		    allowBlank: false,
> +		    fieldLabel: gettext('Name')
> +		},
> +		{
> +		    xtype: 'pvePrivilegesSelector',
> +		    name: 'privs',
> +		    value: me.privs,
> +		    allowBlank: false,
> +		    fieldLabel: gettext('Privileges')
> +		}
> +	    ]
> +	});
> +
> +	me.callParent();
> +	
> +	if (!me.isCreate) {
> +	    me.load({
> +		success: function(response) {
> +		    var data = response.result.data;
> +		    var keys = Ext.Object.getKeys(data);
> +
> +		    me.setValues({
> +			privs: keys,
> +			roleid: me.roleid
> +		    });
> +		}
> +	    });
> +	}
> +    }
> +});
> diff --git a/www/manager6/dc/RoleView.js b/www/manager6/dc/RoleView.js
> index 611dfbb6..23d82b9f 100644
> --- a/www/manager6/dc/RoleView.js
> +++ b/www/manager6/dc/RoleView.js
> @@ -13,9 +13,9 @@ Ext.define('PVE.dc.RoleView', {
>   
>   	var store = new Ext.data.Store({
>   	    model: 'pve-roles',
> -	    sorters: {
> -		property: 'roleid',
> -		order: 'DESC'
> +	    sorters: {
> +		property: 'roleid',
> +		order: 'DESC'
>   	    }
>   	});
>   
> @@ -33,14 +33,46 @@ Ext.define('PVE.dc.RoleView', {
>   
>   	Proxmox.Utils.monStoreErrors(me, store);
>   
> +	var sm = Ext.create('Ext.selection.RowModel', {});
> +
> +	var reload = function() {
> +		store.load();
> +	};
> +
> +	var run_editor = function() {
> +	    var rec = sm.getSelection()[0];
> +	    if (!rec) {
> +		return;
> +	    }
> +
> +	    if (rec.data.special === "1") {
> +		return;
> +	    }
> +
> +	    var win = Ext.create('PVE.dc.RoleEdit',{
> +		roleid: rec.data.roleid,
> +		privs: rec.data.privs,
> +	    });
> +	    win.on('destroy', reload);
> +	    win.show();
> +	};
> +
>   	Ext.apply(me, {
>   	    store: store,
> +	    selModel: sm,
>   
>   	    viewConfig: {
>   		trackOver: false
>   	    },
>   	    columns: [
>   		{
> +		    header: gettext('Built-In'),
> +		    width: 65,
> +		    sortable: true,
> +		    dataIndex: 'special',
> +		    renderer: Proxmox.Utils.format_boolean
> +		},
> +		{
>   		    header: gettext('Name'),
>   		    width: 150,
>   		    sortable: true,
> @@ -58,8 +90,40 @@ Ext.define('PVE.dc.RoleView', {
>   	    listeners: {
>   		activate: function() {
>   		    store.load();
> +		},
> +		itemdblclick: run_editor,
> +	    },
> +	    tbar: [
> +		{
> +		    text: gettext('Create'),
> +		    handler: function() {
> +			var win = Ext.create('PVE.dc.RoleEdit', {});
> +			win.on('destroy', reload);
> +			win.show();
> +		    }
> +		},
> +		{
> +		    xtype: 'proxmoxButton',
> +		    text: gettext('Edit'),
> +		    disabled: true,
> +		    selModel: sm,
> +		    handler: run_editor,
> +		    enableFn: function(record) {
> +			return record.data.special !== '1';
> +		    }
> +		},
> +		{
> +		    xtype: 'proxmoxStdRemoveButton',
> +		    selModel: sm,
> +		    callback: function() {
> +			reload();
> +		    },
> +		    baseurl: '/access/roles/',
> +		    enableFn: function(record) {
> +			return record.data.special !== '1';
> +		    }
>   		}
> -	    }
> +	    ]
>   	});
>   
>   	me.callParent();
> diff --git a/www/manager6/form/PrivilegesSelector.js b/www/manager6/form/PrivilegesSelector.js
> new file mode 100644
> index 00000000..c57cbbf4
> --- /dev/null
> +++ b/www/manager6/form/PrivilegesSelector.js
> @@ -0,0 +1,35 @@
> +Ext.define('PVE.form.PrivilegesSelector', {
> +    extend: 'Proxmox.form.KVComboBox',
> +    xtype: 'pvePrivilegesSelector',
> +
> +    multiSelect: true,
> +
> +    initComponent: function() {
> +	var me = this;
> +
> +	// So me.store is available.
> +	me.callParent();
> +
> +	Proxmox.Utils.API2Request({
> +	    url: '/access/roles/Administrator',
> +	    method: 'GET',
> +	    success: function(response, options) {
> +		var data = [];
> +		for (var key in response.result.data) {
> +		    data.push([key, key]);
> +		}
> +
> +		me.store.setData(data);
> +
> +		me.store.sort({
> +		    property: 'key',
> +		    direction: 'ASC'
> +		});
> +	    },
> +
> +	    failure: function (response, opts) {
> +		Ext.Msg.alert(gettext('Error'), response.htmlStatus);
> +	    }
> +	});
> +    }
> +});
> 





More information about the pve-devel mailing list