Allowedness (WIP)
このコミットが含まれているのは:
コミット
5a647f2fb7
|
@ -6,8 +6,9 @@ from collections import OrderedDict
|
||||||
from quart_compress import Compress
|
from quart_compress import Compress
|
||||||
|
|
||||||
from anonstream.config import update_flask_from_toml
|
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.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'
|
__version__ = '1.3.6'
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@ def create_app(toml_config):
|
||||||
'COMPRESS_LEVEL': 9,
|
'COMPRESS_LEVEL': 9,
|
||||||
})
|
})
|
||||||
|
|
||||||
# Global state: messages, users, captchas
|
# Global state: messages, users, captchas, etc.
|
||||||
app.messages_by_id = OrderedDict()
|
app.messages_by_id = OrderedDict()
|
||||||
app.messages = app.messages_by_id.values()
|
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_factory = create_captcha_factory(app.config['CAPTCHA_FONTS'])
|
||||||
app.captcha_signer = create_captcha_signer(app.config['SECRET_KEY'])
|
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
|
# State for tasks
|
||||||
app.users_update_buffer = set()
|
app.users_update_buffer = set()
|
||||||
|
|
|
@ -48,6 +48,7 @@ def generate_user(
|
||||||
'watching': -inf,
|
'watching': -inf,
|
||||||
'eyes': -inf,
|
'eyes': -inf,
|
||||||
'reading': -inf,
|
'reading': -inf,
|
||||||
|
'allowed': -inf,
|
||||||
},
|
},
|
||||||
'presence': presence,
|
'presence': presence,
|
||||||
'linespan': deque(),
|
'linespan': deque(),
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
import operator
|
import operator
|
||||||
import time
|
import time
|
||||||
|
from functools import reduce
|
||||||
from math import inf
|
from math import inf
|
||||||
|
|
||||||
from quart import current_app
|
from quart import current_app
|
||||||
|
@ -17,6 +18,7 @@ from anonstream.utils.user import get_user_for_websocket, trilean
|
||||||
CONFIG = current_app.config
|
CONFIG = current_app.config
|
||||||
MESSAGES = current_app.messages
|
MESSAGES = current_app.messages
|
||||||
USERS = current_app.users
|
USERS = current_app.users
|
||||||
|
ALLOWEDNESS = current_app.allowedness
|
||||||
CAPTCHA_SIGNER = current_app.captcha_signer
|
CAPTCHA_SIGNER = current_app.captcha_signer
|
||||||
USERS_UPDATE_BUFFER = current_app.users_update_buffer
|
USERS_UPDATE_BUFFER = current_app.users_update_buffer
|
||||||
|
|
||||||
|
@ -41,6 +43,15 @@ class DeletedEyes(EyesException):
|
||||||
class ExpiredEyes(EyesException):
|
class ExpiredEyes(EyesException):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class AllowednessException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Blacklisted(AllowednessException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class SecretClub(AllowednessException):
|
||||||
|
pass
|
||||||
|
|
||||||
def add_state(user, **state):
|
def add_state(user, **state):
|
||||||
state_id = time.time_ns() // 1_000_000
|
state_id = time.time_ns() // 1_000_000
|
||||||
user['state'][state_id] = state
|
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:
|
if just_read_new_segment:
|
||||||
eyes['n_segments'] += 1
|
eyes['n_segments'] += 1
|
||||||
eyes['renewed'] = timestamp
|
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_hash = f'\033[32m{token_hash}\033[0m'
|
||||||
token = f'\033[35m{token}\033[0m'
|
token = f'\033[35m{token}\033[0m'
|
||||||
return '/'.join((tag, token_hash, token))
|
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,
|
||||||
|
}
|
||||||
|
|
読み込み中…
新しいイシューから参照