示例#1
0
def test_rsa_key_from_jwk() -> None:
    key = jwt_utils.rsa_key_from_jwk(json.dumps(RSA_JWK))
    assert key
    assert isinstance(key, str)

    # The PEM keys are not equal, and by more than just the header and footer ("BEGIN RSA
    # PRIVATE KEY" vs "BEGIN PRIVATE KEY").  There might be some more metadata in there that
    # is not relevant.  However below we assert the generated tokens are identical.
    # assert key == RS256_KEY.lstrip()

    # Ensure we can use the key to create a token
    claims = {"iss": "me"}
    token_from_jwk = jwt_utils.encode(claims, key, algorithm="RS256")
    token = jwt_utils.encode(claims, RS256_KEY, algorithm="RS256")
    assert token_from_jwk == token
示例#2
0
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)
示例#3
0
def test_encode_rs256() -> None:
    headers = {
        "alg": "RS256",
        "typ": "JWT",
    }
    claims = {
        "iss": "me",
    }
    encoded_hs256 = jwt_utils.encode(claims, "secret", headers=headers)
    encoded_rs256 = jwt_utils.encode(claims,
                                     RS256_KEY,
                                     headers=headers,
                                     algorithm="RS256")

    assert encoded_rs256.count(".") == 2
    assert encoded_rs256 != encoded_hs256
示例#4
0
 def get_token(self, issuer, uri, method):
     now = int(time())
     payload = {
         "iss": issuer,
         "iat": now,
         "exp": now + 60 * 60,
         "qsh": get_query_hash(uri, method),
         "aud": issuer,
     }
     return jwt.encode(payload, self.secret, algorithm="HS256")
示例#5
0
 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)
示例#6
0
def test_decode(token: str) -> None:
    claims = jwt_utils.decode(token, "secret")
    assert claims == {"iss": "me"}

    for key, value in claims.items():
        assert isinstance(key, str)
        assert isinstance(value, str)

    claims["aud"] = "you"
    token = jwt_utils.encode(claims, "secret")

    with pytest.raises(pyjwt.exceptions.InvalidAudienceError):
        jwt_utils.decode(token, "secret")
示例#7
0
    def get_jwt(self):
        exp = datetime.datetime.utcnow() + datetime.timedelta(minutes=10)
        exp = calendar.timegm(exp.timetuple())
        # Generate the JWT
        payload = {
            # issued at time
            "iat": int(time.time()),
            # JWT expiration time (10 minute maximum)
            "exp": exp,
            # Integration's GitHub identifier
            "iss": options.get("github.integration-app-id"),
        }

        return jwt.encode(payload, options.get("github.integration-private-key"), algorithm="RS256")
示例#8
0
def get_jwt(github_id: str | None = None, github_private_key: str | None = None) -> str:
    if github_id is None:
        github_id = options.get("github-app.id")
    if github_private_key is None:
        github_private_key = options.get("github-app.private-key")
    exp_ = datetime.datetime.utcnow() + datetime.timedelta(minutes=10)
    exp = calendar.timegm(exp_.timetuple())
    # Generate the JWT
    payload = {
        # issued at time
        "iat": int(time.time()),
        # JWT expiration time (10 minute maximum)
        "exp": exp,
        # Integration's GitHub identifier
        "iss": github_id,
    }
    return jwt.encode(payload, github_private_key, algorithm="RS256")
示例#9
0
def test_encode(token: str) -> None:
    headers = {
        "alg": "HS256",
        "typ": "JWT",
    }
    claims = {
        "iss": "me",
    }
    key = "secret"

    encoded = jwt_utils.encode(claims, key, headers=headers)
    assert isinstance(encoded, str)

    assert encoded.count(".") == 2
    assert encoded == token

    decoded_claims = jwt_utils.decode(encoded, key)
    assert decoded_claims == claims
示例#10
0
def test_decode_audience() -> None:
    payload = {
        "iss": "me",
        "aud": "you",
    }
    token = jwt_utils.encode(payload, "secret")

    with pytest.raises(pyjwt.exceptions.InvalidAudienceError):
        jwt_utils.decode(token, "secret")

    claims = jwt_utils.decode(token, "secret", audience="you")
    assert claims == payload

    with pytest.raises(pyjwt.exceptions.InvalidAudienceError):
        jwt_utils.decode(token, "secret", audience="wrong")

    claims = jwt_utils.decode(token, "secret", audience=False)
    assert claims == payload
示例#11
0
    def request_hook(self, method, path, data, params, **kwargs):
        """
        Used by Jira Client to apply the jira-cloud authentication
        """
        # handle params that are already part of the path
        url_params = dict(parse_qs(urlsplit(path).query))
        url_params.update(params or {})
        path = path.split("?")[0]

        jwt_payload = {
            "iss": JIRA_KEY,
            "iat": datetime.datetime.utcnow(),
            "exp": datetime.datetime.utcnow() + datetime.timedelta(seconds=5 * 60),
            "qsh": get_query_hash(path, method.upper(), url_params),
        }
        encoded_jwt = jwt.encode(jwt_payload, self.shared_secret)
        params = dict(jwt=encoded_jwt, **(url_params or {}))
        request_spec = kwargs.copy()
        request_spec.update(dict(method=method, path=path, data=data, params=params))
        return request_spec
示例#12
0
    def create_issue_webhook(self, external_id, secret, credentials):
        auth = OAuth1(
            client_key=credentials["consumer_key"],
            rsa_key=credentials["private_key"],
            resource_owner_key=credentials["access_token"],
            resource_owner_secret=credentials["access_token_secret"],
            signature_method=SIGNATURE_RSA,
            signature_type="auth_header",
        )

        # Create a JWT token that we can add to the webhook URL
        # so we can locate the matching integration later.
        token = jwt.encode({"id": external_id}, secret)
        path = reverse("sentry-extensions-jiraserver-issue-updated",
                       kwargs={"token": token})
        data = {
            "name": "Sentry Issue Sync",
            "url": absolute_uri(path),
            "events": ["jira:issue_created", "jira:issue_updated"],
        }
        return self.post("/rest/webhooks/1.0/webhook", auth=auth, data=data)