import base64 import logging import string from secrets import choice import requests from django.conf import settings _log = logging.getLogger(__name__) class RabbitMQUserManagement: def __init__(self, uuid): self.uuid = uuid def create_random_rabbitmq_credentials(self): """Create a username and password to connect to RabbitMQ""" username = f'sensor_{self.uuid}' password = ''.join(choice(string.ascii_uppercase + string.digits) for i in range(20)) source_credentials = username + '@@' + password credentials_bytes = source_credentials.encode() b64_credentials = base64.b64encode(credentials_bytes) final_credentials = b64_credentials.decode() self._create_rabbitmq_user(username, password) self._set_rabbitmq_permissions(username) return final_credentials @staticmethod def _create_rabbitmq_user(username, password): data = { 'password': password, 'tags': '' } response = requests.put(f'http://{settings.RABBIT_HOST}:15672/api/users/{username}/', auth=('guest', 'guest'), json=data) if response.ok: _log.info(f'RabbitMQ user {username} created') else: _log.error(f'Error creating RabbitMQ user {username}') @staticmethod def _set_rabbitmq_permissions(username): vhost = '%2F' # стандартный хост, на котором находится сервер RabbitMQ. это просто закодированный слэш "/" # https://www.rabbitmq.com/access-control.html#authorisation data = { # юзер может кофигурировать (создавать. удалять, изменять) только свою очередь "configure": username, # может писать в автоматически сгенерированные очереди или в свою "write": f'^(amq.gen.*|amq.default|{username})$', # может читать из своей очереди или из общей для всех сенсоров "read": f"sensors|{username}" } response = requests.put(f'http://{settings.RABBIT_HOST}:15672/api/permissions/{vhost}/{username}/', auth=('guest', 'guest'), json=data) if response.ok: _log.info(f'Set permissions for RabbitMQ user {username}') else: _log.error(f'Error setting permissions for RabbitMQ user {username}')