def user_authenticated(user_token: str, username: str, privilege_level: int, ttl: int) -> None: """ » Subscribed to user_authenticated Populates the cache with info about the user. :param user_token: The user token of the user who just authenticated themselves :param username: The username token of the user who just authenticated themselves :param privilege_level: The privilege level of the user who just authenticated themselves :param ttl: The ttl of the record :return: None """ # print(username, "authenticated.") # TODO: log event active_users = memcache.get("user_cache.active_users") active_users[user_token] = { 'last_seen': time.time(), 'username': username, 'privilege_level': privilege_level, 'ttl': ttl } old_sessions = [] for token, record in active_users.items(): if record['username'] == username and token != user_token: old_sessions.append(token) for token in old_sessions: del active_users[token] memcache.set("user_cache.active_users", active_users)
def init_pubsub(): """ Should be called once on server startup. Initializes the persistent cache. :return: None """ memcache.set("pubsub.topics", dict({}))
def init_user_cache(): """ Should be called once on server startup. Initializes the persistent cache. :return: None """ memcache.set("user_cache.active_users", dict({})) sub('user_activity', activity) sub('user_authenticated', user_authenticated)
def init_config(): """ Should be called once on server startup. Initializes the persistent cache and loads all config values from disk. :return: None """ # TODO: absolute poth for config path in bootstrap script # TODO: log errors with open("./pynitus.yaml") as f: config = yaml.safe_load(f) memcache.set("config", config)
def sub(topic: str, subscriber: Callable) -> None: """ Subscribes a listener method to a certain topic. :param topic: The topic ti subscribe to :param subscriber: The subscriber method :return: None """ topics = memcache.get("pubsub.topics") if topics.get(topic) is not None: topics[topic].append(subscriber) else: topics[topic] = [subscriber] memcache.set("pubsub.topics", topics)
def init_voting(): memcache.set("voting.count", 0) memcache.set("voting.users", set({})) memcache.set("voting.required", 0) sub("required_votes", __set_required_votes) sub("vote", vote)
def __discover_plugins(): plugin_dir = os.path.join(os.path.dirname(__file__), 'plugins') include_paths = [plugin_dir] plugins = dict({}) with open(os.path.join(plugin_dir, 'include.txt')) as f: contents = f.read() if contents is not None: contents = contents.split("\n") include_paths.extend([path for path in contents if path != ""]) for plugin_path in include_paths: try: for filename in os.listdir(plugin_path): absolute_path = os.path.join(plugin_path, filename) name, ext = os.path.splitext(filename) if ext != '.py': continue try: module = __load_plugin(name, absolute_path) except: continue if __is_plugin(module): plugins[module.__name__] = { 'display_name': module.name, 'path': absolute_path, 'description': module.description, 'arguments': module.arguments } except: continue memcache.set("upload.plugins", plugins)
def activity(user_token: str) -> None: """ » Subscribed to user_activity Refreshes the last_seen attribute of the user with the given user_token. Also invalidates the user's session if the ttl has expired. :param user_token: The user token of the active user :return: None """ active_users = memcache.get("user_cache.active_users") record = active_users.get(user_token) if record is None: return if time.time() - record['last_seen'] > record['ttl']: del active_users[user_token] memcache.set("user_cache.active_users", active_users) return active_users[user_token]['last_seen'] = time.time() memcache.set("user_cache.active_users", active_users)
def authorize(user_token: str, required_privilege: int) -> bool: """ Used to check whether a user is permitted to perform a certain action. :param user_token: The user token of the user who wants to perform the action :param required_privilege: The required privilege level to perform the action :return: Whether the user is permitted to perform the action """ if required_privilege < 1: return True record = memcache.get("user_cache.active_users").get(user_token) if record is None: return False if time.time() - record['last_seen'] > record['ttl']: active_users = memcache.get("user_cache.active_users") del active_users[user_token] memcache.set("user_cache.active_users", active_users) return False return record['privilege_level'] >= required_privilege
def vote(user_token: bytes): users = memcache.get("voting.users") if user_token not in users: users.add(user_token) memcache.set("voting.users", users) memcache.incr("voting.count") if memcache.get("voting.count") >= memcache.get("voting.required"): pub("vote_passed") memcache.set("voting.count", 0) memcache.set("voting.users", set({}))
def __set_required_votes(n: int) -> None: memcache.set("voting.required", n)
if app.debug: CORS(app) with app.app_context(): if memcache.get("pynitus.initialized") is None: init_config() init_pubsub() init_db() init_user_cache() init_player() init_queue() init_contributor_queue() init_voting() init_storage() init_upload() memcache.set("pynitus.initialized", True) @app.teardown_appcontext def shutdown_session(exception=None): # TODO: log exception db_session.remove() @app.before_request def refresh_user_session(): user_token = request.args.get('token') user_token = user_token if user_token is not None else request.remote_addr g.user_token = user_token pub('user_activity', user_token)