Пример #1
0
def test_should_get_timestamp():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)

    token = "1jJDJOEeG2FutA8g7NAOHK4Mh5RIE8jtbXd63uYbrFDSR06dtQl9o2gZYhBa36nZHXVfiGFz"

    assert branca.timestamp(token) == 123206400
Пример #2
0
def test_should_throw_with_wrong_key():
    key = unhexlify(
        "77726f6e677365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)
    token = "870S4BYxgHw0KnP3W9fgVUHEhT5g86vJ17etaC5Kh5uIraWHCI1psNQGv298ZmjPwoYbjDQ9chy2z"

    with pytest.raises(RuntimeError):
        branca.decode(token)
Пример #3
0
def test_should_allow_hex_string_key():
    branca = Branca(
        key="73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")

    token = "875GH23U0Dr6nHFA63DhOyd9LkYudBkX8RsCTOMz5xoYAMw9sMd5QwcEqLDRnTDHPenOX7nP2trlT"

    assert branca.decode(token) == b"Hello world!"
    assert branca.timestamp(token) == 123206400
Пример #4
0
def test_decode_hello_world_with_zero_timestamp():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)
    token = "870S4BYxgHw0KnP3W9fgVUHEhT5g86vJ17etaC5Kh5uIraWHCI1psNQGv298ZmjPwoYbjDQ9chy2z"

    assert branca.decode(token) == b"Hello world!"
    assert branca.timestamp(token) == 0
Пример #5
0
def test_decode_hello_world_with_max_timestamp():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)
    token = "89i7YCwu5tWAJNHUDdmIqhzOi5hVHOd4afjZcGMcVmM4enl4yeLiDyYv41eMkNmTX6IwYEFErCSqr"

    assert branca.decode(token) == b"Hello world!"
    assert branca.timestamp(token) == 4294967295
Пример #6
0
def test_decode_empty_payload():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)

    token = "4sfD0vPFhIif8cy4nB3BQkHeJqkOkDvinI4zIhMjYX4YXZU5WIq9ycCVjGzB5"

    assert branca.decode(token) == b""
    assert branca.timestamp(token) == 0
Пример #7
0
def test_decode_eight_nul_bytes_with_zero_timestamp():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)

    token = "1jIBheHbDdkCDFQmtgw4RUZeQoOJgGwTFJSpwOAk3XYpJJr52DEpILLmmwYl4tjdSbbNqcF1"

    assert branca.decode(token) == b"\x00\x00\x00\x00\x00\x00\x00\x00"
    assert branca.timestamp(token) == 0
Пример #8
0
def test_decode_eight_nul_bytes_with_nov27_timestamp():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)

    token = "1jJDJOEjuwVb9Csz1Ypw1KBWSkr0YDpeBeJN6NzJWx1VgPLmcBhu2SbkpQ9JjZ3nfUf7Aytp"

    assert branca.decode(token) == b"\x00\x00\x00\x00\x00\x00\x00\x00"
    assert branca.timestamp(token) == 123206400
Пример #9
0
def test_decode_hello_world_with_nov27_timestamp():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)

    token = "875GH23U0Dr6nHFA63DhOyd9LkYudBkX8RsCTOMz5xoYAMw9sMd5QwcEqLDRnTDHPenOX7nP2trlT"

    assert branca.decode(token) == b"Hello world!"
    assert branca.timestamp(token) == 123206400
Пример #10
0
def test_should_throw_with_modified_tag():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)

    token = "875GH23U0Dr6nHFA63DhOyd9LkYudBkX8RsCTOMz5xoYAMw9sMd5QwcEqLDRnTDHPenOX7nP2trk0"

    with pytest.raises(RuntimeError):
        branca.decode(token)
Пример #11
0
def test_should_throw_with_modified_ciphertext():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)

    token = "875GH23U0Dr6nHFA63DhOyd9LkYudBkX8RsCTOMz5xoYAMw9sMd5Qw6Jpo96myliI3hHD7VbKZBYh"

    with pytest.raises(RuntimeError):
        branca.decode(token)
Пример #12
0
def test_should_throw_with_modified_timestamp():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)

    token = "870g1RCk4lW1YInhaU3TP8u2hGtfol16ettLcTOSoA0JIpjCaQRW7tQeP6dQmTvFIB2s6wL5deMXr"

    with pytest.raises(RuntimeError):
        branca.decode(token)
Пример #13
0
def test_should_throw_with_modified_nonce():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)

    token = "875GH233SUysT7fQ711EWd9BXpwOjB72ng3ZLnjWFrmOqVy49Bv93b78JU5331LbcY0EEzhLfpmSx"

    with pytest.raises(RuntimeError):
        branca.decode(token)
