云
2 天以前 3b5c522aad27543ea3cdddf43ff963c14c06adf2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import socket
import re
import json
import sys
from pathlib import Path
 
source = Path('yudao-server/src/main/resources/application-local.yaml').read_text(encoding='utf-8')
block = re.search(r'(?m)^    redis:\s*\n((?:      [^\n]*\n)+)', source).group(1)
redis = {key: value.split(' #')[0].strip().strip('\"\'') for key, value in re.findall(r'(?m)^      (host|port|database|password):\s*([^\n]*)', block)}
connection = socket.create_connection((redis['host'], int(redis.get('port', 6379))), timeout=10)
stream = connection.makefile('rb')
 
def read():
    kind = stream.read(1)
    value = stream.readline().rstrip(b'\r\n')
    if kind == b'-':
        raise RuntimeError(value.decode())
    if kind == b':':
        return int(value)
    if kind == b'$':
        size = int(value)
        if size < 0:
            return None
        result = stream.read(size)
        stream.read(2)
        return result
    if kind == b'*':
        return [read() for _ in range(int(value))]
    return value
 
def command(*parts):
    values = [str(p).encode() if not isinstance(p, bytes) else p for p in parts]
    connection.sendall(b'*' + str(len(values)).encode() + b'\r\n' + b''.join(b'$' + str(len(v)).encode() + b'\r\n' + v + b'\r\n' for v in values))
    return read()
 
if redis.get('password'):
    command('AUTH', redis['password'])
command('SELECT', redis.get('database', 0))
plan = json.loads(Path('scripts/permission-fix-plan.json').read_text(encoding='utf-8'))
suffixes = tuple(':' + key for key in set(plan['allKeys'] + [pair[0] for pair in plan['aliases']]))
keys = []
cursor = b'0'
while True:
    cursor, batch = command('SCAN', cursor, 'MATCH', '*permission_menu_ids*', 'COUNT', 100)
    keys.extend(key for key in batch if key.decode().endswith(suffixes))
    if cursor == b'0':
        break
menu_suffixes = tuple(':' + str(int(value)) for value in sys.argv[1:])
if menu_suffixes:
    cursor = b'0'
    while True:
        cursor, batch = command('SCAN', cursor, 'MATCH', '*menu_role_ids*', 'COUNT', 100)
        keys.extend(key for key in batch if key.decode().endswith(menu_suffixes))
        if cursor == b'0':
            break
print('Target permission cache keys:', [key.decode() for key in keys])
if keys:
    print('Deleted permission cache entries:', command('DEL', *keys))
else:
    print('No stale affected permission cache entries')
connection.close()