def project_key_from_auth(self, auth): if not auth.public_key: raise APIUnauthorized('Invalid api key') # Make sure the key even looks valid first, since it's # possible to get some garbage input here causing further # issues trying to query it from cache or the database. if not ProjectKey.looks_like_api_key(auth.public_key): raise APIUnauthorized('Invalid api key') try: pk = ProjectKey.objects.get_from_cache(public_key=auth.public_key) except ProjectKey.DoesNotExist: raise APIUnauthorized('Invalid api key') # a secret key may not be present which will be validated elsewhere if not constant_time_compare(pk.secret_key, auth.secret_key or pk.secret_key): raise APIUnauthorized('Invalid api key') if not pk.is_active: raise APIUnauthorized('API key is disabled') if not pk.roles.store: raise APIUnauthorized('Key does not allow event storage access') return pk
def post(self, request): relay = request.relay assert relay is not None # should be provided during Authentication project_ids = {} for public_key in request.relay_request_data.get("publicKeys") or (): if not ProjectKey.looks_like_api_key(public_key): continue try: pk = ProjectKey.objects.get_from_cache(public_key=public_key) except ProjectKey.DoesNotExist: continue # NB: Do not validate pk here (is_active or store). Relay should # also receive a mapping for disabled public keys and then perform # the full project config fetch. project_ids[public_key] = pk.project_id return Response({"projectIds": project_ids}, status=200)