Пример #14
0
def test_should_throw_with_modified_version():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)

    token = "89mvl3S0BE0UCMIY94xxIux4eg1w5oXrhvCEXrDAjusSbO0Yk7AU6FjjTnbTWTqogLfNPJLzecHVb"

    with pytest.raises(RuntimeError):
        branca.decode(token)
Пример #15
0
def test_should_throw_with_wrong_version():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)

    token = "89mvl3RkwXjpEj5WMxK7GUDEHEeeeZtwjMIOogTthvr44qBfYtQSIZH5MHOTC0GzoutDIeoPVZk3w"

    with pytest.raises(RuntimeError):
        branca.decode(token)
Пример #16
0
def test_decode_non_utf8_payload():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)

    token = "K9u6d0zjXp8RXNUGDyXAsB9AtPo60CD3xxQ2ulL8aQoTzXbvockRff0y1eXoHm"

    assert branca.decode(token) == b"\x80"
    assert branca.timestamp(token) == 123206400
Пример #17
0
def test_decode_eight_nul_bytes_with_max_timestamp():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)

    token = "1jrx6DUu5q06oxykef2e2ZMyTcDRTQot9ZnwgifUtzAphGtjsxfbxXNhQyBEOGtpbkBgvIQx"

    assert branca.decode(token) == b"\x00\x00\x00\x00\x00\x00\x00\x00"
    assert branca.timestamp(token) == 4294967295
Пример #18
0
def test_encode_hello_world_with_max_timestamp():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)

    branca._nonce = unhexlify(
        "beefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeef")
    token = branca.encode("Hello world!", timestamp=4294967295)

    assert token == "89i7YCwu5tWAJNHUDdmIqhzOi5hVHOd4afjZcGMcVmM4enl4yeLiDyYv41eMkNmTX6IwYEFErCSqr"
Пример #19
0
def test_encode_hello_world_with_zero_timestamp():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)

    branca._nonce = unhexlify(
        "beefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeef")
    token = branca.encode("Hello world!", timestamp=0)

    assert token == "870S4BYxgHw0KnP3W9fgVUHEhT5g86vJ17etaC5Kh5uIraWHCI1psNQGv298ZmjPwoYbjDQ9chy2z"
Пример #20
0
def other_impl_decode(string: bytes):
    with mock.branca_impl():
        with mock.with_config() as config:
            key = config["manabi"]["key"]
        f = Branca(from_string(key))
        ct = f.encode(string)
        proc = run(["cargo", "run", "decode", key, ct],
                   stdout=PIPE,
                   check=True)
        assert from_string(proc.stdout.decode("UTF-8")) == string
Пример #21
0
def test_encode_eight_nul_bytes_with_zero_timestamp():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)

    branca._nonce = unhexlify(
        "beefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeef")
    token = branca.encode(b"\x00\x00\x00\x00\x00\x00\x00\x00", timestamp=0)

    assert token == "1jIBheHbDdkCDFQmtgw4RUZeQoOJgGwTFJSpwOAk3XYpJJr52DEpILLmmwYl4tjdSbbNqcF1"
Пример #22
0
def test_encode_non_utf8_payload():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)

    branca._nonce = unhexlify(
        "beefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeef")
    token = branca.encode(b"", timestamp=0)

    assert token == "4sfD0vPFhIif8cy4nB3BQkHeJqkOkDvinI4zIhMjYX4YXZU5WIq9ycCVjGzB5"
Пример #23
0
def test_encode_hello_world_with_november_27_timestamp():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)

    branca._nonce = unhexlify(
        "beefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeef")
    token = branca.encode("Hello world!", timestamp=123206400)

    assert token == "875GH23U0Dr6nHFA63DhOyd9LkYudBkX8RsCTOMz5xoYAMw9sMd5QwcEqLDRnTDHPenOX7nP2trlT"
Пример #24
0
def test_encode_eight_nul_bytes_with_november_27_timestamp():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)

    branca._nonce = unhexlify(
        "beefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeef")
    token = branca.encode(b"\x00\x00\x00\x00\x00\x00\x00\x00",
                          timestamp=123206400)

    assert token == "1jJDJOEjuwVb9Csz1Ypw1KBWSkr0YDpeBeJN6NzJWx1VgPLmcBhu2SbkpQ9JjZ3nfUf7Aytp"
