# -*- coding: utf-8 -*-

# Copyright 2018 Whitestack, LLC
# Copyright 2018 Telefonica S.A.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# For those usages not covered by the Apache License, Version 2.0 please
# contact: esousa@whitestack.com or alfonso.tiernosepulveda@telefonica.com
##


"""
Authenticator is responsible for authenticating the users,
create the tokens unscoped and scoped, retrieve the role
list inside the projects that they are inserted
"""

__author__ = "Eduardo Sousa <esousa@whitestack.com>; Alfonso Tierno <alfonso.tiernosepulveda@telefonica.com>"
__date__ = "$27-jul-2018 23:59:59$"

import cherrypy
import logging
import yaml
from base64 import standard_b64decode
from copy import deepcopy

# from functools import reduce
from http import HTTPStatus
from time import time
from os import path

from osm_nbi.authconn import AuthException, AuthconnException, AuthExceptionUnauthorized
from osm_nbi.authconn_keystone import AuthconnKeystone
from osm_nbi.authconn_internal import AuthconnInternal
from osm_nbi.authconn_tacacs import AuthconnTacacs
from osm_common import dbmemory, dbmongo, msglocal, msgkafka
from osm_common.dbbase import DbException
from osm_nbi.validation import is_valid_uuid
from itertools import chain
from uuid import uuid4


