Skip to content

Commit

Permalink
🚑️ (src/db_redis): fix empty request check (#30)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ncvescera authored Oct 17, 2024
1 parent 4a6077e commit d001214
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 9 deletions.
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,13 @@ VAULT_CLIENT_SECRET=
VAULT_API_BASE_URL=
VAULT_CONF_URL=
SECRET_KEY=
ADMIN_USERS=
```

> [!NOTE]
> - `VAULT_API_BASE_URL` should be similar to `<ip>/v1/`.
> - `VAULT_CONF_URL` should be similar to `<ip>/v1/identity/oidc/provider/<provider>/.well-known/openid-configuration`. The `<provider>` string should be `default`.
> - **DON'T FORGET THE PROTOCOL (`http://` or `https://`) BEFORE THE `<ip>` STRING !!**
> - `SECRET_KEY` should be invented (not provided by Voult).
> - `ADMIN_USERS` must be a list of users id. Something like this `ADMIN_USERS='["[email protected]", "[email protected]", "[email protected]"]'`.
> - 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:
Expand All @@ -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='["[email protected]", "[email protected]", "[email protected]"]'
```

## Run
Expand Down
4 changes: 3 additions & 1 deletion src/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'])

Expand Down
3 changes: 2 additions & 1 deletion src/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
49 changes: 48 additions & 1 deletion src/db_redis.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from datetime import datetime
import redis
import requests


class DBManager():
Expand All @@ -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,
Expand All @@ -18,6 +21,7 @@ def __init__(self, app):

# consts
self.__idx = 'req'
self.__infoidx = 'info'
self.__keys = {
'startdate': 'startdate',
'enddate': 'enddate',
Expand All @@ -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")
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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"]}')

Expand All @@ -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:
Expand Down Expand Up @@ -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
4 changes: 3 additions & 1 deletion src/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion src/templates/users/admin.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{% endblock%}

{% block body %}
<h3>Welcome {{user['username']}}</h3>
<h3>Welcome {{user['infos'].get('name', user['username'])}}</h3>

<div class="position-absolute top-50 start-50 translate-middle">
<a href="{{ user['uninuvolaurl'] }}"><button type="button" class="btn btn-primary btn-lg">
Expand All @@ -19,6 +19,7 @@ <h3 class="mt-5">Request status</h3>
<thead>
<tr>
<th>Date</th>
<th>Name</th>
<th>User</th>
<th>State</th>
<th>Accepted Date</th>
Expand All @@ -29,6 +30,7 @@ <h3 class="mt-5">Request status</h3>
{% for req in user['request_data'] %}
<tr>
<td>{{req['startdate']}}</td>
<td>{{req['infos'].get('name', '-')}}</td>
<td>{{req['user']}}</td>
<td>{{req['status']}}</td>
<td>{{ req['enddate'] if req['enddate'] else '-'}}</td>
Expand Down
2 changes: 1 addition & 1 deletion src/templates/users/user.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
{% endblock %}

{% block body %}
<h3>Welcome {{user['username']}}</h3>
<h3>Welcome {{user['infos'].get('name', user['username'])}}</h3>

{% if user['request_data']|length == 0 %}
<h3 class="mt-5">Request status</h3>
Expand Down

0 comments on commit d001214

Please sign in to comment.