예제 #1
0
def test_basic_local_asyncio():
    ns = local.Local()
    ns.foo = 0
    values = []

    async def value_setter(idx):
        await asyncio.sleep(0.01 * idx)
        ns.foo = idx
        await asyncio.sleep(0.02)
        values.append(ns.foo)

    async def main():
        futures = [asyncio.ensure_future(value_setter(i)) for i in [1, 2, 3]]
        await asyncio.gather(*futures)

    asyncio.run(main())
    assert sorted(values) == [1, 2, 3]

    def delfoo():
        del ns.foo

    delfoo()
    pytest.raises(AttributeError, lambda: ns.foo)
    pytest.raises(AttributeError, delfoo)

    local.release_local(ns)
예제 #2
0
def test_basic_local():
    l = local.Local()
    l.foo = 0
    values = []

    def value_setter(idx):
        time.sleep(0.01 * idx)
        l.foo = idx
        time.sleep(0.02)
        values.append(l.foo)

    threads = [Thread(target=value_setter, args=(x, )) for x in [1, 2, 3]]
    for thread in threads:
        thread.start()
    time.sleep(0.2)
    assert sorted(values) == [1, 2, 3]

    def delfoo():
        del l.foo

    delfoo()
    pytest.raises(AttributeError, lambda: l.foo)
    pytest.raises(AttributeError, delfoo)

    local.release_local(l)
예제 #3
0
    def __init__(
            self,
            # The Flask application to analyze
            app: Flask,
            # The HowFast app ID to use
            app_id: str = None,
            # Endpoints not to monitor
            endpoints_blacklist: List[str] = None,
            # Other configuration parameters passed to the CoreAPM constructor
            **kwargs,
    ):
        super().__init__(**kwargs)

        self.app = app
        self.wsgi_app = app.wsgi_app

        # We need to store thread local information, let's use Werkzeug's context locals
        # (see https://werkzeug.palletsprojects.com/en/1.0.x/local/)
        self.local = local.Local()
        self.local_manager = local.LocalManager([self.local])

        # Overwrite the passed WSGI application
        app.wsgi_app = self.local_manager.make_middleware(self)

        if endpoints_blacklist:
            self.endpoints_blacklist = compile_endpoints(*endpoints_blacklist)
        else:
            self.endpoints_blacklist = []

        # Setup the queue and the background thread
        self.setup(app_id)

        request_started.connect(self._request_started)
예제 #4
0
def test_local_release():
    l = local.Local()
    l.foo = 42
    local.release_local(l)
    assert not hasattr(l, 'foo')

    ls = local.LocalStack()
    ls.push(42)
    local.release_local(ls)
    assert ls.top is None
예제 #5
0
    def test_local_release(self):
        loc = local.Local()
        loc.foo = 42
        local.release_local(loc)
        assert not hasattr(loc, 'foo')

        ls = local.LocalStack()
        ls.push(42)
        local.release_local(ls)
        assert ls.top is None
예제 #6
0
def test_local_release():
    ns = local.Local()
    ns.foo = 42
    local.release_local(ns)
    assert not hasattr(ns, "foo")

    ls = local.LocalStack()
    ls.push(42)
    local.release_local(ls)
    assert ls.top is None
예제 #7
0
def test_proxy_local():
    ns = local.Local()
    ns.foo = []
    p = local.LocalProxy(ns, "foo")
    p.append(42)
    p.append(23)
    p[1:] = [1, 2, 3]
    assert p == [42, 1, 2, 3]
    assert p == ns.foo
    ns.foo += [1]
    assert list(p) == [42, 1, 2, 3, 1]
    p_from_local = ns("foo")
    p_from_local.append(2)
    assert p == p_from_local
    assert p._get_current_object() is ns.foo
예제 #8
0
def test_proxy_wrapped():
    class SomeClassWithWrapped:
        __wrapped__ = "wrapped"

    def lookup_func():
        return 42

    proxy = local.LocalProxy(lookup_func)
    assert proxy.__wrapped__ is lookup_func

    partial_lookup_func = partial(lookup_func)
    partial_proxy = local.LocalProxy(partial_lookup_func)
    assert partial_proxy.__wrapped__ == partial_lookup_func

    ns = local.Local()
    ns.foo = SomeClassWithWrapped()
    ns.bar = 42

    assert ns("foo").__wrapped__ == "wrapped"
    pytest.raises(AttributeError, lambda: ns("bar").__wrapped__)