class Authenticator:
    """
    This class should hold all the mechanisms for User Authentication and
    Authorization. Initially it should support Openstack Keystone as a
    backend through a plugin model where more backends can be added and a
    RBAC model to manage permissions on operations.
    This class must be threading safe
    """

    periodin_db_pruning = (
        60 * 30
    )  # for the internal backend only. every 30 minutes expired tokens will be pruned
    token_limit = 500  # when reached, the token cache will be cleared

    def __init__(self, valid_methods, valid_query_string):
        """
        Authenticator initializer. Setup the initial state of the object,
        while it waits for the config dictionary and database initialization.
        """
        self.backend = None
        self.config = None
        self.db = None
        self.msg = None
        self.tokens_cache = dict()
        self.next_db_prune_time = (
            0  # time when next cleaning of expired tokens must be done
        )
        self.roles_to_operations_file = None
        # self.roles_to_operations_table = None
        self.resources_to_operations_mapping = {}
        self.operation_to_allowed_roles = {}
        self.logger = logging.getLogger("nbi.authenticator")
        self.role_permissions = []
        self.valid_methods = valid_methods
        self.valid_query_string = valid_query_string
        self.system_admin_role_id = None  # system_role id
        self.test_project_id = None  # test_project_id

    def start(self, config):
        """
        Method to configure the Authenticator object. This method should be called
        after object creation. It is responsible by initializing the selected backend,
        as well as the initialization of the database connection.

        :param config: dictionary containing the relevant parameters for this object.
        """
        self.config = config

        try:
            if not self.db:
                if config["database"]["driver"] == "mongo":
                    self.db = dbmongo.DbMongo()
                    self.db.db_connect(config["database"])
                elif config["database"]["driver"] == "memory":
                    self.db = dbmemory.DbMemory()
                    self.db.db_connect(config["database"])
                else:
                    raise AuthException(
                        "Invalid configuration param '{}' at '[database]':'driver'".format(
                            config["database"]["driver"]
                        )
                    )
            if not self.msg:
                if config["message"]["driver"] == "local":
                    self.msg = msglocal.MsgLocal()
                    self.msg.connect(config["message"])
                elif config["message"]["driver"] == "kafka":
                    self.msg = msgkafka.MsgKafka()
                    self.msg.connect(config["message"])
                else:
                    raise AuthException(
                        "Invalid configuration param '{}' at '[message]':'driver'".format(
                            config["message"]["driver"]
                        )
                    )
            if not self.backend:
                if config["authentication"]["backend"] == "keystone":
                    self.backend = AuthconnKeystone(
                        self.config["authentication"], self.db, self.role_permissions
                    )
                elif config["authentication"]["backend"] == "internal":
                    self.backend = AuthconnInternal(
                        self.config["authentication"], self.db, self.role_permissions
                    )
                    self._internal_tokens_prune("tokens")
                elif config["authentication"]["backend"] == "tacacs":
                    self.backend = AuthconnTacacs(
                        self.config["authentication"], self.db, self.role_permissions
                    )
                    self._internal_tokens_prune("tokens_tacacs")
                else:
                    raise AuthException(
                        "Unknown authentication backend: {}".format(
                            config["authentication"]["backend"]
                        )
                    )

            if not self.roles_to_operations_file:
                if "roles_to_operations" in config["rbac"]:
                    self.roles_to_operations_file = config["rbac"][
                        "roles_to_operations"
                    ]
                else:
                    possible_paths = (
                        __file__[: __file__.rfind("auth.py")]
                        + "roles_to_operations.yml",
                        "./roles_to_operations.yml",
                    )
                    for config_file in possible_paths:
                        if path.isfile(config_file):
                            self.roles_to_operations_file = config_file
                            break
                if not self.roles_to_operations_file:
                    raise AuthException(
                        "Invalid permission configuration: roles_to_operations file missing"
                    )

            # load role_permissions
            def load_role_permissions(method_dict):
                for k in method_dict:
                    if k == "ROLE_PERMISSION":
                        for method in chain(
                            method_dict.get("METHODS", ()), method_dict.get("TODO", ())
                        ):
                            permission = method_dict["ROLE_PERMISSION"] + method.lower()
                            if permission not in self.role_permissions:
                                self.role_permissions.append(permission)
                    elif k in ("TODO", "METHODS"):
                        continue
                    elif method_dict[k]:
                        load_role_permissions(method_dict[k])

            load_role_permissions(self.valid_methods)
            for query_string in self.valid_query_string:
                for method in ("get", "put", "patch", "post", "delete"):
                    permission = query_string.lower() + ":" + method
                    if permission not in self.role_permissions:
                        self.role_permissions.append(permission)

            # get ids of role system_admin and test project
            role_system_admin = self.db.get_one(
                "roles", {"name": "system_admin"}, fail_on_empty=False
            )
            if role_system_admin:
                self.system_admin_role_id = role_system_admin["_id"]
            test_project_name = self.config["authentication"].get(
                "project_not_authorized", "admin"
            )
            test_project = self.db.get_one(
                "projects", {"name": test_project_name}, fail_on_empty=False
            )
            if test_project:
                self.test_project_id = test_project["_id"]

        except Exception as e:
            raise AuthException(str(e))

    def stop(self):
        try:
            if self.db:
                self.db.db_disconnect()
        except DbException as e:
            raise AuthException(str(e), http_code=e.http_code)

    def create_admin_project(self):
        """
        Creates a new project 'admin' into database if it doesn't exist. Useful for initialization.
        :return: _id identity of the 'admin' project
        """

        # projects = self.db.get_one("projects", fail_on_empty=False, fail_on_more=False)
        project_desc = {"name": "admin"}
        projects = self.backend.get_project_list(project_desc)
        if projects:
            return projects[0]["_id"]
        now = time()
        project_desc["_id"] = str(uuid4())
        project_desc["_admin"] = {"created": now, "modified": now}
        pid = self.backend.create_project(project_desc)
        self.logger.info(
            "Project '{}' created at database".format(project_desc["name"])
        )
        return pid

    def create_admin_user(self, project_id):
        """
        Creates a new user admin/admin into database if database is empty. Useful for initialization
        :return: _id identity of the inserted data, or None
        """
        # users = self.db.get_one("users", fail_on_empty=False, fail_on_more=False)
        users = self.backend.get_user_list()
        if users:
            return None
        # user_desc = {"username": "admin", "password": "admin", "projects": [project_id]}
        now = time()
        user_desc = {
            "username": "admin",
            "password": "admin",
            "_admin": {"created": now, "modified": now},
        }
        if project_id:
            pid = project_id
        else:
            # proj = self.db.get_one("projects", {"name": "admin"}, fail_on_empty=False, fail_on_more=False)
            proj = self.backend.get_project_list({"name": "admin"})
            pid = proj[0]["_id"] if proj else None
        # role = self.db.get_one("roles", {"name": "system_admin"}, fail_on_empty=False, fail_on_more=False)
        roles = self.backend.get_role_list({"name": "system_admin"})
        if pid and roles:
            user_desc["project_role_mappings"] = [
                {"project": pid, "role": roles[0]["_id"]}
            ]
        uid = self.backend.create_user(user_desc)
        self.logger.info("User '{}' created at database".format(user_desc["username"]))
        return uid

    def init_db(self, target_version="1.0"):
        """
        Check if the database has been initialized, with at least one user. If not, create the required tables
        and insert the predefined mappings between roles and permissions.

        :param target_version: schema version that should be present in the database.
        :return: None if OK, exception if error or version is different.
        """

        records = self.backend.get_role_list()

        # Loading permissions to AUTH. At lease system_admin must be present.
        if not records or not next(
            (r for r in records if r["name"] == "system_admin"), None
        ):
            with open(self.roles_to_operations_file, "r") as stream:
                roles_to_operations_yaml = yaml.load(stream, Loader=yaml.Loader)

            role_names = []
            for role_with_operations in roles_to_operations_yaml["roles"]:
                # Verifying if role already exists. If it does, raise exception
                if role_with_operations["name"] not in role_names:
                    role_names.append(role_with_operations["name"])
                else:
                    raise AuthException(
                        "Duplicated role name '{}' at file '{}''".format(
                            role_with_operations["name"], self.roles_to_operations_file
                        )
                    )

                if not role_with_operations["permissions"]:
                    continue

                for permission, is_allowed in role_with_operations[
                    "permissions"
                ].items():
                    if not isinstance(is_allowed, bool):
                        raise AuthException(
                            "Invalid value for permission '{}' at role '{}'; at file '{}'".format(
                                permission,
                                role_with_operations["name"],
                                self.roles_to_operations_file,
                            )
                        )

                    # TODO check permission is ok
                    if permission[-1] == ":":
                        raise AuthException(
                            "Invalid permission '{}' terminated in ':' for role '{}'; at file {}".format(
                                permission,
                                role_with_operations["name"],
                                self.roles_to_operations_file,
                            )
                        )

                if "default" not in role_with_operations["permissions"]:
                    role_with_operations["permissions"]["default"] = False
                if "admin" not in role_with_operations["permissions"]:
                    role_with_operations["permissions"]["admin"] = False

                now = time()
                role_with_operations["_admin"] = {
                    "created": now,
                    "modified": now,
                }

                # self.db.create(self.roles_to_operations_table, role_with_operations)
                try:
                    self.backend.create_role(role_with_operations)
                    self.logger.info(
                        "Role '{}' created".format(role_with_operations["name"])
                    )
                except (AuthException, AuthconnException) as e:
                    if role_with_operations["name"] == "system_admin":
                        raise
                    self.logger.error(
                        "Role '{}' cannot be created: {}".format(
                            role_with_operations["name"], e
                        )
                    )

        # Create admin project&user if required
        pid = self.create_admin_project()
        user_id = self.create_admin_user(pid)

        # try to assign system_admin role to user admin if not any user has this role
        if not user_id:
            try:
                users = self.backend.get_user_list()
                roles = self.backend.get_role_list({"name": "system_admin"})
                role_id = roles[0]["_id"]
                user_with_system_admin = False
                user_admin_id = None
                for user in users:
                    if not user_admin_id:
                        user_admin_id = user["_id"]
                    if user["username"] == "admin":
                        user_admin_id = user["_id"]
                    for prm in user.get("project_role_mappings", ()):
                        if prm["role"] == role_id:
                            user_with_system_admin = True
                            break
                    if user_with_system_admin:
                        break
                if not user_with_system_admin:
                    self.backend.update_user(
                        {
                            "_id": user_admin_id,
                            "add_project_role_mappings": [
                                {"project": pid, "role": role_id}
                            ],
                        }
                    )
                    self.logger.info(
                        "Added role system admin to user='{}' project=admin".format(
                            user_admin_id
                        )
                    )
            except Exception as e:
                self.logger.error(
                    "Error in Authorization DataBase initialization: {}: {}".format(
                        type(e).__name__, e
                    )
                )

        self.load_operation_to_allowed_roles()

    def load_operation_to_allowed_roles(self):
        """
        Fills the internal self.operation_to_allowed_roles based on database role content and self.role_permissions
        It works in a shadow copy and replace at the end to allow other threads working with the old copy
        :return: None
        """
        permissions = {oper: [] for oper in self.role_permissions}
        # records = self.db.get_list(self.roles_to_operations_table)
        records = self.backend.get_role_list()

        ignore_fields = ["_id", "_admin", "name", "default"]
        for record in records:
            if not record.get("permissions"):
                continue
            record_permissions = {
                oper: record["permissions"].get("default", False)
                for oper in self.role_permissions
            }
            operations_joined = [
                (oper, value)
                for oper, value in record["permissions"].items()
                if oper not in ignore_fields
            ]
            operations_joined.sort(key=lambda x: x[0].count(":"))

            for oper in operations_joined:
                match = list(
                    filter(lambda x: x.find(oper[0]) == 0, record_permissions.keys())
                )

                for m in match:
                    record_permissions[m] = oper[1]

            allowed_operations = [k for k, v in record_permissions.items() if v is True]

            for allowed_op in allowed_operations:
                permissions[allowed_op].append(record["name"])

        self.operation_to_allowed_roles = permissions

    def authorize(
        self, role_permission=None, query_string_operations=None, item_id=None
    ):
        token = None
        user_passwd64 = None
        try:
            # 1. Get token Authorization bearer
            auth = cherrypy.request.headers.get("Authorization")
            if auth:
                auth_list = auth.split(" ")
                if auth_list[0].lower() == "bearer":
                    token = auth_list[-1]
                elif auth_list[0].lower() == "basic":
                    user_passwd64 = auth_list[-1]
            if not token:
                if cherrypy.session.get("Authorization"):
                    # 2. Try using session before request a new token. If not, basic authentication will generate
                    token = cherrypy.session.get("Authorization")
                    if token == "logout":
                        token = None  # force Unauthorized response to insert user password again
                elif user_passwd64 and cherrypy.request.config.get(
                    "auth.allow_basic_authentication"
                ):
                    # 3. Get new token from user password
                    user = None
                    passwd = None
                    try:
                        user_passwd = standard_b64decode(user_passwd64).decode()
                        user, _, passwd = user_passwd.partition(":")
                    except Exception:
                        pass
                    outdata = self.new_token(
                        None, {"username": user, "password": passwd}
                    )
                    token = outdata["_id"]
                    cherrypy.session["Authorization"] = token

            if not token:
                raise AuthException(
                    "Needed a token or Authorization http header",
                    http_code=HTTPStatus.UNAUTHORIZED,
                )

            # try to get from cache first
            now = time()
            token_info = self.tokens_cache.get(token)
            if token_info and token_info["expires"] < now:
                # delete token. MUST be done with care, as another thread maybe already delete it. Do not use del
                self.tokens_cache.pop(token, None)
                token_info = None

            # get from database if not in cache
            if not token_info:
                token_info = self.backend.validate_token(token)
                # Clear cache if token limit reached
                if len(self.tokens_cache) > self.token_limit:
                    self.tokens_cache.clear()
                self.tokens_cache[token] = token_info
            # TODO add to token info remote host, port

            if role_permission:
                RBAC_auth = self.check_permissions(
                    token_info,
                    cherrypy.request.method,
                    role_permission,
                    query_string_operations,
                    item_id,
                )
                self.logger.info("RBAC_auth: {}".format(RBAC_auth))
                token_info["allow_show_user_project_role"] = RBAC_auth

            return token_info
        except AuthException as e:
            if not isinstance(e, AuthExceptionUnauthorized):
                if cherrypy.session.get("Authorization"):
                    del cherrypy.session["Authorization"]
                cherrypy.response.headers[
                    "WWW-Authenticate"
                ] = 'Bearer realm="{}"'.format(e)
            if self.config["authentication"].get("user_not_authorized"):
                return {
                    "id": "testing-token",
                    "_id": "testing-token",
                    "project_id": self.test_project_id,
                    "username": self.config["authentication"]["user_not_authorized"],
                    "roles": [self.system_admin_role_id],
                    "admin": True,
                    "allow_show_user_project_role": True,
                }
            raise

    def new_token(self, token_info, indata, remote):
        new_token_info = self.backend.authenticate(
            credentials=indata,
            token_info=token_info,
        )

        new_token_info["remote_port"] = remote.port
        if not new_token_info.get("expires"):
            new_token_info["expires"] = time() + 3600
        if not new_token_info.get("admin"):
            new_token_info["admin"] = (
                True if new_token_info.get("project_name") == "admin" else False
            )
            # TODO put admin in RBAC

        if remote.name:
            new_token_info["remote_host"] = remote.name
        elif remote.ip:
            new_token_info["remote_host"] = remote.ip

        # TODO call self._internal_tokens_prune(now) ?
        return deepcopy(new_token_info)

    def get_token_list(self, token_info):
        if self.config["authentication"]["backend"] == "internal":
            return self._internal_get_token_list(token_info)
        else:
            # TODO: check if this can be avoided. Backend may provide enough information
            return [
                deepcopy(token)
                for token in self.tokens_cache.values()
                if token["username"] == token_info["username"]
            ]

    def get_token(self, token_info, token):
        if self.config["authentication"]["backend"] == "internal":
            return self._internal_get_token(token_info, token)
        else:
            # TODO: check if this can be avoided. Backend may provide enough information
            token_value = self.tokens_cache.get(token)
            if not token_value:
                raise AuthException("token not found", http_code=HTTPStatus.NOT_FOUND)
            if (
                token_value["username"] != token_info["username"]
                and not token_info["admin"]
            ):
                raise AuthException(
                    "needed admin privileges", http_code=HTTPStatus.UNAUTHORIZED
                )
            return token_value

    def del_token(self, token):
        try:
            self.backend.revoke_token(token)
            # self.tokens_cache.pop(token, None)
            self.remove_token_from_cache(token)
            return "token '{}' deleted".format(token)
        except KeyError:
            raise AuthException(
                "Token '{}' not found".format(token), http_code=HTTPStatus.NOT_FOUND
            )

    def check_permissions(
        self,
        token_info,
        method,
        role_permission=None,
        query_string_operations=None,
        item_id=None,
    ):
        """
        Checks that operation has permissions to be done, base on the assigned roles to this user project
        :param token_info: Dictionary that contains "roles" with a list of assigned roles.
            This method fills the token_info["admin"] with True or False based on assigned tokens, if any allows admin
            This will be used among others to hide or not the _admin content of topics
        :param method: GET,PUT, POST, ...
        :param role_permission: role permission name of the operation required
        :param query_string_operations: list of possible admin query strings provided by user. It is checked that the
            assigned role allows this query string for this method
        :param item_id: item identifier if included in the URL, None otherwise
        :return: True if access granted by permission rules, False if access granted by default rules (Bug 853)
        :raises: AuthExceptionUnauthorized if access denied
        """
        self.load_operation_to_allowed_roles()

        roles_required = self.operation_to_allowed_roles[role_permission]
        roles_allowed = [role["name"] for role in token_info["roles"]]

        # fills token_info["admin"] if some roles allows it
        token_info["admin"] = False
        for role in roles_allowed:
            if role in self.operation_to_allowed_roles["admin:" + method.lower()]:
                token_info["admin"] = True
                break

        if "anonymous" in roles_required:
            return True
        operation_allowed = False
        for role in roles_allowed:
            if role in roles_required:
                operation_allowed = True
                # if query_string operations, check if this role allows it
                if not query_string_operations:
                    return True
                for query_string_operation in query_string_operations:
                    if (
                        role
                        not in self.operation_to_allowed_roles[query_string_operation]
                    ):
                        break
                else:
                    return True

        # Bug 853 - Final Solution
        # User/Project/Role whole listings are filtered elsewhere
        # uid, pid, rid = ("user_id", "project_id", "id") if is_valid_uuid(id) else ("username", "project_name", "name")
        uid = "user_id" if is_valid_uuid(item_id) else "username"
        if (
            role_permission
            in [
                "projects:get",
                "projects:id:get",
                "roles:get",
                "roles:id:get",
                "users:get",
            ]
        ) or (role_permission == "users:id:get" and item_id == token_info[uid]):
            # or (role_permission == "projects:id:get" and item_id == token_info[pid]) \
            # or (role_permission == "roles:id:get" and item_id in [role[rid] for role in token_info["roles"]]):
            return False

        if not operation_allowed:
            raise AuthExceptionUnauthorized("Access denied: lack of permissions.")
        else:
            raise AuthExceptionUnauthorized(
                "Access denied: You have not permissions to use these admin query string"
            )

    def get_user_list(self):
        return self.backend.get_user_list()

    def _normalize_url(self, url, method):
        # DEPRECATED !!!
        # Removing query strings
        normalized_url = url if "?" not in url else url[: url.find("?")]
        normalized_url_splitted = normalized_url.split("/")
        parameters = {}

        filtered_keys = [
            key
            for key in self.resources_to_operations_mapping.keys()
            if method in key.split()[0]
        ]

        for idx, path_part in enumerate(normalized_url_splitted):
            tmp_keys = []
            for tmp_key in filtered_keys:
                splitted = tmp_key.split()[1].split("/")
                if idx >= len(splitted):
                    continue
                elif "<" in splitted[idx] and ">" in splitted[idx]:
                    if splitted[idx] == "<artifactPath>":
                        tmp_keys.append(tmp_key)
                        continue
                    elif idx == len(normalized_url_splitted) - 1 and len(
                        normalized_url_splitted
                    ) != len(splitted):
                        continue
                    else:
                        tmp_keys.append(tmp_key)
                elif splitted[idx] == path_part:
                    if idx == len(normalized_url_splitted) - 1 and len(
                        normalized_url_splitted
                    ) != len(splitted):
                        continue
                    else:
                        tmp_keys.append(tmp_key)
            filtered_keys = tmp_keys
            if (
                len(filtered_keys) == 1
                and filtered_keys[0].split("/")[-1] == "<artifactPath>"
            ):
                break

        if len(filtered_keys) == 0:
            raise AuthException(
                "Cannot make an authorization decision. URL not found. URL: {0}".format(
                    url
                )
            )
        elif len(filtered_keys) > 1:
            raise AuthException(
                "Cannot make an authorization decision. Multiple URLs found. URL: {0}".format(
                    url
                )
            )

        filtered_key = filtered_keys[0]

        for idx, path_part in enumerate(filtered_key.split()[1].split("/")):
            if "<" in path_part and ">" in path_part:
                if path_part == "<artifactPath>":
                    parameters[path_part[1:-1]] = "/".join(
                        normalized_url_splitted[idx:]
                    )
                else:
                    parameters[path_part[1:-1]] = normalized_url_splitted[idx]

        return filtered_key, parameters

    def _internal_get_token_list(self, token_info):
        now = time()
        token_list = self.db.get_list(
            "tokens", {"username": token_info["username"], "expires.gt": now}
        )
        return token_list

    def _internal_get_token(self, token_info, token_id):
        token_value = self.db.get_one("tokens", {"_id": token_id}, fail_on_empty=False)
        if not token_value:
            raise AuthException("token not found", http_code=HTTPStatus.NOT_FOUND)
        if (
            token_value["username"] != token_info["username"]
            and not token_info["admin"]
        ):
            raise AuthException(
                "needed admin privileges", http_code=HTTPStatus.UNAUTHORIZED
            )
        return token_value

    def _internal_tokens_prune(self, token_collection, now=None):
        now = now or time()
        if not self.next_db_prune_time or self.next_db_prune_time >= now:
            self.db.del_list(token_collection, {"expires.lt": now})
            self.next_db_prune_time = self.periodin_db_pruning + now
            # self.tokens_cache.clear()  # not required any more

    def remove_token_from_cache(self, token=None):
        if token:
            self.tokens_cache.pop(token, None)
        else:
            self.tokens_cache.clear()
        self.msg.write("admin", "revoke_token", {"_id": token} if token else None)

    def check_password_expiry(self, outdata):
        """
        This method will check for password expiry of the user
        :param outdata: user token information
        """
        user_content = None
        detail = {}
        present_time = time()
        user = outdata["username"]
        if self.config["authentication"].get("pwd_expiry_check"):
            user_content = self.db.get_list("users", {"username": user})[0]
            if not user_content.get("username") == "admin":
                user_content["_admin"]["modified_time"] = present_time
                if user_content.get("_admin").get("expire_time"):
                    expire_time = user_content["_admin"]["expire_time"]
                else:
                    expire_time = present_time
                uid = user_content["_id"]
                self.db.set_one("users", {"_id": uid}, user_content)
                if not present_time < expire_time:
                    return True
        else:
            pass
