コード例 #1
0
ファイル: utils.py プロジェクト: code-watch/sentry
def get_jira_auth_from_request(request):
    # https://developer.atlassian.com/static/connect/docs/latest/concepts/authentication.html
    # Extract the JWT token from the request's jwt query
    # parameter or the authorization header.
    token = request.GET.get("jwt")
    if token is None:
        raise ApiError("No token parameter")
    # Decode the JWT token, without verification. This gives
    # you a header JSON object, a claims JSON object, and a signature.
    decoded = jwt.peek_claims(token)
    # Extract the issuer ('iss') claim from the decoded, unverified
    # claims object. This is the clientKey for the tenant - an identifier
    # for the Atlassian application making the call
    issuer = decoded["iss"]
    # Look up the sharedSecret for the clientKey, as stored
    # by the add-on during the installation handshake
    from sentry_plugins.jira_ac.models import JiraTenant

    jira_auth = JiraTenant.objects.get(client_key=issuer)
    # Verify the signature with the sharedSecret and
    # the algorithm specified in the header's alg field.
    decoded_verified = jwt.decode(token, jira_auth.secret)
    # Verify the query has not been tampered by Creating a Query Hash
    # and comparing it against the qsh claim on the verified token.

    # TODO: probably shouldn't need to hardcode get... for post maybe
    # the secret should just be a hidden field in the form ?
    qsh = get_query_hash(request.path, "GET", request.GET)
    # qsh = get_query_hash(request.path, request.method, request.GET)
    if qsh != decoded_verified["qsh"]:
        raise ApiError("Query hash mismatch")

    return jira_auth
コード例 #2
0
ファイル: client.py プロジェクト: pasala91/test
    def get_create_meta_for_project(self, project):
        params = {
            "expand": "projects.issuetypes.fields",
            "projectIds": project
        }
        metas = self.get_cached(self.META_URL, params=params)
        # We saw an empty JSON response come back from the API :(
        if not metas:
            logger.info(
                "jira.get-create-meta.empty-response",
                extra={
                    "base_url": self.base_url,
                    "project": project
                },
            )
            return None

        # XXX(dcramer): document how this is possible, if it even is
        if len(metas["projects"]) > 1:
            raise ApiError(f"More than one project found matching {project}.")

        try:
            return metas["projects"][0]
        except IndexError:
            logger.info(
                "jira.get-create-meta.key-error",
                extra={
                    "base_url": self.base_url,
                    "project": project
                },
            )
            return None
コード例 #3
0
 def get_issue(self, repo, issue_id):
     try:
         return self.request(
             "GET", "/projects/{}/issues/{}".format(quote(repo, safe=""), issue_id)
         )
     except IndexError:
         raise ApiError("Issue not found with ID", 404)
コード例 #4
0
 def test_get_message_from_error(self):
     self.assert_setup_flow()
     integration = Integration.objects.get(provider=self.provider.key)
     installation = integration.get_installation(self.organization)
     base_error = f"Error Communicating with GitHub (HTTP 404): {API_ERRORS[404]}"
     assert (installation.message_from_error(
         ApiError(
             "Not Found",
             code=404,
             url="https://api.github.com/repos/scefali")) == base_error)
     url = "https://api.github.com/repos/scefali/sentry-integration-example/compare/2adcab794f6f57efa8aa84de68a724e728395792...e208ee2d71e8426522f95efbdae8630fa66499ab"
     assert (
         installation.message_from_error(
             ApiError("Not Found", code=404, url=url)) == base_error +
         f" Please also confirm that the commits associated with the following URL have been pushed to GitHub: {url}"
     )
コード例 #5
0
 def request(self, method, path, headers=None, data=None, params=None, json=False, timeout=None):
     # TODO(meredith): Slack actually supports json now for the chat.postMessage so we
     # can update that so we don't have to pass json=False here
     response = self._request(method, path, headers=headers, data=data, params=params, json=json)
     if not response.json.get("ok"):
         raise ApiError(response.get("error", ""))
     return response
コード例 #6
0
    def get_issue(self, project_id, issue_id):
        """Get an issue

        See https://docs.gitlab.com/ee/api/issues.html#single-issue
        """
        try:
            return self.get(GitLabApiClientPath.issue.format(project=project_id, issue=issue_id))
        except IndexError:
            raise ApiError("Issue not found with ID", 404)
