import redis import frappe from frappe.utils import get_bench_id, random_string class RedisQueue: def __init__(self, conn): self.conn = conn def add_user(self, username, password=None): """Create or update the user. """ password = password or self.conn.acl_genpass() user_settings = self.get_new_user_settings(username, password) is_created = self.conn.acl_setuser(**user_settings) return frappe._dict(user_settings) if is_created else {} @classmethod def get_connection(cls, username=None, password=None): rq_url = frappe.local.conf.redis_queue domain = rq_url.split("redis://", 1)[-1] url = (username and f"redis://{username}:{password or ''}@{domain}") or rq_url conn = redis.from_url(url) conn.ping() return conn @classmethod def new(cls, username='default', password=None): return cls(cls.get_connection(username, password)) @classmethod def set_admin_password(cls, cur_password=None, new_password=None, reset_passwords=False): username = 'default' conn = cls.get_connection(username, cur_password) password = '+'+(new_password or conn.acl_genpass()) conn.acl_setuser( username=username, enabled=True, reset_passwords=reset_passwords, passwords=password ) return password[1:] @classmethod def get_new_user_settings(cls, username, password): d = {} d['username'] = username d['passwords'] = '+'+password d['reset_keys'] = True d['enabled'] = True d['keys'] = cls.get_acl_key_rules() d['commands'] = cls.get_acl_command_rules() return d @classmethod def get_acl_key_rules(cls, include_key_prefix=False): """FIXME: Find better way """ rules = ['rq:[^q]*', 'rq:queues', f'rq:queue:{get_bench_id()}:*'] if include_key_prefix: return ['~'+pattern for pattern in rules] return rules @classmethod def get_acl_command_rules(cls): return ['+@all', '-@admin'] @classmethod def gen_acl_list(cls, set_admin_password=False): """Generate list of ACL users needed for this branch. This list contains default ACL user and the bench ACL user(used by all sites incase of ACL is enabled). """ bench_username = get_bench_id() bench_user_rules = cls.get_acl_key_rules(include_key_prefix=True) + cls.get_acl_command_rules() bench_user_rule_str = ' '.join(bench_user_rules).strip() bench_user_password = random_string(20) default_username = 'default' _default_user_password = random_string(20) if set_admin_password else '' default_user_password = '>'+_default_user_password if _default_user_password else 'nopass' return [ f'user {default_username} on {default_user_password} ~* &* +@all', f'user {bench_username} on >{bench_user_password} {bench_user_rule_str}' ], {'bench': (bench_username, bench_user_password), 'default': (default_username, _default_user_password)}