feat: Add add_user dialog and methods

- wip
diff --git a/erpnext/hub_node/api.py b/erpnext/hub_node/api.py
index c82890c..e69a963 100644
--- a/erpnext/hub_node/api.py
+++ b/erpnext/hub_node/api.py
@@ -33,8 +33,15 @@
 
 
 @frappe.whitelist()
-def register_user(username, first_name, company):
-	pass
+def register_users(user_list):
+	user_list = json.loads(user_list)
+
+	settings = frappe.get_single('Marketplace Settings')
+
+	for user in user_list:
+		settings.add_hub_user(user)
+
+	return user_list
 
 
 def validate_registerer():
@@ -195,15 +202,11 @@
 def get_hub_connection():
 	settings = frappe.get_single('Marketplace Settings')
 	marketplace_url = settings.marketplace_url
-	current_user_records = filter(
-		lambda x: x.user == current_user and x.password,
-		settings.users
-	)
+	hub_user = settings.get_hub_user(frappe.session.user)
 
-	if current_user_records:
-		record = current_user_records[0]
-		password = frappe.get_doc('Hub User', current_user).get_password()
-		hub_connection = FrappeClient(marketplace_url, record.user, password)
+	if hub_user:
+		password = hub_user.get_password()
+		hub_connection = FrappeClient(marketplace_url, hub_user.user, password)
 		return hub_connection
 	else:
 		read_only_hub_connection = FrappeClient(marketplace_url)
diff --git a/erpnext/hub_node/doctype/marketplace_settings/marketplace_settings.py b/erpnext/hub_node/doctype/marketplace_settings/marketplace_settings.py
index 43543a8..a9dfe8a 100644
--- a/erpnext/hub_node/doctype/marketplace_settings/marketplace_settings.py
+++ b/erpnext/hub_node/doctype/marketplace_settings/marketplace_settings.py
@@ -40,6 +40,10 @@
 
 
 	def add_hub_user(self, user_email):
+		'''Create a Hub User and User record on hub server
+		and if successfull append it to Hub User table
+		'''
+
 		if not self.registered:
 			return
 
@@ -63,6 +67,17 @@
 
 		self.insert()
 
+	def get_hub_user(self, user):
+		'''Return the Hub User doc from the `users` table if password is set'''
+
+		filtered_users = filter(
+			lambda x: x.user == user and x.password,
+			self.users
+		)
+
+		if filtered_users:
+			return filtered_users[0]
+
 
 	def get_connection(self):
 		return FrappeClient(self.marketplace_url)
diff --git a/erpnext/public/js/hub/marketplace.js b/erpnext/public/js/hub/marketplace.js
index ce72042..bdcb353 100644
--- a/erpnext/public/js/hub/marketplace.js
+++ b/erpnext/public/js/hub/marketplace.js
@@ -31,6 +31,8 @@
 			this.refresh();
 			if (!is_registered && !is_registered_seller && frappe.user_roles.includes('System Manager')) {
 				this.page.set_primary_action('Become a Seller', this.show_register_dialog.bind(this))
+			} else {
+				this.page.set_secondary_action('Add Users', this.show_add_user_dialog.bind(this));
 			}
 		});
 	}
@@ -115,4 +117,46 @@
 		});
 	}
 
+	show_add_user_dialog() {
+		const user_list = Object.keys(frappe.boot.user_info)
+			.filter(user => !['Administrator', 'Guest', frappe.session.user].includes(user));
+		const d = new frappe.ui.Dialog({
+			title: __('Add Users to Marketplace'),
+			fields: [
+				{
+					label: __('Users'),
+					fieldname: 'users',
+					fieldtype: 'MultiSelect',
+					reqd: 1,
+					get_data() {
+						return user_list;
+					}
+				}
+			],
+			primary_action({ users }) {
+				const selected_users = users.split(',').map(d => d.trim()).filter(Boolean);
+
+				if (!selected_users.every(user => user_list.includes(user))) {
+					d.set_df_property('users', 'description', __('Some emails are invalid'));
+					return;
+				} else {
+					d.set_df_property('users', 'description', '');
+				}
+
+				frappe.call('erpnext.hub_node.api.register_users', {
+					user_list: selected_users
+				})
+				.then(r => {
+					d.hide();
+
+					if (r.message && r.message.length) {
+						frappe.show_alert('Added {0} users', [r.message.length]);
+					}
+				});
+			}
+		});
+
+		d.show();
+	}
+
 }