Example #1
0
def add_fake_yd_tokens(count: int) -> None:
    """
    Adds fake Yandex.Disk tokens in DB.
    """
    free_users_count = UserQuery.get_users_without_yd_token_count()

    if (count > free_users_count):
        raise ValueError(
            f"Number of tokens ({count}) can't be greater than "
            f"number of free users ({free_users_count})"
        )

    i = 0

    while (i != count):
        free_user = UserQuery.get_random_user_without_yd_token()
        result = YandexDiskToken.create_fake(free_user)
        token = result["value"]

        db.session.add(token)
        db.session.commit()

        i += 1

    click.echo(f"Done ({count})")
    def wrapper(*args, **kwargs):
        tg_user = g.telegram_user
        tg_chat = g.telegram_chat

        # TODO: check if user came from different chat,
        # then also register that chat in db.
        if (UserQuery.exists(tg_user.id)):
            return func(*args, **kwargs)

        new_user = User(telegram_id=tg_user.id,
                        is_bot=tg_user.is_bot,
                        language=SupportedLanguage.get(tg_user.language_code))
        Chat(telegram_id=tg_chat.id,
             type=ChatType.get(tg_chat.type),
             user=new_user)

        db.session.add(new_user)

        try:
            db.session.commit()
        except Exception as e:
            print(e)
            return cancel_command(tg_chat.id)

        return func(*args, **kwargs)
Example #3
0
def add_fake_chats(count: int) -> None:
    """
    Adds fake chats in DB.
    """
    i = 0
    error_count = 0

    while (i != count):
        if (error_count >= 5):
            raise PossibleInfiniteLoopError(
                "Too many errors in a row"
            )

        chat = Chat.create_fake(None)
        user = UserQuery.get_random_user()

        if (user is None):
            raise InvalidTableDataError(
                "Random user is none. Users table is empty?"
            )

        chat.user = user
        db.session.add(chat)

        try:
            db.session.commit()
            i += 1
            error_count = 0
        except IntegrityError:
            # error because of same `telegram_id`
            error_count += 1

    click.echo(f"Done ({count})")
Example #4
0
def clear_users() -> None:
    """
    Removes all users from a table.
    """
    count = UserQuery.delete_all_users()
    db.session.commit()

    click.echo(f"Done ({count})")
    def wrapper(*args, **kwargs):
        user = UserQuery.get_user_by_telegram_id(g.telegram_user.id)

        # TODO: check if token is expired
        if ((user is None) or (user.yandex_disk_token is None)
                or (not user.yandex_disk_token.have_access_token())):
            return g.direct_dispatch(CommandName.YD_AUTH)()

        return func(*args, **kwargs)
Example #6
0
    def get_user(self, user_id: int, insert_token: str) -> User:
        """
        :param user_id:
        DB id of needed user.
        :param insert_token:
        User will be returned only in case when provided
        insert token matchs with one from DB. This means
        you are allowed to modify this DB user.
        Insert token of that user can be modified in futher by
        some another operation, so, you should call this function
        once and reuse returned result.

        :returns:
        DB user.

        :raises:
        `MissingData`, `ExpiredInsertToken`, `InvalidInsertToken`.
        """
        user = UserQuery.get_user_by_id(user_id)

        if (user is None or
                # for some reason `yandex_disk_token` not created,
                # it is not intended behavior.
                user.yandex_disk_token is None):
            raise MissingData()

        db_insert_token = None

        try:
            db_insert_token = user.yandex_disk_token.get_insert_token()
        except Exception:
            raise ExpiredInsertToken()

        if (insert_token != db_insert_token):
            raise InvalidInsertToken()

        return user
Example #7
0
def get_db_user():
    """
    - `insert_token` will be checked. If it is not valid,
    an error will be thrown. You shouldn't clear any tokens
    in case of error, because provided tokens is not known
    to attacker (potential).
    - you shouldn't try to avoid checking logic! It is really
    unsafe to access DB user without `insert_token`.

    :returns: User from DB based on incoming `state` from request.
    This user have `yandex_disk_token` property which is
    not `None`.

    :raises InvalidCredentials: If `state` have invalid
    data or user not found in DB.
    :raises LinkExpired: Requested link is expired and
    not valid anymore.
    :raises InvalidInsertToken: Provided `insert_token`
    is not valid.
    """
    base64_state = request.args["state"]
    encoded_state = None
    decoded_state = None

    try:
        encoded_state = base64.urlsafe_b64decode(
            base64_state.encode()
        ).decode()
    except Exception:
        raise InvalidCredentials()

    try:
        decoded_state = jwt.decode(
            encoded_state,
            current_app.secret_key.encode(),
            algorithm="HS256"
        )
    except Exception:
        raise InvalidCredentials()

    incoming_user_id = decoded_state.get("user_id")
    incoming_insert_token = decoded_state.get("insert_token")

    if (
        incoming_user_id is None or
        incoming_insert_token is None
    ):
        raise InvalidCredentials()

    db_user = UserQuery.get_user_by_id(int(incoming_user_id))

    if (
        db_user is None or
        # for some reason `yandex_disk_token` not created,
        # it is not intended behavior.
        db_user.yandex_disk_token is None
    ):
        raise InvalidCredentials()

    db_insert_token = None

    try:
        db_insert_token = db_user.yandex_disk_token.get_insert_token()
    except Exception:
        raise LinkExpired()

    if (incoming_insert_token != db_insert_token):
        raise InvalidInsertToken()

    return db_user
    def wrapper(*args, **kwargs):
        g.db_user = UserQuery.get_user_by_telegram_id(g.telegram_user.id)
        g.db_chat = ChatQuery.get_chat_by_telegram_id(g.telegram_chat.id)
        g.db_private_chat = ChatQuery.get_private_chat(g.db_user.id)

        return func(*args, **kwargs)