コード例 #7
0
ファイル: oauth2.py プロジェクト: zlcoming/sentry
    def handle_refresh_error(self, req, payload):
        error_name = "unknown_error"
        error_description = "no description available"
        for name_key in ["error", "Error"]:
            if name_key in payload:
                error_name = payload.get(name_key)
                break

        for desc_key in ["error_description", "ErrorDescription"]:
            if desc_key in payload:
                error_description = payload.get(desc_key)
                break

        formatted_error = u"HTTP {} ({}): {}".format(req.status_code,
                                                     error_name,
                                                     error_description)

        if req.status_code == 401:
            self.logger.info(
                "identity.oauth.refresh.identity-not-valid-error",
                extra={
                    "error_name": error_name,
                    "error_status_code": req.status_code,
                    "error_description": error_description,
                    "provider_key": self.key,
                },
            )
            raise IdentityNotValid(formatted_error)

        if req.status_code == 400:
            # this may not be common, but at the very least Google will return
            # an invalid grant when a user is suspended
            if error_name == "invalid_grant":
                self.logger.info(
                    "identity.oauth.refresh.identity-not-valid-error",
                    extra={
                        "error_name": error_name,
                        "error_status_code": req.status_code,
                        "error_description": error_description,
                        "provider_key": self.key,
                    },
                )
                raise IdentityNotValid(formatted_error)

        if req.status_code != 200:
            self.logger.info(
                "identity.oauth.refresh.api-error",
                extra={
                    "error_name": error_name,
                    "error_status_code": req.status_code,
                    "error_description": error_description,
                    "provider_key": self.key,
                },
            )
            raise ApiError(formatted_error)
コード例 #8
0
    def get_create_meta_for_project(self, project):
        metas = self.get_create_meta(project)
        # We saw an empty JSON response come back from the API :(
        if not metas:
            return None

        # XXX(dcramer): document how this is possible, if it even is
        if len(metas["projects"]) > 1:
            raise ApiError("More than one project found.")

        try:
            return metas["projects"][0]
        except IndexError:
            return None
コード例 #9
0
ファイル: client.py プロジェクト: blacknode/sentry
 def request(
     self,
     method: str,
     path: str,
     headers: Optional[Mapping[str, str]] = None,
     data: Optional[Mapping[str, Any]] = None,
     params: Optional[Mapping[str, Any]] = None,
     json: bool = False,
     timeout: Optional[int] = None,
 ):
     # TODO(meredith): Slack actually supports json now for the chat.postMessage so we
     # can update that so we don't have to pass json=False here
     response = self._request(method, path, headers=headers, data=data, params=params, json=json)
     if not response.json.get("ok"):
         raise ApiError(response.get("error", ""))
     return response
コード例 #10
0
 def get_access_token(self, request_token, verifier):
     """
     Step 3 of the oauth flow.
     Use the verifier and request token from step 1 to get an access token.
     """
     if not verifier:
         raise ApiError("Missing OAuth token verifier")
     auth = OAuth1(
         client_key=self.consumer_key,
         resource_owner_key=request_token["oauth_token"],
         resource_owner_secret=request_token["oauth_token_secret"],
         verifier=verifier,
         rsa_key=self.private_key,
         signature_method=SIGNATURE_RSA,
         signature_type="auth_header",
     )
     url = self.access_token_url.format(self.base_url)
     resp = self.post(url, auth=auth, allow_text=True)
     return dict(parse_qsl(resp.text))
コード例 #11
0
    def test_notify_failure(self):
        errors = (
            ApiError("The server is sad"),
            SSLError("[SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:590)"),
            HTTPError("A bad response"),
            PluginError("A plugin is sad"),
        )
        for err in errors:
            n = DummyNotificationPlugin()
            n.slug = "slack"

            def hook(*a, **kw):
                raise err

            event = self.store_event(data={}, project_id=self.project.id)
            notification = Notification(event)

            n.notify_users = hook
            assert n.notify(notification) is False
コード例 #12
0
    def test_test_configuration_and_get_test_results(self):
        errors = (
            ApiError("The server is sad"),
            ApiHostError("host error"),
            ApiUnauthorized("not used"),
        )
        for err in errors:
            n = DummyNotificationPlugin()
            n.slug = "slack"

            def hook(*a, **kw):
                n.raise_error(err)

            n.notify_users = hook
            if isinstance(err, ApiUnauthorized):
                message = "your access token was invalid"
            else:
                message = err.text
            assert message
            assert message in n.test_configuration_and_get_test_results(self.project)
コード例 #13
0
 def test_handle_exception_503(self):
     resp = IntegrationEndpoint().handle_exception(
         HttpRequest(), ApiError("This is an error", code=503))
     assert resp.status_code == 503
     assert resp.exception is True
コード例 #14
0
ファイル: stub_client.py プロジェクト: thebarton/sentry
 def get_user(self, user_id):
     user = self._get_stub_data("user.json")
     if user["accountId"] == user_id:
         return user
     raise ApiError("no user found")