From d0012142238b778b7cfde8396f053cb04119d708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Vescera?= Date: Thu, 17 Oct 2024 09:10:19 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=91=EF=B8=8F=20(src/db=5Fredis):=20fix?= =?UTF-8?q?=20empty=20request=20check=20(#30)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed a wrong if statement in `get_request_data()`: `request_data[key]` could be `None` (because it's a string Key) or `set()` (because it's a set Key), respectively generated by `__get_key()` and `__get_skey()`. Need to check that req. data is not None and then is not an empty set. Added ldapsync support and updated UI ## Commits * 🚑️ (src/db_redis): fix emty request check Fixed a wrong if statement in `get_request_data()`: `request_data[key]` could be `None` (because it's a string Key) or `set()` (because it's a set Key), respectively generated by `__get_key()` and `__get_skey`. Need to check that req. data is not None and then is not an empty set. * 🚑 (src/routes): fix `KeyError` for new requests * 🔥 (src/): remove `ADMIN_USERS` Removed old `ADMIN_USERS` config from code. * 📝 (README): remove `ADMIN_USERS` * ✨ (src/db_redis): update groups when updating request When a requests is approved (passing from `pending` to `approved`), `groups` key are set by adding `users`. * ✨ (src/): add user infos Added functions to get and use redis userinfos keys. * 🐛 (src/db_redis): fix wrong var name * 🐛 (src/db_redis): fix missing string in logging * 💄 (src/templates/users/admin): add full user's name * 🐛 (src/routes): fix wrong argument * 🐛 (src/db_redis): fix wrong redis key format * 💄 (src/): add user's name in admin view * ✨ (src/): add notify ldapsync function * 🐛 (src/db_redis): add protocol to ldap notify * 💄 (src/templates/users/user): update user's name --- README.md | 3 --- src/app.py | 4 ++- src/config.py | 3 ++- src/db_redis.py | 49 +++++++++++++++++++++++++++++++++- src/routes.py | 4 ++- src/templates/users/admin.html | 4 ++- src/templates/users/user.html | 2 +- 7 files changed, 60 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 0a00a1c..7262f5c 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,6 @@ VAULT_CLIENT_SECRET= VAULT_API_BASE_URL= VAULT_CONF_URL= SECRET_KEY= -ADMIN_USERS= ``` > [!NOTE] @@ -33,7 +32,6 @@ ADMIN_USERS= > - `VAULT_CONF_URL` should be similar to `/v1/identity/oidc/provider//.well-known/openid-configuration`. The `` string should be `default`. > - **DON'T FORGET THE PROTOCOL (`http://` or `https://`) BEFORE THE `` STRING !!** > - `SECRET_KEY` should be invented (not provided by Voult). -> - `ADMIN_USERS` must be a list of users id. Something like this `ADMIN_USERS='["alice.alice@alice.it", "prova@unipg.it", "eliasforna@gmail.com"]'`. > - Replace email with usernames or whatever you want. Be careful with `'` and `"`, these must be used exactly as in the example. One example of a configuration is shown below: @@ -44,7 +42,6 @@ VAULT_CLIENT_SECRET=hvo_secret_TcKGRPh3sjC1WE4PrS2GV3XYpY2AkL0FEgYWRNQUPw7rLTYSS VAULT_API_BASE_URL=http://localhost:8200/v1/ VAULT_CONF_URL=http://127.0.0.1:8200/v1/identity/oidc/provider/default/.well-known/openid-configuration SECRET_KEY=!secret -ADMIN_USERS='["alice.alice@unipg.it", "prova@unipg.it", "eliasforna@gmail.com"]' ``` ## Run diff --git a/src/app.py b/src/app.py index d13cb48..a31f6a9 100644 --- a/src/app.py +++ b/src/app.py @@ -46,7 +46,9 @@ app.redis_ip = app.config['REDIS_IP'] app.redis_password = app.config['REDIS_PASSWORD'] -app.logger.debug(f"ADMIN USERS: {app.config['ADMIN_USERS']}") +app.logger.debug("Setting LDAPSYNC ip and port: %s %s", app.config['LDAPSYNC_IP'], app.config['LDAPSYNC_PORT']) +app.ldapsync_ip = app.config['LDAPSYNC_IP'] +app.ldapsync_port = app.config['LDAPSYNC_PORT'] app.logger.debug("SERVER NAME: %s", app.config['SERVER_NAME']) diff --git a/src/config.py b/src/config.py index 04bce23..18d5cb5 100644 --- a/src/config.py +++ b/src/config.py @@ -9,6 +9,7 @@ VAULT_CONF_URL = os.getenv('VAULT_CONF_URL') SERVER_NAME = os.getenv('WEB_PUBLIC_URL') SECRET_KEY = os.getenv('SECRET_KEY') -ADMIN_USERS = json.loads(os.getenv('ADMIN_USERS')) REDIS_IP = os.getenv('REDIS_IP') REDIS_PASSWORD = os.getenv('REDIS_PASSWORD') +LDAPSYNC_IP = os.getenv('LDAPSYNC_IP') +LDAPSYNC_PORT = os.getenv('LDAPSYNC_PORT') diff --git a/src/db_redis.py b/src/db_redis.py index 1efd870..8baf82f 100644 --- a/src/db_redis.py +++ b/src/db_redis.py @@ -1,5 +1,6 @@ from datetime import datetime import redis +import requests class DBManager(): @@ -8,6 +9,8 @@ def __init__(self, app): self.logger = app.logger self.REDIS_IP = app.redis_ip self.REDIS_PASSWORD = app.redis_password + self.LDAPSYNC_IP = app.ldapsync_ip + self.LDAPSYNC_PORT = app.ldapsync_port self.connection = redis.Redis( host=self.REDIS_IP, @@ -18,6 +21,7 @@ def __init__(self, app): # consts self.__idx = 'req' + self.__infoidx = 'info' self.__keys = { 'startdate': 'startdate', 'enddate': 'enddate', @@ -30,6 +34,10 @@ def __init__(self, app): 'synced': 'synced', } + def __notify_ldapsync(self): + self.logger.info('NOTIFY LDAPSYNC') + r = requests.get(url=f"http://{self.LDAPSYNC_IP}:{self.LDAPSYNC_PORT}") + self.logger.debug("TRIGGERED LDAPSYNC, RESPONSE: %s", r) def __del__(self): self.logger.debug("Closing DB connection") @@ -57,6 +65,10 @@ def __set_key(self, key: str, value: str): self.logger.debug("SETTING KEY: %s --> %s", key, value) self.connection.set(key, value) + def __add_to_set(self, key: str, values: list): + self.logger.debug("ADDING %s TO %s", values, key) + self.connection.sadd(key, *values) + def __get_key(self, key: str) -> str: value = self.connection.get(key) self.logger.debug("GET KEY: %s --> %s", key, value) @@ -107,6 +119,8 @@ def add_request(self, user: str): self.__request_statuses['pending'], ) + self.__notify_ldapsync() + def delete_request(self, user: str): self.__valid_user(user) @@ -141,6 +155,9 @@ def update_request_status(self, user: str): if new_request_status == self.__request_statuses['approved']: self.__set_key(f'{self.__idx}:{user}:{self.__keys["enddate"]}', str(datetime.now())) + self.__add_to_set(f'{self.__idx}:{user}:{self.__keys["groups"]}', ["users"]) + self.__notify_ldapsync() + else: self.__del_key(f'{self.__idx}:{user}:{self.__keys["enddate"]}') @@ -158,7 +175,11 @@ def get_request_data(self, user: str) -> dict[str, str]: else: request_data[key] = self.__get_key(f'{self.__idx}:{user}:{key}') - if request_data[key] is not None: + # `request_data[key]` could be `None` (because it's a string Key) or + # `set()` (because it's a set Key), respectively generated by `__get_key()` and + # `__get_skey`. Need to check that req. data is not None and then is not an + # empty set. + if request_data[key] is not None and request_data[key] != set(): request_empty = False if request_empty: @@ -195,7 +216,33 @@ def get_all_request_data(self): for user in users: request_data = self.get_request_data(user) request_data['user'] = user + request_data['infos'] = self.get_user_infos(user) all_requests_data.append(request_data) return all_requests_data + + def get_user_infos(self, user: str) -> dict: + self.logger.info("GETTING USER %s INFOS", user) + + self.__valid_user(user) + + user_infos = {} + infos_empty = True + infokeys = self.connection.keys(f'{self.__infoidx}:{user}:*') + + self.logger.debug("USER %s KEYS: %s", user, infokeys) + + for key in infokeys: + dictkey = key.split(':')[-1] + user_infos[dictkey] = self.__get_key(key) + + if user_infos[dictkey] is not None: + infos_empty = False + + self.logger.debug("USER INFOS: %s", user_infos) + + if infos_empty: + return {} + + return user_infos diff --git a/src/routes.py b/src/routes.py index f3d9dd8..e652eeb 100644 --- a/src/routes.py +++ b/src/routes.py @@ -10,9 +10,11 @@ def homepage(): if user: _username = user['metadata']['name'] - _groups = dbms.get_request_data(_username)['groups'] + _groups = dbms.get_request_data(_username).get('groups', []) + _infos = dbms.get_user_infos(_username) user['username'] = _username user['groups'] = _groups + user['infos'] = _infos user['uninuvolaurl'] = 'https://compute.uninuvola.unipg.it/hub/oauth_login?next=' # ADMIN ROLE diff --git a/src/templates/users/admin.html b/src/templates/users/admin.html index fb28650..59bdad0 100644 --- a/src/templates/users/admin.html +++ b/src/templates/users/admin.html @@ -4,7 +4,7 @@ {% endblock%} {% block body %} -

Welcome {{user['username']}}

+

Welcome {{user['infos'].get('name', user['username'])}}