def check_access(*args: Any, **kwargs: Any) -> Callable[..., Any]:
    """Check the source ip, authorization header, or client certificates.

    .. note::
        The actual logic to check access is implemented through :func:`RestApiServer.check_access`.

        Optionally it is possible to skip source ip check by specifying ``allowlist_check_members=False``.

    :returns: a decorator that executes *func* only if :func:`RestApiServer.check_access` returns ``True``.

    :Example:

        >>> class FooServer:
        ...   def check_access(self, *args, **kwargs):
        ...     print(f'In FooServer: {args[0].__class__.__name__}')
        ...     return True
        ...

        >>> class Foo:
        ...   server = FooServer()
        ...   @check_access
        ...   def do_PUT_foo(self):
        ...      print('In do_PUT_foo')
        ...   @check_access(allowlist_check_members=False)
        ...   def do_POST_bar(self):
        ...      print('In do_POST_bar')

        >>> f = Foo()
        >>> f.do_PUT_foo()
        In FooServer: Foo
        In do_PUT_foo
    """
    allowlist_check_members = kwargs.get('allowlist_check_members', True)

    def inner_decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        def wrapper(self: 'RestApiHandler', *args: Any, **kwargs: Any) -> Any:
            if self.server.check_access(self, allowlist_check_members=allowlist_check_members):
                return func(self, *args, **kwargs)

        return wrapper

    # A hacky way to have decorators that work with and without parameters.
    if len(args) == 1 and callable(args[0]):
        # The first parameter is a function, it means decorator is used as "@check_access"
        return inner_decorator(args[0])
    else:
        # @check_access(allowlist_check_members=False) case
        return inner_decorator
Check the source ip, authorization header, or client certificates.

    .. note::
        The actual logic to check access is implemented through :func:`RestApiServer.check_access`.

        Optionally it is possible to skip source ip check by specifying ``allowlist_check_members=False``.

    :returns: a decorator that executes *func* only if :func:`RestApiServer.check_access` returns ``True``.

    :Example:

        >>> class FooServer:
        ...   def check_access(self, *args, **kwargs):
        ...     print(f'In FooServer: {args[0].__class__.__name__}')
        ...     return True
        ...

        >>> class Foo:
        ...   server = FooServer()
        ...   @check_access
        ...   def do_PUT_foo(self):
        ...      print('In do_PUT_foo')
        ...   @check_access(allowlist_check_members=False)
        ...   def do_POST_bar(self):
        ...      print('In do_POST_bar')

        >>> f = Foo()
        >>> f.do_PUT_foo()
        In FooServer: Foo
        In do_PUT_foo
    
patroni/api.py