def make_api_request(req: Request, access_token: str) -> Request: if req.headers is None: headers = {} else: headers = dict(req.headers).copy() if req.params is None: params = {} else: params = dict(req.params).copy() headers["Authorization"] = f"Bearer {access_token}" data = req.data if data is not None and isinstance(data, dict): data = json.dumps(data).encode("utf8") assert "Content-Type" not in headers headers["Content-Type"] = "application/json" return Request( method=req.method, url=req.url, params=params, headers=headers, data=data, preload_content=req.preload_content, success_codes=tuple(req.success_codes), retry_codes=tuple(req.retry_codes), )
def create_access_token_request( creds: Mapping[str, str], scope: str, success_codes: Sequence[int] = (200, )) -> Request: if "refreshToken" in creds: # https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-protocols-oauth-code#refreshing-the-access-tokens data = { "grant_type": "refresh_token", "refresh_token": creds["refreshToken"], "resource": scope, } tenant = "common" else: # https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-client-creds-grant-flow#request-an-access-token # https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-protocols-oauth-code # https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-azure-active-directory#use-oauth-access-tokens-for-authentication # https://docs.microsoft.com/en-us/rest/api/azure/ # https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-azure-active-directory # az ad sp create-for-rbac --name <name> # az account list # az role assignment create --role "Storage Blob Data Contributor" --assignee <appid> --scope "/subscriptions/<account id>" data = { "grant_type": "client_credentials", "client_id": creds["appId"], "client_secret": creds["password"], "resource": scope, } tenant = creds["tenant"] return Request( url=f"https://login.microsoftonline.com/{tenant}/oauth2/token", method="POST", headers={"Content-Type": "application/x-www-form-urlencoded"}, data=urllib.parse.urlencode(data).encode("utf8"), success_codes=success_codes, )
def create_user_delegation_sas_request(account: str) -> Request: # https://docs.microsoft.com/en-us/rest/api/storageservices/create-user-delegation-sas now = datetime.datetime.utcnow() start = (now + datetime.timedelta(hours=-1)).strftime("%Y-%m-%dT%H:%M:%SZ") expiration = now + datetime.timedelta(days=6) expiry = expiration.strftime("%Y-%m-%dT%H:%M:%SZ") return Request( url=f"https://{account}.blob.core.windows.net/", method="POST", params=dict(restype="service", comp="userdelegationkey"), data={"KeyInfo": {"Start": start, "Expiry": expiry}}, )
def _refresh_access_token_request(client_id: str, client_secret: str, refresh_token: str) -> Request: # https://developers.google.com/identity/protocols/OAuth2WebServer#offline data = { "grant_type": "refresh_token", "refresh_token": refresh_token, "client_id": client_id, "client_secret": client_secret, } return Request( url="https://www.googleapis.com/oauth2/v4/token", method="POST", headers={"Content-Type": "application/x-www-form-urlencoded"}, data=urllib.parse.urlencode(data).encode("utf8"), )
def _create_token_request(client_email: str, private_key: str, scopes: List[str]) -> Request: # https://developers.google.com/identity/protocols/OAuth2ServiceAccount now = time.time() claim_set = { "iss": client_email, "scope": " ".join(scopes), "aud": "https://www.googleapis.com/oauth2/v4/token", "exp": now + 60 * 60, "iat": now, } data = { "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion": _create_jwt(private_key, claim_set), } return Request( url="https://www.googleapis.com/oauth2/v4/token", method="POST", headers={"Content-Type": "application/x-www-form-urlencoded"}, data=urllib.parse.urlencode(data).encode("utf8"), )
def make_api_request(req: Request, auth: Tuple[str, str]) -> Request: if req.headers is None: headers = {} else: headers = dict(req.headers).copy() if req.params is None: params = {} else: params = dict(req.params).copy() # https://docs.microsoft.com/en-us/rest/api/storageservices/previous-azure-storage-service-versions headers["x-ms-version"] = "2019-02-02" headers["x-ms-date"] = datetime.datetime.utcnow().strftime( "%a, %d %b %Y %H:%M:%S GMT" ) data = req.data if data is not None and isinstance(data, dict): data = xmltodict.unparse(data).encode("utf8") result = Request( method=req.method, url=req.url, params=params, headers=headers, data=data, preload_content=req.preload_content, success_codes=tuple(req.success_codes), retry_codes=tuple(req.retry_codes), ) kind, token = auth if kind == SHARED_KEY: # make sure we are signing the request that has the ms headers added already headers["Authorization"] = sign_with_shared_key(result, token) elif kind == OAUTH_TOKEN: headers["Authorization"] = f"Bearer {token}" elif kind == ANONYMOUS: pass return result