예제 #9
0
def test_custom_idents():
    ident = 0
    l = local.Local()
    stack = local.LocalStack()
    local.LocalManager([l, stack], ident_func=lambda: ident)

    l.foo = 42
    stack.push({'foo': 42})
    ident = 1
    l.foo = 23
    stack.push({'foo': 23})
    ident = 0
    assert l.foo == 42
    assert stack.top['foo'] == 42
    stack.pop()
    assert stack.top is None
    ident = 1
    assert l.foo == 23
    assert stack.top['foo'] == 23
    stack.pop()
    assert stack.top is None
예제 #10
0
def test_local_proxy_wrapped_attribute():
    class SomeClassWithWrapped(object):
        __wrapped__ = 'wrapped'

    def lookup_func():
        return 42

    partial_lookup_func = partial(lookup_func)

    proxy = local.LocalProxy(lookup_func)
    assert proxy.__wrapped__ is lookup_func

    partial_proxy = local.LocalProxy(partial_lookup_func)
    assert partial_proxy.__wrapped__ == partial_lookup_func

    l = local.Local()
    l.foo = SomeClassWithWrapped()
    l.bar = 42

    assert l('foo').__wrapped__ == 'wrapped'
    pytest.raises(AttributeError, lambda: l('bar').__wrapped__)
예제 #11
0
def test_custom_idents():
    ident = 0
    ns = local.Local()
    stack = local.LocalStack()
    local.LocalManager([ns, stack], ident_func=lambda: ident)

    ns.foo = 42
    stack.push({"foo": 42})
    ident = 1
    ns.foo = 23
    stack.push({"foo": 23})
    ident = 0
    assert ns.foo == 42
    assert stack.top["foo"] == 42
    stack.pop()
    assert stack.top is None
    ident = 1
    assert ns.foo == 23
    assert stack.top["foo"] == 23
    stack.pop()
    assert stack.top is None
예제 #12
0
def test_basic_local_asyncio():
    ns = local.Local()
    ns.foo = 0
    values = []

    async def value_setter(idx):
        await asyncio.sleep(0.01 * idx)
        ns.foo = idx
        await asyncio.sleep(0.02)
        values.append(ns.foo)

    loop = asyncio.get_event_loop()
    futures = [asyncio.ensure_future(value_setter(idx)) for idx in [1, 2, 3]]
    loop.run_until_complete(asyncio.gather(*futures))
    assert sorted(values) == [1, 2, 3]

    def delfoo():
        del ns.foo

    delfoo()
    pytest.raises(AttributeError, lambda: ns.foo)
    pytest.raises(AttributeError, delfoo)

    local.release_local(ns)
