
    $jj                         d Z ddlmZmZ ddlmZ ddlmZ ddlm	Z	 ddl
mZ  G d de          Ze G d	 d
                      Ze G d d                      Z G d de	e          ZdS )z>Tenant Extension for multi-tenancy and API key authentication.    )ABCabstractmethod)	dataclass)Any)	Extension)RequestContextc                   D     e Zd ZdZddedeeef         dz  f fdZ xZS )AuthenticationErrorz!Raised when authentication fails.Nreasonheadersc                 p    || _         |pi | _        t                                          d|            d S )NzAuthentication failed: )r   r   super__init__)selfr   r   	__class__s      g/home/rurouni/.hermes/hermes-agent/venv/lib/python3.11/site-packages/hindsight_api/extensions/tenant.pyr   zAuthenticationError.__init__   s<    }";6;;<<<<<    )N)__name__
__module____qualname____doc__strdictr   __classcell__)r   s   @r   r
   r
      sc        ++= =s =T#s(^d-B = = = = = = = = = =r   r
   c                       e Zd ZU dZeed<   dS )TenantContextz
    Tenant context returned by authentication.

    Contains the PostgreSQL schema name for tenant isolation.
    All database queries will use fully-qualified table names
    with this schema (e.g., schema_name.memory_units).
    schema_nameNr   r   r   r   r   __annotations__ r   r   r   r      s*           r   r   c                       e Zd ZU dZeed<   dS )Tenantz
    Represents a tenant for worker discovery.

    Used by list_tenants() to return tenant information including
    the PostgreSQL schema name for database operations.
    schemaNr   r    r   r   r"   r"   !   s%           KKKKKr   r"   c                       e Zd ZdZededefd            Zedee	         fd            Z
dedeeef         fdZdededee         dz  fd	Zdedefd
ZdS )TenantExtensiona  
    Extension for multi-tenancy and API key authentication.

    This extension validates incoming requests and returns the tenant context
    including the PostgreSQL schema to use for database operations.

    Built-in implementation:
        hindsight_api.extensions.builtin.tenant.ApiKeyTenantExtension

    Enable via environment variable:
        HINDSIGHT_API_TENANT_EXTENSION=hindsight_api.extensions.builtin.tenant:ApiKeyTenantExtension
        HINDSIGHT_API_TENANT_API_KEY=your-secret-key

    The returned schema_name is used for fully-qualified table names in queries,
    enabling tenant isolation at the database level.
    contextreturnc                 
   K   dS )aP  
        Authenticate the action context and return tenant context.

        Args:
            context: The action context containing API key and other auth data.

        Returns:
            TenantContext with the schema_name for database operations.

        Raises:
            AuthenticationError: If authentication fails.
        Nr    r   r&   s     r   authenticatezTenantExtension.authenticate?   s       	r   c                 
   K   dS )a  
        List all tenants that should be processed by workers.

        This method is used by the worker to discover all tenants that need
        task polling. Workers will poll for pending tasks in each tenant's schema.

        Returns:
            List of Tenant objects containing schema information.
            For single-tenant setups, return [Tenant(schema="public")].
        Nr    )r   s    r   list_tenantszTenantExtension.list_tenantsO   s       	r   c                 
   K   i S )a,  
        Get tenant-specific configuration overrides.

        This method is called during hierarchical configuration resolution to get
        tenant-level config overrides. The returned dict should contain Python field
        names (lowercase snake_case) as keys, not environment variable names.

        Example:
            {"llm_model": "gpt-4", "retain_extraction_mode": "verbose"}

        The default implementation returns an empty dict (no tenant-specific config).
        Override this method in custom extensions to provide tenant-specific configuration.

        Args:
            context: The request context containing tenant information.

        Returns:
            Dict of config field names to values (only configurable fields).
            Empty dict if no tenant-specific config.
        r    r)   s     r   get_tenant_configz!TenantExtension.get_tenant_config]   s      * 	r   bank_idNc                 
   K   dS )a  
        Get set of config fields that this tenant/bank is allowed to modify.

        This method controls which configurable fields can be modified via the bank config API.
        It enables fine-grained permission control per tenant or per bank.

        Examples:
            - Return None: Allow all configurable fields (default)
            - Return {"retain_chunk_size", "retain_custom_instructions"}: Allow only these fields
            - Return set(): Allow no modifications (read-only)

        The default implementation returns None (all configurable fields allowed).
        Override this method in custom extensions to implement custom permission logic.

        Args:
            context: The request context containing tenant information.
            bank_id: The bank identifier for per-bank permissions.

        Returns:
            Set of allowed field names, or None to allow all configurable fields.
            Returned fields must be a subset of HindsightConfig.get_configurable_fields().
        Nr    )r   r&   r/   s      r   get_allowed_config_fieldsz)TenantExtension.get_allowed_config_fieldst   s      . tr   c                 <   K   |                      |           d{V S )a  
        Authenticate MCP requests.

        By default, this calls authenticate(). Override this method to provide
        different authentication behavior for MCP endpoints (e.g., to disable
        auth for backwards compatibility with existing MCP servers).

        Args:
            context: The action context containing API key and other auth data.

        Returns:
            TenantContext with the schema_name for database operations.

        Raises:
            AuthenticationError: If authentication fails.
        N)r*   r)   s     r   authenticate_mcpz TenantExtension.authenticate_mcp   s.      " &&w/////////r   )r   r   r   r   r   r   r   r*   listr"   r,   r   r   r   r.   setr1   r3   r    r   r   r%   r%   -   s         " . ]    ^ DL    ^~ $sCx.    .~ PS X[\_X`cgXg    20n 0 0 0 0 0 0 0r   r%   N)r   abcr   r   dataclassesr   typingr   hindsight_api.extensions.baser   hindsight_api.modelsr   	Exceptionr
   r   r"   r%   r    r   r   <module>r<      s=   D D # # # # # # # # ! ! ! ! ! !       3 3 3 3 3 3 / / / / / /= = = = =) = = = 	 	 	 	 	 	 	 	        q0 q0 q0 q0 q0i q0 q0 q0 q0 q0r   