chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
from libcpp cimport bool as c_bool
|
||||
from libcpp.memory cimport shared_ptr
|
||||
from ray.includes.rpc_token_authentication cimport (
|
||||
CAuthenticationMode,
|
||||
GetAuthenticationMode,
|
||||
IsK8sTokenAuthEnabled,
|
||||
CAuthenticationToken,
|
||||
CAuthenticationTokenLoader,
|
||||
CAuthenticationTokenValidator,
|
||||
CTokenLoadResult,
|
||||
)
|
||||
from ray._private.authentication.authentication_constants import AUTHORIZATION_HEADER_NAME
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Authentication mode enum exposed to Python
|
||||
class AuthenticationMode:
|
||||
DISABLED = CAuthenticationMode.DISABLED
|
||||
TOKEN = CAuthenticationMode.TOKEN
|
||||
|
||||
|
||||
def get_authentication_mode():
|
||||
"""Get the current authentication mode.
|
||||
|
||||
Returns:
|
||||
AuthenticationMode enum value (DISABLED or TOKEN)
|
||||
"""
|
||||
return GetAuthenticationMode()
|
||||
|
||||
|
||||
def is_k8s_token_auth_enabled():
|
||||
"""Returns whether Kubernetes token authentication is enabled.
|
||||
|
||||
Returns:
|
||||
bool: True if Kubernetes token auth is enabled, false otherwise.
|
||||
"""
|
||||
return IsK8sTokenAuthEnabled()
|
||||
|
||||
|
||||
def validate_authentication_token(provided_metadata: str) -> bool:
|
||||
"""Validate provided authentication token.
|
||||
|
||||
For TOKEN mode, compares against the expected token.
|
||||
If K8S auth is enabled, validates against the Kubernetes API.
|
||||
|
||||
Args:
|
||||
provided_metadata: Full authorization header value (e.g., "Bearer <token>")
|
||||
|
||||
Returns:
|
||||
bool: True if token is valid, False otherwise
|
||||
"""
|
||||
cdef shared_ptr[const CAuthenticationToken] expected_ptr
|
||||
|
||||
if get_authentication_mode() == CAuthenticationMode.TOKEN and not is_k8s_token_auth_enabled():
|
||||
expected_ptr = CAuthenticationTokenLoader.instance().GetToken(False)
|
||||
if not expected_ptr:
|
||||
return False
|
||||
|
||||
return CAuthenticationTokenValidator.instance().ValidateToken(
|
||||
expected_ptr, provided_metadata.encode())
|
||||
|
||||
|
||||
class AuthenticationTokenLoader:
|
||||
"""Python wrapper for C++ AuthenticationTokenLoader singleton."""
|
||||
|
||||
@staticmethod
|
||||
def instance():
|
||||
"""Get the singleton instance (returns a wrapper for convenience)."""
|
||||
return AuthenticationTokenLoader()
|
||||
|
||||
def has_token(self, ignore_auth_mode=False):
|
||||
"""Check if an authentication token exists without crashing.
|
||||
|
||||
Args:
|
||||
ignore_auth_mode: If True, bypass auth mode check and attempt to load token
|
||||
regardless of RAY_AUTH_MODE setting.
|
||||
|
||||
Returns:
|
||||
bool: True if a token exists, False otherwise
|
||||
|
||||
Raises:
|
||||
AuthenticationError: If any issues loading the token
|
||||
"""
|
||||
cdef CTokenLoadResult result
|
||||
cdef c_bool c_ignore_auth_mode = ignore_auth_mode
|
||||
|
||||
with nogil:
|
||||
result = CAuthenticationTokenLoader.instance().TryLoadToken(c_ignore_auth_mode)
|
||||
|
||||
if result.hasError():
|
||||
from ray.exceptions import AuthenticationError
|
||||
raise AuthenticationError(result.error_message.decode('utf-8'))
|
||||
|
||||
if not result.token.has_value() or result.token.value().empty():
|
||||
return False
|
||||
return True
|
||||
|
||||
def reset_cache(self):
|
||||
"""Reset the C++ authentication token cache.
|
||||
|
||||
This forces the token loader to reload the token from environment
|
||||
variables or files on the next request.
|
||||
"""
|
||||
CAuthenticationTokenLoader.instance().ResetCache()
|
||||
|
||||
def get_token_for_http_header(self, ignore_auth_mode=False) -> dict:
|
||||
"""Get authentication token as a dictionary for HTTP headers.
|
||||
|
||||
This method loads the token from C++ AuthenticationTokenLoader and returns it
|
||||
as a dictionary that can be merged with existing headers. It returns an empty
|
||||
dictionary if:
|
||||
- A token does not exist
|
||||
- The token is empty
|
||||
|
||||
Args:
|
||||
ignore_auth_mode: If True, bypass auth mode check and attempt to load token
|
||||
regardless of RAY_AUTH_MODE setting.
|
||||
|
||||
Returns:
|
||||
dict: Empty dict or {"authorization": "Bearer <token>"}
|
||||
"""
|
||||
if not self.has_token(ignore_auth_mode):
|
||||
return {}
|
||||
|
||||
# Get the token from C++ layer (returns shared_ptr)
|
||||
cdef shared_ptr[const CAuthenticationToken] token_ptr = \
|
||||
CAuthenticationTokenLoader.instance().GetToken(ignore_auth_mode)
|
||||
|
||||
if not token_ptr or token_ptr.get().empty():
|
||||
return {}
|
||||
|
||||
return {AUTHORIZATION_HEADER_NAME: token_ptr.get().ToAuthorizationHeaderValue().decode('utf-8')}
|
||||
|
||||
def get_raw_token(self, ignore_auth_mode=False) -> str:
|
||||
"""Get the raw authentication token value.
|
||||
|
||||
Args:
|
||||
ignore_auth_mode: If True, bypass auth mode check and attempt to load token
|
||||
regardless of RAY_AUTH_MODE setting.
|
||||
|
||||
Returns:
|
||||
str: The raw token string, or empty string if no token exists
|
||||
"""
|
||||
if not self.has_token(ignore_auth_mode):
|
||||
return ""
|
||||
|
||||
# Get the token from C++ layer (returns shared_ptr)
|
||||
cdef shared_ptr[const CAuthenticationToken] token_ptr = \
|
||||
CAuthenticationTokenLoader.instance().GetToken(ignore_auth_mode)
|
||||
|
||||
if not token_ptr or token_ptr.get().empty():
|
||||
return ""
|
||||
|
||||
return token_ptr.get().GetRawValue().decode('utf-8')
|
||||
Reference in New Issue
Block a user