Allowedness (WIP)
このコミットが含まれているのは:
コミット
5a647f2fb7
|
@ -6,8 +6,9 @@ from collections import OrderedDict
|
|||
from quart_compress import Compress
|
||||
|
||||
from anonstream.config import update_flask_from_toml
|
||||
from anonstream.utils.captcha import create_captcha_factory, create_captcha_signer
|
||||
from anonstream.quart import Quart
|
||||
from anonstream.utils.captcha import create_captcha_factory, create_captcha_signer
|
||||
from anonstream.utils.user import generate_blank_allowedness
|
||||
|
||||
__version__ = '1.3.6'
|
||||
|
||||
|
@ -30,7 +31,7 @@ def create_app(toml_config):
|
|||
'COMPRESS_LEVEL': 9,
|
||||
})
|
||||
|
||||
# Global state: messages, users, captchas
|
||||
# Global state: messages, users, captchas, etc.
|
||||
app.messages_by_id = OrderedDict()
|
||||
app.messages = app.messages_by_id.values()
|
||||
|
||||
|
@ -41,7 +42,8 @@ def create_app(toml_config):
|
|||
app.captcha_factory = create_captcha_factory(app.config['CAPTCHA_FONTS'])
|
||||
app.captcha_signer = create_captcha_signer(app.config['SECRET_KEY'])
|
||||
|
||||
app.failures = OrderedDict()
|
||||
app.failures = OrderedDict() # access captcha failures
|
||||
app.allowedness = generate_blank_allowedness()
|
||||
|
||||
# State for tasks
|
||||
app.users_update_buffer = set()
|
||||
|
|
|
@ -48,6 +48,7 @@ def generate_user(
|
|||
'watching': -inf,
|
||||
'eyes': -inf,
|
||||
'reading': -inf,
|
||||
'allowed': -inf,
|
||||
},
|
||||
'presence': presence,
|
||||
'linespan': deque(),
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import operator
|
||||
import time
|
||||
from functools import reduce
|
||||
from math import inf
|
||||
|
||||
from quart import current_app
|
||||
|
@ -17,6 +18,7 @@ from anonstream.utils.user import get_user_for_websocket, trilean
|
|||
CONFIG = current_app.config
|
||||
MESSAGES = current_app.messages
|
||||
USERS = current_app.users
|
||||
ALLOWEDNESS = current_app.allowedness
|
||||
CAPTCHA_SIGNER = current_app.captcha_signer
|
||||
USERS_UPDATE_BUFFER = current_app.users_update_buffer
|
||||
|
||||
|
@ -41,6 +43,15 @@ class DeletedEyes(EyesException):
|
|||
class ExpiredEyes(EyesException):
|
||||
pass
|
||||
|
||||
class AllowednessException(Exception):
|
||||
pass
|
||||
|
||||
class Blacklisted(AllowednessException):
|
||||
pass
|
||||
|
||||
class SecretClub(AllowednessException):
|
||||
pass
|
||||
|
||||
def add_state(user, **state):
|
||||
state_id = time.time_ns() // 1_000_000
|
||||
user['state'][state_id] = state
|
||||
|
@ -302,3 +313,31 @@ def renew_eyes(timestamp, user, eyes_id, just_read_new_segment=False):
|
|||
if just_read_new_segment:
|
||||
eyes['n_segments'] += 1
|
||||
eyes['renewed'] = timestamp
|
||||
|
||||
def ensure_allowedness(user, timestamp=None):
|
||||
if timestamp is None:
|
||||
timestamp = get_timestamp()
|
||||
|
||||
# Check against blacklist
|
||||
for keytuple, values in ALLOWEDNESS['blacklist'].items():
|
||||
try:
|
||||
value = reduce(lambda mapping, key: mapping[key], keytuple, user)
|
||||
except (KeyError, TypeError):
|
||||
value = None
|
||||
if value in values:
|
||||
raise Blacklisted
|
||||
|
||||
# Check against whitelist
|
||||
for keytuple, values in ALLOWEDNESS['whitelist'].items():
|
||||
try:
|
||||
value = reduce(lambda mapping, key: mapping[key], keytuple, user)
|
||||
except (KeyError, TypeError):
|
||||
value = None
|
||||
if value in values:
|
||||
break
|
||||
else:
|
||||
# Apply default
|
||||
if not ALLOWEDNESS['default']:
|
||||
raise SecretClub
|
||||
|
||||
user['last']['allowed'] = timestamp
|
||||
|
|
|
@ -60,3 +60,17 @@ def identifying_string(user, ansi=True):
|
|||
token_hash = f'\033[32m{token_hash}\033[0m'
|
||||
token = f'\033[35m{token}\033[0m'
|
||||
return '/'.join((tag, token_hash, token))
|
||||
|
||||
def generate_blank_allowedness():
|
||||
return {
|
||||
'blacklist': {
|
||||
('token',): set(),
|
||||
('token_hash',): set(),
|
||||
},
|
||||
'whitelist': {
|
||||
('token',): set(),
|
||||
('token_hash',): set(),
|
||||
('tripcode', 'digest'): set(),
|
||||
},
|
||||
'default': True,
|
||||
}
|
||||
|
|
読み込み中…
新しいイシューから参照