Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions connexion/apis/sanic_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@
from contextlib import suppress
from http import HTTPStatus
from re import findall
from urllib.parse import parse_qs

import sanic
from sanic import Blueprint
from sanic.exceptions import NotFound as HTTPNotFound
from sanic.request import Request
from sanic.response import HTTPResponse, json, redirect, text
from sanic.response import HTTPResponse, redirect, text

from connexion.apis.abstract import AbstractAPI
from connexion.exceptions import ProblemException
from connexion.security import SanicSecurityHandlerFactory
from connexion.handlers import AuthErrorHandler
from connexion.jsonifier import JSONEncoder, Jsonifier
from connexion.lifecycle import ConnexionRequest, ConnexionResponse
Expand Down Expand Up @@ -78,6 +77,11 @@ class SanicApi(AbstractAPI):
def __init__(self, *args, **kwargs):
AbstractAPI.__init__(self, *args, **kwargs)

@staticmethod
def make_security_handler_factory(pass_context_arg_name):
""" Create default SecurityHandlerFactory to create all security check handlers """
return SanicSecurityHandlerFactory(pass_context_arg_name)

def _set_base_path(self, base_path):
AbstractAPI._set_base_path(self, base_path)
self._api_name = SanicApi.normalize_string(self.base_path)
Expand Down
2 changes: 2 additions & 0 deletions connexion/security/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
# concrete
from .flask_security_handler_factory import FlaskSecurityHandlerFactory # NOQA
from .aiohttp_security_handler_factory import AioHttpSecurityHandlerFactory # NOQA

from .sanic_security_handler_factory import SanicSecurityHandlerFactory # NOQA
2 changes: 0 additions & 2 deletions connexion/security/async_security_handler_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
import functools
import logging

import aiohttp

from ..exceptions import OAuthProblem, OAuthResponseProblem, OAuthScopeProblem
from .security_handler_factory import AbstractSecurityHandlerFactory

Expand Down
38 changes: 38 additions & 0 deletions connexion/security/sanic_security_handler_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import logging

import httpx

from .async_security_handler_factory import AbstractAsyncSecurityHandlerFactory

logger = logging.getLogger("connexion.api.security")


class SanicSecurityHandlerFactory(AbstractAsyncSecurityHandlerFactory):
def __init__(self, pass_context_arg_name):
super(SanicSecurityHandlerFactory, self).__init__(
pass_context_arg_name=pass_context_arg_name
)

def get_token_info_remote(self, token_info_url):
"""
Return a function which will call `token_info_url` to retrieve token info.

Returned function must accept oauth token in parameter.
It must return a token_info dict in case of success, None otherwise.

:param token_info_url: Url to get information about the token
:type token_info_url: str
:rtype: types.FunctionType
"""

async def wrapper(token):
async with httpx.AsyncClient() as client:
headers = {"Authorization": "Bearer {}".format(token)}
token_request = await client.get(
token_info_url, headers=headers, timeout=5
)
if token_request.status_code != 200:
return None
return token_request.json()

return wrapper
1 change: 1 addition & 0 deletions requirements-sanic.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
sanic>=20.3.0
httpx>=0.16.1