We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Support JWT on cookies
private conversion: https://huggingface.slack.com/archives/D030YA5BW91/p1696507761676679

When the users goes to https://huggingface.co/datasets/emrgnt-cmplxty/sciphi-textbooks-are-all-you-need, moonlanding can put a cookie on `datasets-server.huggingface.co` with name `hf_jwt_[sha256(/datasets/emrgnt-cmplxty/sciphi-textbooks-are-all-you-need)]` and with the JWT as the value

This cookie would be read on datasets server when accessing a gated dataset

Doing so would simplify a lot the code on the Hub (moonlanding) by removing the need to refresh the JWT (remove an endpoint), and avoid the logic in the frontend code that refreshes the JWT. It would be a security improvement too, because the Hub's frontend code (javascript) would no more have access to the JWT (the browser directly adds the cookie to the HTTP request)

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `libs/libapi/src/libapi/authentication.py`
Content:
```
1 # SPDX-License-Identifier: Apache-2.0
2 # Copyright 2022 The HuggingFace Authors.
3 
4 import logging
5 from collections.abc import Generator
6 from typing import Literal, Optional
7 
8 import httpx
9 from libcommon.prometheus import StepProfiler
10 from starlette.requests import Request
11 
12 from libapi.exceptions import (
13     AuthCheckHubRequestError,
14     ExternalAuthenticatedError,
15     ExternalUnauthenticatedError,
16 )
17 from libapi.jwt_token import validate_jwt
18 
19 
20 class RequestAuth(httpx.Auth):
21     """Attaches input Request authentication headers to the given Request object."""
22 
23     def __init__(self, request: Optional[Request]) -> None:
24         self.cookie = request.headers.get("cookie") if request else None
25         self.authorization = request.headers.get("authorization") if request else None
26 
27     def auth_flow(self, request: httpx.Request) -> Generator[httpx.Request, httpx.Response, None]:
28         # modify and yield the request
29         if self.cookie:
30             request.headers["cookie"] = self.cookie
31         if self.authorization:
32             request.headers["authorization"] = self.authorization
33         yield request
34 
35 
36 def get_jwt_token(request: Optional[Request] = None) -> Optional[str]:
37     if not request:
38         return None
39     # x-api-token is deprecated and will be removed in the future
40     if token := request.headers.get("x-api-key"):
41         return token
42     authorization = request.headers.get("authorization")
43     if not authorization:
44         return None
45     token = authorization.removeprefix("Bearer jwt:")
46     return None if token == authorization else token
47 
48 
49 async def auth_check(
50     dataset: str,
51     external_auth_url: Optional[str] = None,
52     request: Optional[Request] = None,
53     hf_jwt_public_keys: Optional[list[str]] = None,
54     hf_jwt_algorithm: Optional[str] = None,
55     hf_timeout_seconds: Optional[float] = None,
56 ) -> Literal[True]:
57     """check if the dataset is authorized for the request
58 
59     It sends a request to the Hugging Face API to check if the dataset is authorized for the input request. The request
60     to the Hugging Face API is authenticated with the same authentication headers as the input request. It timeouts
61     after 200ms.
62 
63     Args:
64         dataset (`str`): the dataset name
65         external_auth_url (`str`, *optional*): the URL of an external authentication service. The URL must contain `%s`,
66           which will be replaced with the dataset name, for example: https://huggingface.co/api/datasets/%s/auth-check
67           The authentication service must return 200, 401, 403 or 404.
68           If None, the dataset is always authorized.
69         request (`Request`, *optional*): the request which optionally bears authentication headers: "cookie",
70           "authorization" or "X-Api-Key"
71         hf_jwt_public_keys (`list[str]`, *optional*): the public keys to use to decode the JWT token
72         hf_jwt_algorithm (`str`): the algorithm to use to decode the JWT token
73         hf_timeout_seconds (`float`, *optional*): the timeout in seconds for the external authentication service. It
74           is used both for the connection timeout and the read timeout. If None, the request never timeouts.
75 
76     Returns:
77         `Literal[True]`: the dataset is authorized for the request
78     """
79     with StepProfiler(method="auth_check", step="all"):
80         with StepProfiler(method="auth_check", step="check JWT"):
81             if (jwt_token := get_jwt_token(request)) and hf_jwt_public_keys and hf_jwt_algorithm:
82                 validate_jwt(
83                     dataset=dataset, token=jwt_token, public_keys=hf_jwt_public_keys, algorithm=hf_jwt_algorithm
84                 )
85                 logging.debug(
86                     "By-passing the authentication step, because a valid JWT was passed in headers"
87                     f" for dataset {dataset}. JWT was: {jwt_token}"
88                 )
89                 return True
90         with StepProfiler(method="auth_check", step="prepare parameters"):
91             if external_auth_url is None:
92                 return True
93             try:
94                 url = external_auth_url % dataset
95             except TypeError as e:
96                 raise ValueError("external_auth_url must contain %s") from e
97         with StepProfiler(method="auth_check", step="create auth parameter"):
98             auth = RequestAuth(request)
99         with StepProfiler(
100             method="auth_check",
101             step="requests.get",
102             context=f"external_auth_url={external_auth_url} timeout={hf_timeout_seconds}",
103         ):
104             try:
105                 logging.debug(
106                     f"Checking authentication on the Hugging Face Hub for dataset {dataset}, url: {url}, timeout:"
107                     f" {hf_timeout_seconds}, authorization: {auth.authorization}"
108                 )
109                 async with httpx.AsyncClient() as client:
110                     response = await client.get(url, auth=auth, timeout=hf_timeout_seconds)
111             except Exception as err:
112                 raise AuthCheckHubRequestError(
113                     (
114                         "Authentication check on the Hugging Face Hub failed or timed out. Please try again later,"
115                         " it's a temporary internal issue."
116                     ),
117                     err,
118                 ) from err
119     with StepProfiler(method="auth_check", step="return or raise"):
120         if response.status_code == 200:
121             return True
122         elif response.status_code == 401:
123             raise ExternalUnauthenticatedError(
124                 "The dataset does not exist, or is not accessible without authentication (private or gated). Please"
125                 " check the spelling of the dataset name or retry with authentication."
126             )
127         elif response.status_code in {403, 404}:
128             raise ExternalAuthenticatedError(
129                 "The dataset does not exist, or is not accessible with the current credentials (private or gated)."
130                 " Please check the spelling of the dataset name or retry with other authentication credentials."
131             )
132         else:
133             raise ValueError(f"Unexpected status code {response.status_code}")
134
```

