[pmg-devel] [PATCH v3 widget-toolkit 5/7] add ACME account panel

Wolfgang Bumiller w.bumiller at proxmox.com
Tue Mar 16 11:24:21 CET 2021


Copied from PVE with URLs now being based on the 'acmeUrl'
property which should point to the acme/ root containing
/tos, /directories, etc.

Signed-off-by: Wolfgang Bumiller <w.bumiller at proxmox.com>
---
No changes since v2

 src/Makefile              |   2 +
 src/panel/ACMEAccount.js  | 116 ++++++++++++++++++++++
 src/window/ACMEAccount.js | 204 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 322 insertions(+)
 create mode 100644 src/panel/ACMEAccount.js
 create mode 100644 src/window/ACMEAccount.js

diff --git a/src/Makefile b/src/Makefile
index d782e92..00a25c7 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -50,6 +50,7 @@ JSSRC=					\
 	panel/RRDChart.js		\
 	panel/GaugeWidget.js		\
 	panel/Certificates.js		\
+	panel/ACMEAccount.js		\
 	window/Edit.js			\
 	window/PasswordEdit.js		\
 	window/SafeDestroy.js		\
@@ -58,6 +59,7 @@ JSSRC=					\
 	window/DiskSmart.js		\
 	window/ZFSDetail.js		\
 	window/Certificates.js		\
+	window/ACMEAccount.js		\
 	node/APT.js			\
 	node/NetworkEdit.js		\
 	node/NetworkView.js		\
