def _get_authorization_header( credentials: AppConnectCredentials, expiry_sec: Optional[int] = None) -> Mapping[str, str]: """Creates a JWT (javascript web token) for use with app store connect API All requests to app store connect require an "Authorization" header build as below. Note: The maximum allowed expiry time is 20 minutes. The default is somewhat shorter than that to avoid running into the limit. :return: the Bearer auth token to be added as the "Authorization" header """ if expiry_sec is None: expiry_sec = 60 * 10 # default to 10 mins with sentry_sdk.start_span( op="jwt", description="Generating AppStoreConnect JWT token"): token = jwt.encode( { "iss": credentials.issuer_id, "exp": int(time.time()) + expiry_sec, "aud": "appstoreconnect-v1", }, credentials.key, algorithm="ES256", headers={ "kid": credentials.key_id, "alg": "ES256", "typ": "JWT" }, ) return jwt.authorization_header(token)
def create_token(self): headers = { # TODO(jess): remove this whenever it's out of preview "Accept": "application/vnd.github.machine-man-preview+json", } headers.update(jwt.authorization_header(self.get_jwt())) return self.post( f"/app/installations/{self.integration.external_id}/access_tokens", headers=headers, )
def request(self, method, path, data=None, params=None, **kwargs): jwt_payload = { "iss": BITBUCKET_KEY, "iat": datetime.datetime.utcnow(), "exp": datetime.datetime.utcnow() + datetime.timedelta(seconds=5 * 60), "qsh": get_query_hash(path, method.upper(), params), "sub": self.subject, } encoded_jwt = jwt.encode(jwt_payload, self.shared_secret) headers = jwt.authorization_header(encoded_jwt, scheme="JWT") return self._request(method, path, data=data, params=params, headers=headers, **kwargs)
def get_installation_info(self, installation_id: str) -> Mapping[str, Any]: client = self.get_client() headers = { # TODO(jess): remove this whenever it's out of preview "Accept": "application/vnd.github.machine-man-preview+json", } headers.update(jwt.authorization_header(get_jwt())) resp: Mapping[str, Any] = client.get( f"/app/installations/{installation_id}", headers=headers) return resp
def get_installation_info(self, installation_id): headers = { # TODO(jess): remove this whenever it's out of preview "Accept": "application/vnd.github.machine-man-preview+json", } headers.update(jwt.authorization_header(get_jwt())) with http.build_session() as session: resp = session.get( f"https://api.github.com/app/installations/{installation_id}", headers=headers) resp.raise_for_status() installation_resp = resp.json() return installation_resp
def get_installation_info(self, installation_data, access_token, installation_id): headers = { # TODO(jess): remove this whenever it's out of preview "Accept": "application/vnd.github.machine-man-preview+json", } headers.update( jwt.authorization_header( get_jwt( github_id=installation_data["id"], github_private_key=installation_data["private_key"], ) ) ) with http.build_session() as session: resp = session.get( f"https://{installation_data['url']}/api/v3/app/installations/{installation_id}", headers=headers, verify=installation_data["verify_ssl"], ) resp.raise_for_status() installation_resp = resp.json() resp = session.get( f"https://{installation_data['url']}/api/v3/user/installations", headers={ "Accept": "application/vnd.github.machine-man-preview+json", "Authorization": f"token {access_token}", }, verify=installation_data["verify_ssl"], ) resp.raise_for_status() user_installations_resp = resp.json() # verify that user actually has access to the installation for installation in user_installations_resp["installations"]: if installation["id"] == installation_resp["id"]: return installation_resp return None
def test_authorization_header(token: str) -> None: header = jwt_utils.authorization_header(token) assert header == {"Authorization": f"Bearer {token}"} header = jwt_utils.authorization_header(token, scheme="JWT") assert header == {"Authorization": f"JWT {token}"}