Пример #25
0
def test_encode_eight_nul_bytes_with_zero_timestamp():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)

    branca._nonce = unhexlify(
        "beefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeef")
    token = branca.encode(b"\x00\x00\x00\x00\x00\x00\x00\x00",
                          timestamp=4294967295)

    assert token == "1jrx6DUu5q06oxykef2e2ZMyTcDRTQot9ZnwgifUtzAphGtjsxfbxXNhQyBEOGtpbkBgvIQx"
Пример #26
0
 def from_ciphertext(cls, key: Key, ciphertext: str) -> "Token":
     assert ciphertext
     branca = Branca(key.data)
     try:
         timestamp = branca.timestamp(ciphertext)
     except (struct.error, ValueError):
         return cls(key, None, None)
     try:
         token_path = Path(branca.decode(ciphertext).decode("UTF-8"))
     except RuntimeError:
         return cls(key, None, timestamp)
     return cls(key, token_path, timestamp, ciphertext)
Пример #27
0
    def __init__(self, app, secret):
        """Initialize the Api Token manager.

        Parameters
        ----------
        app : aiohttp.web.Application
            The aiohttp application instance
        secret : str
            The secret key used to sign the API tokens (after hashing)
        """
        self.app = app
        self.branca = Branca(key=sha3_256(secret.encode("utf-8")).digest())
        logger.debug("created Branca instance")
Пример #28
0
def test_should_throw_when_expired():
    key = unhexlify(
        "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974")
    branca = Branca(key)

    branca._nonce = unhexlify(
        "0102030405060708090a0b0c0102030405060708090a0b0c")
    token = branca.encode(b"Hello world!", timestamp=123206400)

    with pytest.raises(RuntimeError):
        branca.decode(token, 3600)
Пример #29
0
 def __init__(self, app, secret):
     self.app = app
     self.branca = Branca(key=sha3_256(secret.encode("utf-8")).digest())
     logger.debug("created Branca instance")
Пример #30
0
class ApiTokens:
    def __init__(self, app, secret):
        self.app = app
        self.branca = Branca(key=sha3_256(secret.encode("utf-8")).digest())
        logger.debug("created Branca instance")

    async def generate_token(self, username, token_name=str(uuid4()), permissions="*"):
        if not token_name:
            token_name = str(uuid4())
        logger.debug(
            f"generating a token for {username} with these permissions: {permissions}"
        )
        user = await find_user_by_username(
            self.app, username, ["permissions", "password", "_id"]
        )
        if permissions == "*":
            permissions = list(user.get("permissions", []))
        else:
            permissions = list(
                filter(
                    lambda permission: permission in user.get("permissions", []),
                    permissions,
                )
            )
        packed = msgpack.dumps(
            {"username": username, "permisisons": permissions, "token_name": token_name}
        )
        token = self.branca.encode(packed)
        logger.debug(
            f"successfuly generated a token for {username}: {token}. Adding it to the database"
        )
        await add_token_to_user(self.app, user.get("_id", ""), token_name, token)
        return (
            token,
            token_name,
            permissions,
        )

    async def validate_token(self, token, permissions=[], raise_error=False):
        logger.debug(
            f"validating a token{' for permissions' + permissions if permissions != [] else ''}. Token: {token}"
        )
        user = await find_user_by_token(self.app, token, ["permissions", "username"])
        packed = self.branca.decode(token)
        payload = msgpack.loads(packed, raw=False)
        logger.debug(f"decoded token: {payload}")
        if user == None:
            if raise_error:
                raise HTTPUnauthorized()
            return False
        user_permission_set = set(user.get("permissions", []))
        if not set(payload.get("permissions", [])).issubset(user_permission_set):
            payload["permissions"] = filter(
                lambda permission: permission in user_permission_set,
                payload["permissions"],
            )
        if (
            # check if token has all requested permissions
            not set(permissions).issubset(set(payload.get("permissions", [])))
            # check if user has all requested permissions
            or not set(permissions).issubset(user_permission_set)
        ):
            if raise_error:
                raise HTTPForbidden()
            return False
        logger.debug("Token is valid")
        return True

    async def get_token_info(self, token):
        user = await find_user_by_token(self.app, token, ["permissions", "username"])
        packed = self.branca.decode(token)
        payload = msgpack.loads(packed, raw=False)
        if user == None:
            return payload, None
        user_permission_set = set(user.get("permissions", []))
        if not set(payload.get("permissions", [])).issubset(user_permission_set):
            payload["permissions"] = filter(
                lambda permission: permission in user_permission_set,
                payload["permissions"],
            )
        return payload, user