diff --git a/src/panel/ACMEAccount.js b/src/panel/ACMEAccount.js
new file mode 100644
index 0000000..c7d329e
--- /dev/null
+++ b/src/panel/ACMEAccount.js
@@ -0,0 +1,116 @@
+Ext.define('Proxmox.panel.ACMEAccounts', {
+    extend: 'Ext.grid.Panel',
+    xtype: 'pmxACMEAccounts',
+
+    title: gettext('Accounts'),
+
+    acmeUrl: undefined,
+
+    controller: {
+	xclass: 'Ext.app.ViewController',
+
+	addAccount: function() {
+	    let me = this;
+	    let view = me.getView();
+	    let defaultExists = view.getStore().findExact('name', 'default') !== -1;
+	    Ext.create('Proxmox.window.ACMEAccountCreate', {
+		defaultExists,
+		acmeUrl: view.acmeUrl,
+		taskDone: function() {
+		    me.reload();
+		},
+	    }).show();
+	},
+
+	viewAccount: function() {
+	    let me = this;
+	    let view = me.getView();
+	    let selection = view.getSelection();
+	    if (selection.length < 1) return;
+	    Ext.create('Proxmox.window.ACMEAccountView', {
+	        url: `${view.acmeUrl}/account/${selection[0].data.name}`,
+	    }).show();
+	},
+
+	reload: function() {
+	    let me = this;
+	    let view = me.getView();
+	    view.getStore().rstore.load();
+	},
+
+	showTaskAndReload: function(options, success, response) {
+	    let me = this;
+	    if (!success) return;
+
+	    let upid = response.result.data;
+	    Ext.create('Proxmox.window.TaskProgress', {
+		upid,
+		taskDone: function() {
+		    me.reload();
+		},
+	    }).show();
+	},
+    },
+
+    minHeight: 150,
+    emptyText: gettext('No Accounts configured'),
+
+    columns: [
+	{
+	    dataIndex: 'name',
+	    text: gettext('Name'),
+	    renderer: Ext.String.htmlEncode,
+	    flex: 1,
+	},
+    ],
+
+    listeners: {
+	itemdblclick: 'viewAccount',
+    },
+
+    store: {
+	type: 'diff',
+	autoDestroy: true,
+	autoDestroyRstore: true,
+	rstore: {
+	    type: 'update',
+	    storeid: 'proxmox-acme-accounts',
+	    model: 'proxmox-acme-accounts',
+	    autoStart: true,
+	},
+	sorters: 'name',
+    },
+
+    initComponent: function() {
+	let me = this;
+
+	if (!me.acmeUrl) {
+	    throw "no acmeUrl given";
+	}
+
+	Ext.apply(me, {
+	    tbar: [
+		{
+		    xtype: 'proxmoxButton',
+		    text: gettext('Add'),
+		    selModel: false,
+		    handler: 'addAccount',
+		},
+		{
+		    xtype: 'proxmoxButton',
+		    text: gettext('View'),
+		    handler: 'viewAccount',
+		    disabled: true,
+		},
+		{
+		    xtype: 'proxmoxStdRemoveButton',
+		    baseurl: `${me.acmeUrl}/account`,
+		    callback: 'showTaskAndReload',
+		},
+	    ],
+	});
+
+	me.callParent();
+	me.store.rstore.proxy.setUrl(`/api2/json/${me.acmeUrl}/account`);
+    },
+});
diff --git a/src/window/ACMEAccount.js b/src/window/ACMEAccount.js
new file mode 100644
index 0000000..05278a8
--- /dev/null
+++ b/src/window/ACMEAccount.js
@@ -0,0 +1,204 @@
+Ext.define('Proxmox.window.ACMEAccountCreate', {
+    extend: 'Proxmox.window.Edit',
+    mixins: ['Proxmox.Mixin.CBind'],
+    xtype: 'pmxACMEAccountCreate',
+
+    acmeUrl: undefined,
+
+    width: 450,
+    title: gettext('Register Account'),
+    isCreate: true,
+    method: 'POST',
+    submitText: gettext('Register'),
+    showTaskViewer: true,
+    defaultExists: false,
+
+    items: [
+	{
+	    xtype: 'proxmoxtextfield',
+	    fieldLabel: gettext('Account Name'),
+	    name: 'name',
+	    cbind: {
+		emptyText: (get) => get('defaultExists') ? '' : 'default',
+		allowBlank: (get) => !get('defaultExists'),
+	    },
+	},
+	{
+	    xtype: 'textfield',
+	    name: 'contact',
+	    vtype: 'email',
+	    allowBlank: false,
+	    fieldLabel: gettext('E-Mail'),
+	},
+	{
+	    xtype: 'proxmoxComboGrid',
+	    name: 'directory',
+	    reference: 'directory',
+	    allowBlank: false,
+	    valueField: 'url',
+	    displayField: 'name',
+	    fieldLabel: gettext('ACME Directory'),
+	    store: {
+		autoLoad: true,
+		fields: ['name', 'url'],
+		idProperty: ['name'],
+		proxy: { type: 'proxmox' },
+		sorters: {
+		    property: 'name',
+		    order: 'ASC',
+		},
+	    },
+	    listConfig: {
+		columns: [
+		    {
+			header: gettext('Name'),
+			dataIndex: 'name',
+			flex: 1,
+		    },
+		    {
+			header: gettext('URL'),
+			dataIndex: 'url',
+			flex: 1,
+		    },
+		],
+	    },
+	    listeners: {
+		change: function(combogrid, value) {
+		    let me = this;
+
+		    if (!value) {
+			return;
+		    }
+
+		    let acmeUrl = me.up('window').acmeUrl;
+
+		    let disp = me.up('window').down('#tos_url_display');
+		    let field = me.up('window').down('#tos_url');
+		    let checkbox = me.up('window').down('#tos_checkbox');
+
+		    disp.setValue(gettext('Loading'));
+		    field.setValue(undefined);
+		    checkbox.setValue(undefined);
+		    checkbox.setHidden(true);
+
+		    Proxmox.Utils.API2Request({
+			url: `${acmeUrl}/tos`,
+			method: 'GET',
+			params: {
+			    directory: value,
+			},
+			success: function(response, opt) {
+			    field.setValue(response.result.data);
+			    disp.setValue(response.result.data);
+			    checkbox.setHidden(false);
+			},
+			failure: function(response, opt) {
+			    Ext.Msg.alert(gettext('Error'), response.htmlStatus);
+			},
+		    });
+		},
+	    },
+	},
+	{
+	    xtype: 'displayfield',
+	    itemId: 'tos_url_display',
+	    renderer: Proxmox.Utils.render_optional_url,
+	    name: 'tos_url_display',
+	},
+	{
+	    xtype: 'hidden',
+	    itemId: 'tos_url',
+	    name: 'tos_url',
+	},
+	{
+	    xtype: 'proxmoxcheckbox',
+	    itemId: 'tos_checkbox',
+	    boxLabel: gettext('Accept TOS'),
+	    submitValue: false,
+	    validateValue: function(value) {
+		if (value && this.checked) {
+		    return true;
+		}
+		return false;
+	    },
+	},
+    ],
+
+    initComponent: function() {
+	let me = this;
+
+	if (!me.acmeUrl) {
+	    throw "no acmeUrl given";
+	}
+
+	me.url = `${me.acmeUrl}/account`;
+
+	me.callParent();
+
+	me.lookup('directory')
+	    .store
+	    .proxy
+	    .setUrl(`/api2/json/${me.acmeUrl}/directories`);
+    },
+});
+
+Ext.define('Proxmox.window.ACMEAccountView', {
+    extend: 'Proxmox.window.Edit',
+    xtype: 'pmxACMEAccountView',
+
+    width: 600,
+    fieldDefaults: {
+	labelWidth: 140,
+    },
+
+    title: gettext('Account'),
+
+    items: [
+	{
+	    xtype: 'displayfield',
+	    fieldLabel: gettext('E-Mail'),
+	    name: 'email',
+	},
+	{
+	    xtype: 'displayfield',
+	    fieldLabel: gettext('Created'),
+	    name: 'createdAt',
+	},
+	{
+	    xtype: 'displayfield',
+	    fieldLabel: gettext('Status'),
+	    name: 'status',
+	},
+	{
+	    xtype: 'displayfield',
+	    fieldLabel: gettext('Directory'),
+	    renderer: Proxmox.Utils.render_optional_url,
+	    name: 'directory',
+	},
+	{
+	    xtype: 'displayfield',
+	    fieldLabel: gettext('Terms of Services'),
+	    renderer: Proxmox.Utils.render_optional_url,
+	    name: 'tos',
+	},
+    ],
+
+    initComponent: function() {
+	var me = this;
+
+	me.callParent();
+
+	// hide OK/Reset button, because we just want to show data
+	me.down('toolbar[dock=bottom]').setVisible(false);
+
+	me.load({
+	    success: function(response) {
+		var data = response.result.data;
+		data.email = data.account.contact[0];
+		data.createdAt = data.account.createdAt;
+		data.status = data.account.status;
+		me.setValues(data);
+	    },
+	});
+    },
+});
-- 
2.20.1





More information about the pmg-devel mailing list