diff --git a/app/classes/shared/models.py b/app/classes/shared/models.py index bfd8a0cd..063b45d2 100644 --- a/app/classes/shared/models.py +++ b/app/classes/shared/models.py @@ -118,7 +118,7 @@ class User_Servers(BaseModel): class Role_Servers(BaseModel): - user_id = ForeignKeyField(Roles, backref='role_server') + role_id = ForeignKeyField(Roles, backref='role_server') server_id = ForeignKeyField(Servers, backref='role_server') class Meta: @@ -198,6 +198,8 @@ class db_builder: Host_Stats, Webhooks, Servers, + User_Servers, + Role_Servers, Server_Stats, Commands, Audit_Log @@ -316,31 +318,67 @@ class db_shortcuts: return None @staticmethod - def get_user(uid): - query = Users.select(Users, Roles).join(User_Roles, JOIN.LEFT_OUTER).join(Roles, JOIN.LEFT_OUTER).where(Users.user_id == uid) - query = [model_to_dict(r) for r in query] - if len(query) > 0: - user = query[0].copy() + def get_user(user_id): + user = model_to_dict(Users.get(Users.user_id == user_id)) + + if user: + roles_query = User_Roles.select().join(Roles, JOIN.INNER).where(User_Roles.user_id == user_id) + # TODO: this query needs to be narrower + roles = set() + for r in roles_query: + roles.add(r.role_id.role_id) + servers_query = User_Servers.select().join(Servers, JOIN.INNER).where(User_Servers.user_id == user_id) + # TODO: this query needs to be narrower + servers = set() + for s in servers_query: + servers.add(s.server_id.server_id) + user['roles'] = roles + user['servers'] = servers + logger.debug("user: ({}) {}".format(user_id, user)) return user else: + logger.debug("user: ({}) {}".format(user_id, {})) return {} @staticmethod def update_user(user_id, user_data={}): base_data = db_helper.get_user(user_id) up_data = {} + added_roles = set() + removed_roles = set() + added_servers = set() + removed_servers = set() for key in user_data: if key == "user_id": continue elif key == "roles": - continue + added_roles = user_data['roles'].difference(base_data['roles']) + removed_roles = base_data['roles'].difference(user_data['roles']) + elif key == "servers": + added_servers = user_data['servers'].difference(base_data['servers']) + removed_servers = base_data['servers'].difference(user_data['servers']) elif key == "regen_api": - up_data['api_token'] = db_shortcuts.new_api_token() + if user_data['regen_api']: + up_data['api_token'] = db_shortcuts.new_api_token() elif key == "password": - up_data['password'] = helper.encode_pass(user_data['password']) + if user_data['password'] is not None and user_data['password'] != "": + up_data['password'] = helper.encode_pass(user_data['password']) elif base_data[key] != user_data[key]: up_data[key] = user_data[key] - Users.update(up_data).where(Users.user_id == user_id).execute() + logger.debug("user: {} +role:{} -role:{} +server:{} -server{}".format(user_data, added_roles, removed_roles, added_servers, removed_servers)) + with database.atomic(): + for role in added_roles: + User_Roles.get_or_create(user_id=user_id, role_id=role) + # TODO: This is horribly inefficient and we should be using bulk queries but im going for functionality at this point + User_Roles.delete().where(User_Roles.user_id == user_id).where(User_Roles.role_id.in_(removed_roles)).execute() + + for server in added_servers: + User_Servers.get_or_create(user_id=user_id, server_id=server) + # TODO: This is horribly inefficient and we should be using bulk queries but im going for functionality at this point + User_Servers.delete().where(User_Servers.user_id == user_id).where(User_Servers.server_id.in_(removed_servers)).execute() + if up_data: + Users.update(up_data).where(Users.user_id == user_id).execute() + @staticmethod diff --git a/app/classes/web/panel_handler.py b/app/classes/web/panel_handler.py index 8c231f7f..716f8f75 100644 --- a/app/classes/web/panel_handler.py +++ b/app/classes/web/panel_handler.py @@ -120,6 +120,10 @@ class PanelHandler(BaseHandler): elif page == 'panel_config': page_data['users'] = db_helper.get_all_users() + exec_user = db_helper.get_user(user_data['user_id']) + for user in page_data['users']: + if user.user_id != exec_user['user_id']: + user.api_token = "********" template = "panel/panel_config.html" elif page == "add_user": @@ -129,9 +133,15 @@ class PanelHandler(BaseHandler): page_data['user']['user_id'] = -1 page_data['user']['enabled'] = True page_data['user']['superuser'] = False - page_data['user']['roles'] = [] + page_data['user']['api_token'] = "N/A" + page_data['user']['created'] = "N/A" + page_data['user']['last_login'] = "N/A" + page_data['user']['last_ip'] = "N/A" + page_data['user']['roles'] = set() + page_data['user']['servers'] = set() page_data['roles_all'] = db_helper.get_all_roles() + page_data['servers_all'] = controller.list_defined_servers() template = "panel/panel_edit_user.html" elif page == "edit_user": @@ -139,6 +149,12 @@ class PanelHandler(BaseHandler): uid = self.get_argument('id', None) page_data['user'] = db_helper.get_user(uid) page_data['roles_all'] = db_helper.get_all_roles() + page_data['servers_all'] = controller.list_defined_servers() + + exec_user = db_helper.get_user(user_data['user_id']) + + if exec_user['user_id'] != page_data['user']['user_id']: + page_data['user']['api_token'] = "********" template = "panel/panel_edit_user.html" elif page == "remove_user": @@ -269,17 +285,38 @@ class PanelHandler(BaseHandler): self.redirect("/panel/error?error=Passwords must match") return False + roles = set() + for server in db_helper.get_all_roles(): + argument = int(float( + bleach.clean( + self.get_argument('role_{}_membership'.format(role['role_id']), '0') + ) + )) + if argument: + servers.add(role['role_id']) + + servers = set() + for server in controller.list_defined_servers(): + argument = int(float( + bleach.clean( + self.get_argument('server_{}_access'.format(server['server_id']), '0') + ) + )) + if argument: + servers.add(server['server_id']) + user_data = { "username": username, "password": password0, "enabled": enabled, "regen_api": regen_api, - "roles": [] + "roles": roles, + "servers": servers } db_helper.update_user(user_id, user_data=user_data) db_helper.add_to_audit_log(exec_user['user_id'], - "Edited user {} (UID:{})".format(username, user_id), + "Edited user {} (UID:{}) with roles {} and servers {}".format(username, user_id, roles, servers), server_id=0, source_ip=self.get_remote_ip()) self.redirect("/panel/panel_config") @@ -309,14 +346,35 @@ class PanelHandler(BaseHandler): self.redirect("/panel/error?error=Passwords must match") return False + roles = set() + for server in db_helper.get_all_roles(): + argument = int(float( + bleach.clean( + self.get_argument('role_{}_membership'.format(role['role_id']), '0') + ) + )) + if argument: + roles.add(role['role_id']) + + servers = set() + for server in controller.list_defined_servers(): + argument = int(float( + bleach.clean( + self.get_argument('server_{}_access'.format(server['server_id']), '0') + ) + )) + if argument: + servers.add(server['server_id']) + user_id = db_helper.add_user(username, password=password0, enabled=enabled) + db_helper.update_user(user_id, {"roles":roles, "servers": servers}) db_helper.add_to_audit_log(exec_user['user_id'], "Added user {} (UID:{})".format(username, user_id), server_id=0, source_ip=self.get_remote_ip()) db_helper.add_to_audit_log(exec_user['user_id'], - "Edited user {} (UID:{})".format(username, user_id), + "Edited user {} (UID:{}) with roles {} and servers {}".format(username, user_id, roles, servers), server_id=0, source_ip=self.get_remote_ip()) self.redirect("/panel/panel_config") \ No newline at end of file diff --git a/app/frontend/templates/panel/panel_edit_user.html b/app/frontend/templates/panel/panel_edit_user.html index c5d5df18..9f01988a 100644 --- a/app/frontend/templates/panel/panel_edit_user.html +++ b/app/frontend/templates/panel/panel_edit_user.html @@ -75,11 +75,6 @@ -
Server Name | +Access? | +
---|---|
{{ server['server_name'] }} | ++ {% if server['server_id'] in data['user']['servers'] %} + + {% else %} + + {% end %} + | +