mirror of
https://github.com/danswer-ai/danswer.git
synced 2025-09-27 12:29:41 +02:00
@@ -1,3 +1,4 @@
|
|||||||
|
import hashlib
|
||||||
import secrets
|
import secrets
|
||||||
import uuid
|
import uuid
|
||||||
from urllib.parse import quote
|
from urllib.parse import quote
|
||||||
@@ -18,7 +19,8 @@ _API_KEY_HEADER_NAME = "Authorization"
|
|||||||
# organizations like the Internet Engineering Task Force (IETF).
|
# organizations like the Internet Engineering Task Force (IETF).
|
||||||
_API_KEY_HEADER_ALTERNATIVE_NAME = "X-Danswer-Authorization"
|
_API_KEY_HEADER_ALTERNATIVE_NAME = "X-Danswer-Authorization"
|
||||||
_BEARER_PREFIX = "Bearer "
|
_BEARER_PREFIX = "Bearer "
|
||||||
_API_KEY_PREFIX = "dn_"
|
_API_KEY_PREFIX = "on_"
|
||||||
|
_DEPRECATED_API_KEY_PREFIX = "dn_"
|
||||||
_API_KEY_LEN = 192
|
_API_KEY_LEN = 192
|
||||||
|
|
||||||
|
|
||||||
@@ -52,7 +54,9 @@ def extract_tenant_from_api_key_header(request: Request) -> str | None:
|
|||||||
|
|
||||||
api_key = raw_api_key_header[len(_BEARER_PREFIX) :].strip()
|
api_key = raw_api_key_header[len(_BEARER_PREFIX) :].strip()
|
||||||
|
|
||||||
if not api_key.startswith(_API_KEY_PREFIX):
|
if not api_key.startswith(_API_KEY_PREFIX) and not api_key.startswith(
|
||||||
|
_DEPRECATED_API_KEY_PREFIX
|
||||||
|
):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
parts = api_key[len(_API_KEY_PREFIX) :].split(".", 1)
|
parts = api_key[len(_API_KEY_PREFIX) :].split(".", 1)
|
||||||
@@ -63,10 +67,19 @@ def extract_tenant_from_api_key_header(request: Request) -> str | None:
|
|||||||
return unquote(tenant_id) if tenant_id else None
|
return unquote(tenant_id) if tenant_id else None
|
||||||
|
|
||||||
|
|
||||||
|
def _deprecated_hash_api_key(api_key: str) -> str:
|
||||||
|
return sha256_crypt.hash(api_key, salt="", rounds=API_KEY_HASH_ROUNDS)
|
||||||
|
|
||||||
|
|
||||||
def hash_api_key(api_key: str) -> str:
|
def hash_api_key(api_key: str) -> str:
|
||||||
# NOTE: no salt is needed, as the API key is randomly generated
|
# NOTE: no salt is needed, as the API key is randomly generated
|
||||||
# and overlaps are impossible
|
# and overlaps are impossible
|
||||||
return sha256_crypt.hash(api_key, salt="", rounds=API_KEY_HASH_ROUNDS)
|
if api_key.startswith(_API_KEY_PREFIX):
|
||||||
|
return hashlib.sha256(api_key.encode("utf-8")).hexdigest()
|
||||||
|
elif api_key.startswith(_DEPRECATED_API_KEY_PREFIX):
|
||||||
|
return _deprecated_hash_api_key(api_key)
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Invalid API key prefix: {api_key[:3]}")
|
||||||
|
|
||||||
|
|
||||||
def build_displayable_api_key(api_key: str) -> str:
|
def build_displayable_api_key(api_key: str) -> str:
|
||||||
|
Reference in New Issue
Block a user