Path: `services/admin/src/admin/authentication.py`
Content:
```
1 # SPDX-License-Identifier: Apache-2.0
2 # Copyright 2022 The HuggingFace Authors.
3 
4 from typing import Literal, Optional
5 
6 import httpx
7 from libapi.authentication import RequestAuth
8 from libapi.exceptions import ExternalAuthenticatedError, ExternalUnauthenticatedError
9 from starlette.requests import Request
10 
11 
12 async def auth_check(
13     external_auth_url: Optional[str] = None,
14     request: Optional[Request] = None,
15     organization: Optional[str] = None,
16     hf_timeout_seconds: Optional[float] = None,
17 ) -> Literal[True]:
18     """check if the user is member of the organization
19 
20     Args:
21         external_auth_url (`str`, *optional*): the URL of an external authentication service. If None, the dataset is always
22           authorized.
23         request (`Request`, *optional*): the request which optionally bears authentication headers: "cookie" or
24           "authorization"
25         organization (`str`, *optional*): the organization name. If None, the dataset is always
26           authorized.
27         hf_timeout_seconds (`float`, *optional*): the timeout in seconds for the HTTP request to the external authentication
28           service.
29 
30     Returns:
31         `Literal[True]`: the user is authorized
32     """
33     if organization is None or external_auth_url is None:
34         return True
35     try:
36         async with httpx.AsyncClient() as client:
37             response = await client.get(external_auth_url, auth=RequestAuth(request), timeout=hf_timeout_seconds)
38     except Exception as err:
39         raise RuntimeError("External authentication check failed", err) from err
40     if response.status_code == 200:
41         try:
42             json = response.json()
43             if organization is None or organization in {org["name"] for org in json["orgs"]}:
44                 return True
45             else:
46                 raise ExternalAuthenticatedError("You are not member of the organization")
47         except Exception as err:
48             raise ExternalAuthenticatedError(
49                 "Cannot access the route with the current credentials. Please retry with other authentication"
50                 " credentials."
51             ) from err
52     elif response.status_code == 401:
53         raise ExternalUnauthenticatedError("Cannot access the route. Please retry with authentication.")
54     elif response.status_code in {403, 404}:
55         raise ExternalAuthenticatedError(
56             "Cannot access the route with the current credentials. Please retry with other authentication credentials."
57         )
58     else:
59         raise ValueError(f"Unexpected status code {response.status_code}")
60
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/libs/libapi/src/libapi/authentication.py b/libs/libapi/src/libapi/authentication.py
--- a/libs/libapi/src/libapi/authentication.py
+++ b/libs/libapi/src/libapi/authentication.py
@@ -21,13 +21,10 @@
     """Attaches input Request authentication headers to the given Request object."""
 
     def __init__(self, request: Optional[Request]) -> None:
-        self.cookie = request.headers.get("cookie") if request else None
         self.authorization = request.headers.get("authorization") if request else None
 
     def auth_flow(self, request: httpx.Request) -> Generator[httpx.Request, httpx.Response, None]:
         # modify and yield the request
-        if self.cookie:
-            request.headers["cookie"] = self.cookie
         if self.authorization:
             request.headers["authorization"] = self.authorization
         yield request
@@ -66,7 +63,7 @@
           which will be replaced with the dataset name, for example: https://huggingface.co/api/datasets/%s/auth-check
           The authentication service must return 200, 401, 403 or 404.
           If None, the dataset is always authorized.
-        request (`Request`, *optional*): the request which optionally bears authentication headers: "cookie",
+        request (`Request`, *optional*): the request which optionally bears authentication headers:
           "authorization" or "X-Api-Key"
         hf_jwt_public_keys (`list[str]`, *optional*): the public keys to use to decode the JWT token
         hf_jwt_algorithm (`str`): the algorithm to use to decode the JWT token
diff --git a/services/admin/src/admin/authentication.py b/services/admin/src/admin/authentication.py
--- a/services/admin/src/admin/authentication.py
+++ b/services/admin/src/admin/authentication.py
@@ -20,8 +20,7 @@
     Args:
         external_auth_url (`str`, *optional*): the URL of an external authentication service. If None, the dataset is always
           authorized.
-        request (`Request`, *optional*): the request which optionally bears authentication headers: "cookie" or
-          "authorization"
+        request (`Request`, *optional*): the request which optionally bears authentication header: "authorization"
         organization (`str`, *optional*): the organization name. If None, the dataset is always
           authorized.
         hf_timeout_seconds (`float`, *optional*): the timeout in seconds for the HTTP request to the external authentication

{"golden_diff": "diff --git a/libs/libapi/src/libapi/authentication.py b/libs/libapi/src/libapi/authentication.py\n--- a/libs/libapi/src/libapi/authentication.py\n+++ b/libs/libapi/src/libapi/authentication.py\n@@ -21,13 +21,10 @@\n     \"\"\"Attaches input Request authentication headers to the given Request object.\"\"\"\n \n     def __init__(self, request: Optional[Request]) -> None:\n-        self.cookie = request.headers.get(\"cookie\") if request else None\n         self.authorization = request.headers.get(\"authorization\") if request else None\n \n     def auth_flow(self, request: httpx.Request) -> Generator[httpx.Request, httpx.Response, None]:\n         # modify and yield the request\n-        if self.cookie:\n-            request.headers[\"cookie\"] = self.cookie\n         if self.authorization:\n             request.headers[\"authorization\"] = self.authorization\n         yield request\n@@ -66,7 +63,7 @@\n           which will be replaced with the dataset name, for example: https://huggingface.co/api/datasets/%s/auth-check\n           The authentication service must return 200, 401, 403 or 404.\n           If None, the dataset is always authorized.\n-        request (`Request`, *optional*): the request which optionally bears authentication headers: \"cookie\",\n+        request (`Request`, *optional*): the request which optionally bears authentication headers:\n           \"authorization\" or \"X-Api-Key\"\n         hf_jwt_public_keys (`list[str]`, *optional*): the public keys to use to decode the JWT token\n         hf_jwt_algorithm (`str`): the algorithm to use to decode the JWT token\ndiff --git a/services/admin/src/admin/authentication.py b/services/admin/src/admin/authentication.py\n--- a/services/admin/src/admin/authentication.py\n+++ b/services/admin/src/admin/authentication.py\n@@ -20,8 +20,7 @@\n     Args:\n         external_auth_url (`str`, *optional*): the URL of an external authentication service. If None, the dataset is always\n           authorized.\n-        request (`Request`, *optional*): the request which optionally bears authentication headers: \"cookie\" or\n-          \"authorization\"\n+        request (`Request`, *optional*): the request which optionally bears authentication header: \"authorization\"\n         organization (`str`, *optional*): the organization name. If None, the dataset is always\n           authorized.\n         hf_timeout_seconds (`float`, *optional*): the timeout in seconds for the HTTP request to the external authentication\n", "issue": "Support JWT on cookies\nprivate conversion: https://huggingface.slack.com/archives/D030YA5BW91/p1696507761676679\r\n\r\nWhen the users goes to https://huggingface.co/datasets/emrgnt-cmplxty/sciphi-textbooks-are-all-you-need, moonlanding can put a cookie on `datasets-server.huggingface.co` with name `hf_jwt_[sha256(/datasets/emrgnt-cmplxty/sciphi-textbooks-are-all-you-need)]` and with the JWT as the value\r\n\r\nThis cookie would be read on datasets server when accessing a gated dataset\r\n\r\nDoing so would simplify a lot the code on the Hub (moonlanding) by removing the need to refresh the JWT (remove an endpoint), and avoid the logic in the frontend code that refreshes the JWT. It would be a security improvement too, because the Hub's frontend code (javascript) would no more have access to the JWT (the browser directly adds the cookie to the HTTP request)\n", "before_files": [{"content": "# SPDX-License-Identifier: Apache-2.0\n# Copyright 2022 The HuggingFace Authors.\n\nimport logging\nfrom collections.abc import Generator\nfrom typing import Literal, Optional\n\nimport httpx\nfrom libcommon.prometheus import StepProfiler\nfrom starlette.requests import Request\n\nfrom libapi.exceptions import (\n    AuthCheckHubRequestError,\n    ExternalAuthenticatedError,\n    ExternalUnauthenticatedError,\n)\nfrom libapi.jwt_token import validate_jwt\n\n\nclass RequestAuth(httpx.Auth):\n    \"\"\"Attaches input Request authentication headers to the given Request object.\"\"\"\n\n    def __init__(self, request: Optional[Request]) -> None:\n        self.cookie = request.headers.get(\"cookie\") if request else None\n        self.authorization = request.headers.get(\"authorization\") if request else None\n\n    def auth_flow(self, request: httpx.Request) -> Generator[httpx.Request, httpx.Response, None]:\n        # modify and yield the request\n        if self.cookie:\n            request.headers[\"cookie\"] = self.cookie\n        if self.authorization:\n            request.headers[\"authorization\"] = self.authorization\n        yield request\n\n\ndef get_jwt_token(request: Optional[Request] = None) -> Optional[str]:\n    if not request:\n        return None\n    # x-api-token is deprecated and will be removed in the future\n    if token := request.headers.get(\"x-api-key\"):\n        return token\n    authorization = request.headers.get(\"authorization\")\n    if not authorization:\n        return None\n    token = authorization.removeprefix(\"Bearer jwt:\")\n    return None if token == authorization else token\n\n\nasync def auth_check(\n    dataset: str,\n    external_auth_url: Optional[str] = None,\n    request: Optional[Request] = None,\n    hf_jwt_public_keys: Optional[list[str]] = None,\n    hf_jwt_algorithm: Optional[str] = None,\n    hf_timeout_seconds: Optional[float] = None,\n) -> Literal[True]:\n    \"\"\"check if the dataset is authorized for the request\n\n    It sends a request to the Hugging Face API to check if the dataset is authorized for the input request. The request\n    to the Hugging Face API is authenticated with the same authentication headers as the input request. It timeouts\n    after 200ms.\n\n    Args:\n        dataset (`str`): the dataset name\n        external_auth_url (`str`, *optional*): the URL of an external authentication service. The URL must contain `%s`,\n          which will be replaced with the dataset name, for example: https://huggingface.co/api/datasets/%s/auth-check\n          The authentication service must return 200, 401, 403 or 404.\n          If None, the dataset is always authorized.\n        request (`Request`, *optional*): the request which optionally bears authentication headers: \"cookie\",\n          \"authorization\" or \"X-Api-Key\"\n        hf_jwt_public_keys (`list[str]`, *optional*): the public keys to use to decode the JWT token\n        hf_jwt_algorithm (`str`): the algorithm to use to decode the JWT token\n        hf_timeout_seconds (`float`, *optional*): the timeout in seconds for the external authentication service. It\n          is used both for the connection timeout and the read timeout. If None, the request never timeouts.\n\n    Returns:\n        `Literal[True]`: the dataset is authorized for the request\n    \"\"\"\n    with StepProfiler(method=\"auth_check\", step=\"all\"):\n        with StepProfiler(method=\"auth_check\", step=\"check JWT\"):\n            if (jwt_token := get_jwt_token(request)) and hf_jwt_public_keys and hf_jwt_algorithm:\n                validate_jwt(\n                    dataset=dataset, token=jwt_token, public_keys=hf_jwt_public_keys, algorithm=hf_jwt_algorithm\n                )\n                logging.debug(\n                    \"By-passing the authentication step, because a valid JWT was passed in headers\"\n                    f\" for dataset {dataset}. JWT was: {jwt_token}\"\n                )\n                return True\n        with StepProfiler(method=\"auth_check\", step=\"prepare parameters\"):\n            if external_auth_url is None:\n                return True\n            try:\n                url = external_auth_url % dataset\n            except TypeError as e:\n                raise ValueError(\"external_auth_url must contain %s\") from e\n        with StepProfiler(method=\"auth_check\", step=\"create auth parameter\"):\n            auth = RequestAuth(request)\n        with StepProfiler(\n            method=\"auth_check\",\n            step=\"requests.get\",\n            context=f\"external_auth_url={external_auth_url} timeout={hf_timeout_seconds}\",\n        ):\n            try:\n                logging.debug(\n                    f\"Checking authentication on the Hugging Face Hub for dataset {dataset}, url: {url}, timeout:\"\n                    f\" {hf_timeout_seconds}, authorization: {auth.authorization}\"\n                )\n                async with httpx.AsyncClient() as client:\n                    response = await client.get(url, auth=auth, timeout=hf_timeout_seconds)\n            except Exception as err:\n                raise AuthCheckHubRequestError(\n                    (\n                        \"Authentication check on the Hugging Face Hub failed or timed out. Please try again later,\"\n                        \" it's a temporary internal issue.\"\n                    ),\n                    err,\n                ) from err\n    with StepProfiler(method=\"auth_check\", step=\"return or raise\"):\n        if response.status_code == 200:\n            return True\n        elif response.status_code == 401:\n            raise ExternalUnauthenticatedError(\n                \"The dataset does not exist, or is not accessible without authentication (private or gated). Please\"\n                \" check the spelling of the dataset name or retry with authentication.\"\n            )\n        elif response.status_code in {403, 404}:\n            raise ExternalAuthenticatedError(\n                \"The dataset does not exist, or is not accessible with the current credentials (private or gated).\"\n                \" Please check the spelling of the dataset name or retry with other authentication credentials.\"\n            )\n        else:\n            raise ValueError(f\"Unexpected status code {response.status_code}\")\n", "path": "libs/libapi/src/libapi/authentication.py"}, {"content": "# SPDX-License-Identifier: Apache-2.0\n# Copyright 2022 The HuggingFace Authors.\n\nfrom typing import Literal, Optional\n\nimport httpx\nfrom libapi.authentication import RequestAuth\nfrom libapi.exceptions import ExternalAuthenticatedError, ExternalUnauthenticatedError\nfrom starlette.requests import Request\n\n\nasync def auth_check(\n    external_auth_url: Optional[str] = None,\n    request: Optional[Request] = None,\n    organization: Optional[str] = None,\n    hf_timeout_seconds: Optional[float] = None,\n) -> Literal[True]:\n    \"\"\"check if the user is member of the organization\n\n    Args:\n        external_auth_url (`str`, *optional*): the URL of an external authentication service. If None, the dataset is always\n          authorized.\n        request (`Request`, *optional*): the request which optionally bears authentication headers: \"cookie\" or\n          \"authorization\"\n        organization (`str`, *optional*): the organization name. If None, the dataset is always\n          authorized.\n        hf_timeout_seconds (`float`, *optional*): the timeout in seconds for the HTTP request to the external authentication\n          service.\n\n    Returns:\n        `Literal[True]`: the user is authorized\n    \"\"\"\n    if organization is None or external_auth_url is None:\n        return True\n    try:\n        async with httpx.AsyncClient() as client:\n            response = await client.get(external_auth_url, auth=RequestAuth(request), timeout=hf_timeout_seconds)\n    except Exception as err:\n        raise RuntimeError(\"External authentication check failed\", err) from err\n    if response.status_code == 200:\n        try:\n            json = response.json()\n            if organization is None or organization in {org[\"name\"] for org in json[\"orgs\"]}:\n                return True\n            else:\n                raise ExternalAuthenticatedError(\"You are not member of the organization\")\n        except Exception as err:\n            raise ExternalAuthenticatedError(\n                \"Cannot access the route with the current credentials. Please retry with other authentication\"\n                \" credentials.\"\n            ) from err\n    elif response.status_code == 401:\n        raise ExternalUnauthenticatedError(\"Cannot access the route. Please retry with authentication.\")\n    elif response.status_code in {403, 404}:\n        raise ExternalAuthenticatedError(\n            \"Cannot access the route with the current credentials. Please retry with other authentication credentials.\"\n        )\n    else:\n        raise ValueError(f\"Unexpected status code {response.status_code}\")\n", "path": "services/admin/src/admin/authentication.py"}], "after_files": [{"content": "# SPDX-License-Identifier: Apache-2.0\n# Copyright 2022 The HuggingFace Authors.\n\nimport logging\nfrom collections.abc import Generator\nfrom typing import Literal, Optional\n\nimport httpx\nfrom libcommon.prometheus import StepProfiler\nfrom starlette.requests import Request\n\nfrom libapi.exceptions import (\n    AuthCheckHubRequestError,\n    ExternalAuthenticatedError,\n    ExternalUnauthenticatedError,\n)\nfrom libapi.jwt_token import validate_jwt\n\n\nclass RequestAuth(httpx.Auth):\n    \"\"\"Attaches input Request authentication headers to the given Request object.\"\"\"\n\n    def __init__(self, request: Optional[Request]) -> None:\n        self.authorization = request.headers.get(\"authorization\") if request else None\n\n    def auth_flow(self, request: httpx.Request) -> Generator[httpx.Request, httpx.Response, None]:\n        # modify and yield the request\n        if self.authorization:\n            request.headers[\"authorization\"] = self.authorization\n        yield request\n\n\ndef get_jwt_token(request: Optional[Request] = None) -> Optional[str]:\n    if not request:\n        return None\n    # x-api-token is deprecated and will be removed in the future\n    if token := request.headers.get(\"x-api-key\"):\n        return token\n    authorization = request.headers.get(\"authorization\")\n    if not authorization:\n        return None\n    token = authorization.removeprefix(\"Bearer jwt:\")\n    return None if token == authorization else token\n\n\nasync def auth_check(\n    dataset: str,\n    external_auth_url: Optional[str] = None,\n    request: Optional[Request] = None,\n    hf_jwt_public_keys: Optional[list[str]] = None,\n    hf_jwt_algorithm: Optional[str] = None,\n    hf_timeout_seconds: Optional[float] = None,\n) -> Literal[True]:\n    \"\"\"check if the dataset is authorized for the request\n\n    It sends a request to the Hugging Face API to check if the dataset is authorized for the input request. The request\n    to the Hugging Face API is authenticated with the same authentication headers as the input request. It timeouts\n    after 200ms.\n\n    Args:\n        dataset (`str`): the dataset name\n        external_auth_url (`str`, *optional*): the URL of an external authentication service. The URL must contain `%s`,\n          which will be replaced with the dataset name, for example: https://huggingface.co/api/datasets/%s/auth-check\n          The authentication service must return 200, 401, 403 or 404.\n          If None, the dataset is always authorized.\n        request (`Request`, *optional*): the request which optionally bears authentication headers:\n          \"authorization\" or \"X-Api-Key\"\n        hf_jwt_public_keys (`list[str]`, *optional*): the public keys to use to decode the JWT token\n        hf_jwt_algorithm (`str`): the algorithm to use to decode the JWT token\n        hf_timeout_seconds (`float`, *optional*): the timeout in seconds for the external authentication service. It\n          is used both for the connection timeout and the read timeout. If None, the request never timeouts.\n\n    Returns:\n        `Literal[True]`: the dataset is authorized for the request\n    \"\"\"\n    with StepProfiler(method=\"auth_check\", step=\"all\"):\n        with StepProfiler(method=\"auth_check\", step=\"check JWT\"):\n            if (jwt_token := get_jwt_token(request)) and hf_jwt_public_keys and hf_jwt_algorithm:\n                validate_jwt(\n                    dataset=dataset, token=jwt_token, public_keys=hf_jwt_public_keys, algorithm=hf_jwt_algorithm\n                )\n                logging.debug(\n                    \"By-passing the authentication step, because a valid JWT was passed in headers\"\n                    f\" for dataset {dataset}. JWT was: {jwt_token}\"\n                )\n                return True\n        with StepProfiler(method=\"auth_check\", step=\"prepare parameters\"):\n            if external_auth_url is None:\n                return True\n            try:\n                url = external_auth_url % dataset\n            except TypeError as e:\n                raise ValueError(\"external_auth_url must contain %s\") from e\n        with StepProfiler(method=\"auth_check\", step=\"create auth parameter\"):\n            auth = RequestAuth(request)\n        with StepProfiler(\n            method=\"auth_check\",\n            step=\"requests.get\",\n            context=f\"external_auth_url={external_auth_url} timeout={hf_timeout_seconds}\",\n        ):\n            try:\n                logging.debug(\n                    f\"Checking authentication on the Hugging Face Hub for dataset {dataset}, url: {url}, timeout:\"\n                    f\" {hf_timeout_seconds}, authorization: {auth.authorization}\"\n                )\n                async with httpx.AsyncClient() as client:\n                    response = await client.get(url, auth=auth, timeout=hf_timeout_seconds)\n            except Exception as err:\n                raise AuthCheckHubRequestError(\n                    (\n                        \"Authentication check on the Hugging Face Hub failed or timed out. Please try again later,\"\n                        \" it's a temporary internal issue.\"\n                    ),\n                    err,\n                ) from err\n    with StepProfiler(method=\"auth_check\", step=\"return or raise\"):\n        if response.status_code == 200:\n            return True\n        elif response.status_code == 401:\n            raise ExternalUnauthenticatedError(\n                \"The dataset does not exist, or is not accessible without authentication (private or gated). Please\"\n                \" check the spelling of the dataset name or retry with authentication.\"\n            )\n        elif response.status_code in {403, 404}:\n            raise ExternalAuthenticatedError(\n                \"The dataset does not exist, or is not accessible with the current credentials (private or gated).\"\n                \" Please check the spelling of the dataset name or retry with other authentication credentials.\"\n            )\n        else:\n            raise ValueError(f\"Unexpected status code {response.status_code}\")\n", "path": "libs/libapi/src/libapi/authentication.py"}, {"content": "# SPDX-License-Identifier: Apache-2.0\n# Copyright 2022 The HuggingFace Authors.\n\nfrom typing import Literal, Optional\n\nimport httpx\nfrom libapi.authentication import RequestAuth\nfrom libapi.exceptions import ExternalAuthenticatedError, ExternalUnauthenticatedError\nfrom starlette.requests import Request\n\n\nasync def auth_check(\n    external_auth_url: Optional[str] = None,\n    request: Optional[Request] = None,\n    organization: Optional[str] = None,\n    hf_timeout_seconds: Optional[float] = None,\n) -> Literal[True]:\n    \"\"\"check if the user is member of the organization\n\n    Args:\n        external_auth_url (`str`, *optional*): the URL of an external authentication service. If None, the dataset is always\n          authorized.\n        request (`Request`, *optional*): the request which optionally bears authentication header: \"authorization\"\n        organization (`str`, *optional*): the organization name. If None, the dataset is always\n          authorized.\n        hf_timeout_seconds (`float`, *optional*): the timeout in seconds for the HTTP request to the external authentication\n          service.\n\n    Returns:\n        `Literal[True]`: the user is authorized\n    \"\"\"\n    if organization is None or external_auth_url is None:\n        return True\n    try:\n        async with httpx.AsyncClient() as client:\n            response = await client.get(external_auth_url, auth=RequestAuth(request), timeout=hf_timeout_seconds)\n    except Exception as err:\n        raise RuntimeError(\"External authentication check failed\", err) from err\n    if response.status_code == 200:\n        try:\n            json = response.json()\n            if organization is None or organization in {org[\"name\"] for org in json[\"orgs\"]}:\n                return True\n            else:\n                raise ExternalAuthenticatedError(\"You are not member of the organization\")\n        except Exception as err:\n            raise ExternalAuthenticatedError(\n                \"Cannot access the route with the current credentials. Please retry with other authentication\"\n                \" credentials.\"\n            ) from err\n    elif response.status_code == 401:\n        raise ExternalUnauthenticatedError(\"Cannot access the route. Please retry with authentication.\")\n    elif response.status_code in {403, 404}:\n        raise ExternalAuthenticatedError(\n            \"Cannot access the route with the current credentials. Please retry with other authentication credentials.\"\n        )\n    else:\n        raise ValueError(f\"Unexpected status code {response.status_code}\")\n", "path": "services/admin/src/admin/authentication.py"}]}