
    $jN,                        d Z ddlmZ ddlZddlmZ ddlmZ ddl	m
Z
 ddlmZmZ ddlmZmZ ddlmZ dd	lmZmZmZ dd
lmZ ddlmZmZmZ ddlmZmZ  ej         e!          Z" G d de          Z#dS )a  Authorization middleware for FastMCP.

This module provides middleware-based authorization using callable auth checks.
AuthMiddleware applies auth checks globally to all components on the server.

Example:
    ```python
    from fastmcp import FastMCP
    from fastmcp.server.auth import require_scopes, restrict_tag
    from fastmcp.server.middleware import AuthMiddleware

    # Require specific scope for all components
    mcp = FastMCP(middleware=[
        AuthMiddleware(auth=require_scopes("api"))
    ])

    # Tag-based: components tagged "admin" require "admin" scope
    mcp = FastMCP(middleware=[
        AuthMiddleware(auth=restrict_tag("admin", scopes=["admin"]))
    ])
    ```
    )annotationsN)Sequence)AuthorizationError)PromptPromptResult)ResourceResourceResult)ResourceTemplate)	AuthCheckAuthContextrun_auth_checks)get_access_token)CallNext
MiddlewareMiddlewareContext)Tool
ToolResultc                  R    e Zd ZdZd&dZd'dZd(dZd)dZd*dZd+dZ	d,d Z
d-d$Zd%S ).AuthMiddlewarea  Global authorization middleware using callable checks.

    This middleware applies auth checks to all components (tools, resources,
    prompts) on the server. It uses the same callable API as component-level
    auth checks.

    The middleware:
    - Filters tools/resources/prompts from list responses based on auth checks
    - Checks auth before tool execution, resource read, and prompt render
    - Skips all auth checks for STDIO transport (no OAuth concept)

    Args:
        auth: A single auth check function or list of check functions.
            All checks must pass for authorization to succeed (AND logic).

    Example:
        ```python
        from fastmcp import FastMCP
        from fastmcp.server.auth import require_scopes

        # Require specific scope for all components
        mcp = FastMCP(middleware=[AuthMiddleware(auth=require_scopes("api"))])

        # Multiple scopes (AND logic)
        mcp = FastMCP(middleware=[
            AuthMiddleware(auth=require_scopes("read", "api"))
        ])
        ```
    authAuthCheck | list[AuthCheck]returnNonec                    || _         d S )N)r   )selfr   s     o/home/rurouni/.hermes/hermes-agent/venv/lib/python3.11/site-packages/fastmcp/server/middleware/authorization.py__init__zAuthMiddleware.__init__R   s    			    context&MiddlewareContext[mt.ListToolsRequest]	call_next-CallNext[mt.ListToolsRequest, Sequence[Tool]]Sequence[Tool]c                :  K    ||           d{V }ddl m} |                                dk    r|S t                      }g }|D ]T}t	          ||          }	 t          | j        |           d{V r|                    |           E# t          $ r Y Qw xY w|S )z0Filter tools/list response based on auth checks.Nr   _current_transportstdiotoken	component	fastmcp.server.contextr&   getr   r   r   r   appendr   )	r   r   r!   toolsr&   r)   authorized_toolstoolctxs	            r   on_list_toolszAuthMiddleware.on_list_toolsU   s        i(((((((( 	>=====!!##w..L ""') 	 	DET:::C(C88888888 2$++D111%        0B
BB+MiddlewareContext[mt.CallToolRequestParams].CallNext[mt.CallToolRequestParams, ToolResult]r   c                  K   ddl m} |                                dk    r ||           d{V S |j        j        }|j        }|1t                              d| d           t          d| d          |j	        
                    |           d{V }|t          d| d	          t                      }t          ||
          }t          | j        |           d{V st          d| d           ||           d{V S )z!Check auth before tool execution.r   r%   r'   Nz2AuthMiddleware: fastmcp_context is None for tool ''. Denying access for security.zAuthorization failed for tool '': missing contextz': tool not foundr(   ': insufficient permissions)r,   r&   r-   messagenamefastmcp_contextloggerwarningr   fastmcpget_toolr   r   r   r   )	r   r   r!   r&   	tool_namer@   r1   r)   r2   s	            r   on_call_toolzAuthMiddleware.on_call_toolq   s      	>=====!!##w.."7+++++++++ O(	)?NN/Y / / /   %O)OOO  
 _--i88888888<$N)NNN  
 !""666$TY44444444 	$X)XXX   Yw'''''''''r   *MiddlewareContext[mt.ListResourcesRequest]5CallNext[mt.ListResourcesRequest, Sequence[Resource]]Sequence[Resource]c                :  K    ||           d{V }ddl m} |                                dk    r|S t                      }g }|D ]T}t	          ||          }	 t          | j        |           d{V r|                    |           E# t          $ r Y Qw xY w|S )z4Filter resources/list response based on auth checks.Nr   r%   r'   r(   r+   )	r   r   r!   	resourcesr&   r)   authorized_resourcesresourcer2   s	            r   on_list_resourcesz AuthMiddleware.on_list_resources   s       $)G,,,,,,,,	 	>=====!!##w.. ""/1! 	 	HEX>>>C(C88888888 :(//999%    $#r4   /MiddlewareContext[mt.ReadResourceRequestParams]6CallNext[mt.ReadResourceRequestParams, ResourceResult]r	   c                  K   ddl m} |                                dk    r ||           d{V S |j        j        }|j        }|1t                              d| d           t          d| d          |j	        
                    t          |                     d{V }|-|j	                            t          |                     d{V }|t          d| d	          t                      }t          ||
          }t          | j        |           d{V st          d| d           ||           d{V S )z Check auth before resource read.r   r%   r'   Nz6AuthMiddleware: fastmcp_context is None for resource 'r8   z#Authorization failed for resource 'r9   z': resource not foundr(   r:   )r,   r&   r-   r;   urir=   r>   r?   r   r@   get_resourcestrget_resource_templater   r   r   r   )	r   r   r!   r&   rO   r@   r*   r)   r2   s	            r   on_read_resourcezAuthMiddleware.on_read_resource   s      	>=====!!##w.."7+++++++++ o!)?NN/ / / /   %McMMM  
 "/66s3xx@@@@@@@@	%oCCCHHMMMMMMMMI$PcPPP  
 !"";;;$TY44444444 	$VcVVV   Yw'''''''''r   2MiddlewareContext[mt.ListResourceTemplatesRequest]ECallNext[mt.ListResourceTemplatesRequest, Sequence[ResourceTemplate]]Sequence[ResourceTemplate]c                :  K    ||           d{V }ddl m} |                                dk    r|S t                      }g }|D ]T}t	          ||          }	 t          | j        |           d{V r|                    |           E# t          $ r Y Qw xY w|S )z=Filter resource templates/list response based on auth checks.Nr   r%   r'   r(   r+   )	r   r   r!   	templatesr&   r)   authorized_templatestemplater2   s	            r   on_list_resource_templatesz)AuthMiddleware.on_list_resource_templates   s       $)G,,,,,,,,	 	>=====!!##w.. ""79! 	 	HEX>>>C(C88888888 :(//999%    $#r4   (MiddlewareContext[mt.ListPromptsRequest]1CallNext[mt.ListPromptsRequest, Sequence[Prompt]]Sequence[Prompt]c                :  K    ||           d{V }ddl m} |                                dk    r|S t                      }g }|D ]T}t	          ||          }	 t          | j        |           d{V r|                    |           E# t          $ r Y Qw xY w|S )z2Filter prompts/list response based on auth checks.Nr   r%   r'   r(   r+   )	r   r   r!   promptsr&   r)   authorized_promptspromptr2   s	            r   on_list_promptszAuthMiddleware.on_list_prompts   s       "	'******** 	>=====!!##w..N ""+- 	 	FEV<<<C(C88888888 6&--f555%    "!r4   ,MiddlewareContext[mt.GetPromptRequestParams]1CallNext[mt.GetPromptRequestParams, PromptResult]r   c                  K   ddl m} |                                dk    r ||           d{V S |j        j        }|j        }|1t                              d| d           t          d| d          |j	        
                    |           d{V }|t          d| d	          t                      }t          ||
          }t          | j        |           d{V st          d| d           ||           d{V S )z Check auth before prompt render.r   r%   r'   Nz4AuthMiddleware: fastmcp_context is None for prompt 'r8   z!Authorization failed for prompt 'r9   z': prompt not foundr(   r:   )r,   r&   r-   r;   r<   r=   r>   r?   r   r@   
get_promptr   r   r   r   )	r   r   r!   r&   prompt_namer@   rb   r)   r2   s	            r   on_get_promptzAuthMiddleware.on_get_prompt  s      	>=====!!##w.."7+++++++++ o*)?NN/{ / / /   %SKSSS  
 11+>>>>>>>>>$TKTTT  
 !""888$TY44444444 	$\K\\\   Yw'''''''''r   N)r   r   r   r   )r   r    r!   r"   r   r#   )r   r5   r!   r6   r   r   )r   rD   r!   rE   r   rF   )r   rL   r!   rM   r   r	   )r   rT   r!   rU   r   rV   )r   r\   r!   r]   r   r^   )r   rd   r!   re   r   r   )__name__
__module____qualname____doc__r   r3   rC   rK   rS   r[   rc   ri    r   r   r   r   3   s         <          8)( )( )( )(V$ $ $ $6)( )( )( )(V$ $ $ $:" " " "6'( '( '( '( '( '(r   r   )$rm   
__future__r   loggingcollections.abcr   	mcp.typestypesmtfastmcp.exceptionsr   fastmcp.prompts.baser   r   fastmcp.resources.baser   r	   fastmcp.resources.templater
   !fastmcp.server.auth.authorizationr   r   r   fastmcp.server.dependenciesr   $fastmcp.server.middleware.middlewarer   r   r   fastmcp.tools.baser   r   	getLoggerrj   r>   r   rn   r   r   <module>r~      s   . # " " " " "  $ $ $ $ $ $       1 1 1 1 1 1 5 5 5 5 5 5 5 5 ; ; ; ; ; ; ; ; 7 7 7 7 7 7         
 9 8 8 8 8 8         
 0 / / / / / / /		8	$	$N( N( N( N( N(Z N( N( N( N( N(r   