예제 #13
0
class SpnegoAuth:
    """SPNEGO authentication implementation."""

    LOCALS = local.Local()

    def __init__(self, wrapped,
                 protected_paths=(), unprotected_paths=(),
                 unprotected_methods=(),
                 unprotected_is_regex=False):
        """
        :param protected_paths:
            Provide a list of path for which this module should enforce auth
            (e.g. '/login')
        :param wad_cnx_settings:
            Tuple connection settings the WebAuthD daemon (e.g. ('inet',
            [port]) or ('unix', [path]))
        :param unprotected_is_regex:
            Whether unprotected_paths parameter contains regexes (default:
            False)
        """
        self._wrapped = wrapped

        # build a re like this '^(/path1(/.*)?|/path2(/.*)?|/path3(/.*)?)$'
        # Note that empty protected_paths matches *EVERY* paths
        self.protected_paths_re = re.compile(
            r'^(:?' +
            r'(:?/.*)?|'.join(protected_paths) +
            r'(:?/.*)?)$'
        )

        if unprotected_paths:
            if not unprotected_is_regex:
                unprotected_paths = [
                    path + '(:?/.*)?' for path in unprotected_paths
                ]
            self.unprotected_paths_re = re.compile(
                r'^(:?' +
                r'|'.join(unprotected_paths) +
                r')$'
            )
        else:
            self.unprotected_paths_re = None

        self.unprotected_methods = unprotected_methods

        # Print WebAuthD version for information
        _LOGGER.info('Protecting paths: %r',
                     self.protected_paths_re.pattern)
        _LOGGER.info('Unprotecting paths: %r',
                     (self.unprotected_paths_re.pattern
                      if self.unprotected_paths_re is not None
                      else None))
        _LOGGER.info('Unprotecting methods: %r', self.unprotected_methods)

    def _wrapped_authenticated(self, auth_user, auth_token=None):

        def _wrapped(environ, start_response):
            environ['REMOTE_USER'] = auth_user

            # TODO: when is auth token every none?
            if auth_token:
                def spnego_start_response(status, headers, exc_info=None):
                    """Initial spnego response."""
                    headers.append(
                        ('WWW-Authenticate', 'Negotiate %s' % auth_token)
                    )
                    return start_response(status, headers, exc_info)
            else:
                spnego_start_response = start_response

            return self._wrapped(environ, spnego_start_response)

        return _wrapped

    def _auth_spnego(self, request):
        """Perform SPNEGO authentication.
        """
        if 'Authorization' not in request.headers:
            # Send the SPNEGO Negociate challenge
            _LOGGER.debug("Sending SPNEGO Negotiate request")
            resp = BaseResponse(status=401)
            resp.headers['WWW-Authenticate'] = 'Negotiate'
            return resp

        # We have authorization headers
        auth_type, auth_chal = request.headers['Authorization'].split(' ', 3)
        if auth_type != 'Negotiate':
            return _UNAUTHORIZED('Invalid authorization header.')

        _LOGGER.debug("Received SPNEGO Negociate token: %r", auth_chal)
        try:
            if not hasattr(self.LOCALS, 'ctx'):
                # pylint: disable=assigning-non-slot
                self.LOCALS.ctx = gssapi.SecurityContext(
                    creds=None, usage='accept'
                )
                _LOGGER.debug('Init security context.')

            in_token = base64.standard_b64decode(auth_chal)
            out_token = self.LOCALS.ctx.step(in_token)
            auth_token = base64.b64encode(out_token)

            if not self.LOCALS.ctx.complete:
                _LOGGER.debug("Sending SPNEGO Negotiate (continue).")
                resp = BaseResponse(status=401)
                resp.headers['WWW-Authenticate'] = 'Negotiate %s' % auth_token
                return resp

            # GSSAPI negotiation completed.
            auth_user = str(self.LOCALS.ctx.initiator_name)
            _LOGGER.info('Authenticated user: %s', auth_user)

            return self._wrapped_authenticated(auth_user, auth_token)

        # pylint: disable=c-extension-no-member
        except gssapi.raw.misc.GSSError as err:
            _LOGGER.warning('Unhandled exception: %s', str(err))
            return _UNAUTHORIZED(str(err))

    def wsgi_app(self, environ, start_response):
        """WSGI middleware main entry point.
        """
        request = BaseRequest(environ)

        if request.method in self.unprotected_methods:
            return self._wrapped(environ, start_response)

        if not self.protected_paths_re.match(request.path):
            return self._wrapped(environ, start_response)

        if (self.unprotected_paths_re is not None and
                self.unprotected_paths_re.match(request.path)):
            return self._wrapped(environ, start_response)

        _LOGGER.info('Authenticating access to %s', request.path)
        app = self._auth_spnego(request)
        return app(environ, start_response)

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)
예제 #14
0
def _make_proxy(value):
    ns = local.Local()
    ns.value = value
    p = ns("value")
    return ns, p
예제 #15
0
def test_proxy_unbound():
    ns = local.Local()
    p = ns("value")
    assert repr(p) == "<LocalProxy unbound>"
    assert not p
    assert dir(p) == []
예제 #16
0
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Date    : 2017/10/17 16:14
# @Author  : xxc727xxc ([email protected])
# @Version : 1.0.0

import asyncio
import functools
import logging

import aiomysql
from werkzeug import local

logger = logging.getLogger(__name__)
conn_local = local.Local()


def log(sql, args=()):
    logger.debug('SQL: %s  args: %s' % (sql, args))


def get_transaction():
    return _DBTransaction(__pool)


@asyncio.coroutine
def create_pool(loop: asyncio.AbstractEventLoop, **kw):
    logger.info('create database connection pool...')
    global __pool
    __pool = yield from aiomysql.create_pool(host=kw.get('host', 'localhost'),
                                             port=kw.get('port', 3306),