Пример #1
0
 async def _retrieve_subscription_from_cache(cls, owner_id):
     r = await utils.get_aredis_for_cache()
     encrypted_sub = await r.get("subscription-cache-owner-%s" % owner_id)
     if encrypted_sub:
         return cls.from_dict(
             owner_id, json.loads(crypto.decrypt(encrypted_sub).decode())
         )
Пример #2
0
def test_key_rotation(
    cleanup_secrets: None,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    x = "this is an amazing string, right? 🙄".encode()

    monkeypatch.setattr(config, "CACHE_TOKEN_SECRET", "old password")
    importlib.reload(crypto)  # regen digest with new secret
    encryped_old = crypto.encrypt(x)

    monkeypatch.setattr(config, "CACHE_TOKEN_SECRET", "new password")
    monkeypatch.setattr(config, "CACHE_TOKEN_SECRET_OLD", "old password")
    importlib.reload(crypto)  # regen digest with new secrets
    encryped_new = crypto.encrypt(x)
    assert encryped_new != encryped_old

    assert x == crypto.decrypt(encryped_new)
    assert x == crypto.decrypt(encryped_old)
Пример #3
0
 async def _retrieve_subscription_from_cache(
         cls: typing.Type[SubscriptionT], redis: utils.RedisCache,
         owner_id: int) -> typing.Optional[SubscriptionT]:
     async with await redis.pipeline() as pipe:
         await pipe.get(cls._cache_key(owner_id))
         await pipe.ttl(cls._cache_key(owner_id))
         encrypted_sub, ttl = typing.cast(typing.Tuple[str, int], await
                                          pipe.execute())
     if encrypted_sub:
         return cls.from_dict(
             redis,
             owner_id,
             json.loads(crypto.decrypt(encrypted_sub.encode()).decode()),
             ttl,
         )
     return None
Пример #4
0
 async def _retrieve_from_cache(
         cls, redis: utils.RedisCache,
         owner_id: int) -> typing.Optional["UserTokens"]:
     async with await redis.pipeline() as pipe:
         await pipe.get(cls._cache_key(owner_id))
         await pipe.ttl(cls._cache_key(owner_id))
         encrypted_tokens, ttl = typing.cast(typing.Tuple[str, int], await
                                             pipe.execute())
     if encrypted_tokens:
         return cls(
             redis,
             owner_id,
             json.loads(crypto.decrypt(
                 encrypted_tokens.encode()).decode())["tokens"],
             ttl,
         )
     return None
Пример #5
0
    async def update(
        cls,
        redis: redis_utils.RedisCache,
        api_access_key: str,
        data: ApplicationDashboardJSON,
    ) -> None:
        if data["github_account"] is None:
            account_scope = None
        else:
            account_scope = data["github_account"]["login"]

        encrypted_application = await redis.get(
            cls._cache_key(api_access_key, account_scope))
        if encrypted_application is not None:
            decrypted_application = typing.cast(
                CachedApplication,
                json.loads(
                    crypto.decrypt(encrypted_application.encode()).decode()),
            )
            if "account_scope" not in decrypted_application:
                # TODO(sileht): Backward compat, delete me
                return None

            if data["github_account"] is None:
                full_account_scope = None
            else:
                full_account_scope = ApplicationAccountScope({
                    "id":
                    data["github_account"]["id"],
                    "login":
                    data["github_account"]["login"],
                })
            app = cls(
                redis,
                data["id"],
                data["name"],
                decrypted_application["api_access_key"],
                decrypted_application["api_secret_key"],
                full_account_scope,
            )
            await app.save_to_cache()
        return None
Пример #6
0
    async def _retrieve_from_cache(
        cls,
        redis: redis_utils.RedisCache,
        api_access_key: str,
        api_secret_key: str,
        account_scope: typing.Optional[github_types.GitHubLogin],
    ) -> typing.Optional["ApplicationSaas"]:
        async with await redis.pipeline() as pipe:
            await pipe.get(cls._cache_key(api_access_key, account_scope))
            await pipe.ttl(cls._cache_key(api_access_key, account_scope))
            encrypted_application, ttl = typing.cast(typing.Tuple[str, int],
                                                     await pipe.execute())
        if encrypted_application:
            decrypted_application = typing.cast(
                CachedApplication,
                json.loads(
                    crypto.decrypt(encrypted_application.encode()).decode()),
            )
            if decrypted_application["api_secret_key"] != api_secret_key:
                # Don't raise ApplicationUserNotFound yet, check the database first
                return None

            if "account_scope" not in decrypted_application:
                # TODO(sileht): Backward compat, delete me
                return None

            if "id" not in decrypted_application:
                # TODO(sileht): Backward compat, delete me
                return None

            return cls(
                redis,
                decrypted_application["id"],
                decrypted_application["name"],
                decrypted_application["api_access_key"],
                decrypted_application["api_secret_key"],
                decrypted_application["account_scope"],
                ttl,
            )
        return None
Пример #7
0
    async def _retrieve_from_cache(
            cls, redis: utils.RedisCache,
            owner_id: int) -> typing.Optional["UserTokensSaas"]:
        async with await redis.pipeline() as pipe:
            await pipe.get(cls._cache_key(owner_id))
            await pipe.ttl(cls._cache_key(owner_id))
            encrypted_tokens, ttl = typing.cast(typing.Tuple[str, int], await
                                                pipe.execute())
        if encrypted_tokens:
            decrypted_tokens = json.loads(
                crypto.decrypt(encrypted_tokens.encode()).decode())

            if "tokens" in decrypted_tokens:
                # Old cache format, just drop it
                return None

            if (decrypted_tokens["user_tokens"]
                    and "id" not in decrypted_tokens["user_tokens"][0]):
                # Old cache format, just drop it
                return None

            return cls(redis, owner_id, decrypted_tokens["user_tokens"], ttl)
        return None
Пример #8
0
def test_encrypt() -> None:
    x = "this is an amazing string, right? 🙄".encode()
    assert x == crypto.decrypt(crypto.encrypt(x))
    assert x == crypto.decrypt(crypto.encrypt(x))
    assert x == crypto.decrypt(
        crypto.encrypt(crypto.decrypt(crypto.encrypt(x))))