# -*- coding:utf-8 -*- import json from functools import partial import requests from jinja2 import Template from requests.auth import HTTPBasicAuth from requests_oauthlib import OAuth2Session class BearerAuth(requests.auth.AuthBase): def __init__(self, token): self.token = token def __call__(self, r): r.headers["authorization"] = "Bearer {}".format(self.token) return r def _wrap_auth(**kwargs): auth_type = (kwargs.get('type') or "").lower() if auth_type == "basicauth": return HTTPBasicAuth(kwargs.get('username'), kwargs.get('password')) elif auth_type == "bearer": return BearerAuth(kwargs.get('token')) elif auth_type == 'oauth2.0': client_id = kwargs.get('client_id') client_secret = kwargs.get('client_secret') authorization_base_url = kwargs.get('authorization_base_url') token_url = kwargs.get('token_url') redirect_url = kwargs.get('redirect_url') scope = kwargs.get('scope') oauth2_session = OAuth2Session(client_id, scope=scope or None) oauth2_session.authorization_url(authorization_base_url) oauth2_session.fetch_token(token_url, client_secret=client_secret, authorization_response=redirect_url) return oauth2_session elif auth_type == "apikey": return HTTPBasicAuth(kwargs.get('key'), kwargs.get('value')) def webhook_request(webhook, payload): """ :param webhook: { "url": "https://veops.cn" "method": "GET|POST|PUT|DELETE" "body": {}, "headers": { "Content-Type": "Application/json" }, "parameters": { "key": "value" }, "authorization": { "type": "BasicAuth|Bearer|OAuth2.0|APIKey", "password": "mmmm", # BasicAuth "username": "bbb", # BasicAuth "token": "xxx", # Bearer "key": "xxx", # APIKey "value": "xxx", # APIKey "client_id": "xxx", # OAuth2.0 "client_secret": "xxx", # OAuth2.0 "authorization_base_url": "xxx", # OAuth2.0 "token_url": "xxx", # OAuth2.0 "redirect_url": "xxx", # OAuth2.0 "scope": "xxx" # OAuth2.0 } } :param payload: :return: """ assert webhook.get('url') is not None payload = {k: v or '' for k, v in payload.items()} url = Template(webhook['url']).render(payload) params = webhook.get('parameters') or None if isinstance(params, dict): params = json.loads(Template(json.dumps(params)).render(payload)) headers = json.loads(Template(json.dumps(webhook.get('headers') or {})).render(payload)) data = Template(json.dumps(webhook.get('body', ''))).render(payload) auth = _wrap_auth(**webhook.get('authorization', {})) if (webhook.get('authorization', {}).get("type") or '').lower() == 'oauth2.0': request = getattr(auth, webhook.get('method', 'GET').lower()) else: request = partial(requests.request, webhook.get('method', 'GET')) return request( url, params=params, headers=headers or None, data=data, auth=auth )