def setUp(self): self.install = self.create_sentry_app_installation() self.code = self.install.api_grant.code self.client_id = self.install.sentry_app.application.client_id self.user = self.install.sentry_app.proxy_user self.grant_exchanger = GrantExchanger( install=self.install, client_id=self.client_id, code=self.code, user=self.user )
def test_records_analytics(self, record): GrantExchanger.run( install=self.install, client_id=self.client_id, code=self.code, user=self.user ) record.assert_called_with( "sentry_app.token_exchanged", sentry_app_installation_id=self.install.id, exchange_type="authorization", )
def test_records_analytics(self, record): GrantExchanger.run( install=self.install, client_id=self.client_id, code=self.code, user=self.user, ) record.assert_called_with( 'sentry_app.token_exchanged', sentry_app_installation_id=self.install.id, exchange_type='authorization', )
def post(self, request, installation): try: if request.json_body.get("grant_type") == GrantTypes.AUTHORIZATION: token = GrantExchanger.run( install=installation, code=request.json_body.get("code"), client_id=request.json_body.get("client_id"), user=request.user, ) elif request.json_body.get("grant_type") == GrantTypes.REFRESH: token = Refresher.run( install=installation, refresh_token=request.json_body.get("refresh_token"), client_id=request.json_body.get("client_id"), user=request.user, ) else: return Response({"error": "Invalid grant_type"}, status=403) except APIUnauthorized as e: return Response({"error": e.msg or "Unauthorized"}, status=403) attrs = {"state": request.json_body.get("state"), "application": None} body = ApiTokenSerializer().serialize(token, attrs, request.user) return Response(body, status=201)
def post(self, request, installation): with sentry_sdk.configure_scope() as scope: scope.set_tag("organization", installation.organization_id) scope.set_tag("sentry_app_id", installation.sentry_app_id) scope.set_tag("sentry_app_slug", installation.sentry_app.slug) try: if request.json_body.get("grant_type") == GrantTypes.AUTHORIZATION: token = GrantExchanger.run( install=installation, code=request.json_body.get("code"), client_id=request.json_body.get("client_id"), user=request.user, ) elif request.json_body.get("grant_type") == GrantTypes.REFRESH: token = Refresher.run( install=installation, refresh_token=request.json_body.get("refresh_token"), client_id=request.json_body.get("client_id"), user=request.user, ) else: return Response({"error": "Invalid grant_type"}, status=403) except APIUnauthorized as e: logger.error(e, exc_info=True) return Response({"error": e.msg or "Unauthorized"}, status=403) attrs = {"state": request.json_body.get("state"), "application": None} body = ApiTokenSerializer().serialize(token, attrs, request.user) return Response(body, status=201)
def test_non_internal_app(self): sentry_app = self.create_sentry_app(name="My External App", organization=self.org) install = self.create_sentry_app_installation(slug=sentry_app.slug, organization=self.org, user=self.user) client_id = install.sentry_app.application.client_id user = install.sentry_app.proxy_user api_token = GrantExchanger.run(install=install, code=install.api_grant.code, client_id=client_id, user=user) url = reverse( "sentry-api-0-sentry-internal-app-token-details", args=[install.sentry_app.slug, api_token.token], ) self.login_as(user=self.user) response = self.client.delete(url, format="json") assert response.status_code == 403 assert response.data == "This route is limited to internal integrations only"
def test_organization(self): self.request.session = {} sentry_app = self.create_sentry_app(name="Tesla App", published=True, organization=self.organization) install = self.create_sentry_app_installation( slug=sentry_app.slug, organization=self.organization, user=self.user) client_id = sentry_app.application.client_id user = sentry_app.proxy_user api_token = GrantExchanger.run(install=install, code=install.api_grant.code, client_id=client_id, user=user) self.request.user = sentry_app.proxy_user self.request.auth = api_token assert ( get_rate_limit_key(self.view, self.request) == f"org:OrganizationGroupIndexEndpoint:GET:{install.organization_id}" )
def post(self, request, installation): try: if request.json_body.get('grant_type') == GrantTypes.AUTHORIZATION: token = GrantExchanger.run( install=installation, code=request.json_body.get('code'), client_id=request.json_body.get('client_id'), user=request.user, ) elif request.json_body.get('grant_type') == GrantTypes.REFRESH: token = Refresher.run( install=installation, refresh_token=request.json_body.get('refresh_token'), client_id=request.json_body.get('client_id'), user=request.user, ) else: return Response({'error': 'Invalid grant_type'}, status=403) except APIUnauthorized as e: return Response({'error': e.msg or 'Unauthorized'}, status=403) attrs = { 'state': request.json_body.get('state'), 'application': None, } body = ApiTokenSerializer().serialize(token, attrs, request.user) return Response(body, status=201)
def setUp(self): super().setUp() self.token = GrantExchanger.run( install=self.installation, code=self.installation.api_grant.code, client_id=self.published_app.application.client_id, user=self.published_app.proxy_user, )
def setUp(self): self.install = self.create_sentry_app_installation() self.code = self.install.api_grant.code self.client_id = self.install.sentry_app.application.client_id self.user = self.install.sentry_app.proxy_user self.grant_exchanger = GrantExchanger( install=self.install, client_id=self.client_id, code=self.code, user=self.user, )
def test_sentry_app_installation_mark_installed_wrong_app(self): self.token = GrantExchanger.run( install=self.installation2, code=self.installation2.api_grant.code, client_id=self.unpublished_app.application.client_id, user=self.unpublished_app.proxy_user, ) self.url = reverse("sentry-api-0-sentry-app-installation-details", args=[self.installation.uuid]) response = self.client.put( self.url, data={"status": "installed"}, HTTP_AUTHORIZATION=f"Bearer {self.token.token}", format="json", ) assert response.status_code == 403
def setUp(self): self.install = self.create_sentry_app_installation() self.client_id = self.install.sentry_app.application.client_id self.user = self.install.sentry_app.proxy_user self.token = GrantExchanger.run( install=self.install, code=self.install.api_grant.code, client_id=self.client_id, user=self.user, ) self.refresher = Refresher( install=self.install, client_id=self.client_id, refresh_token=self.token.refresh_token, user=self.user, )
def test_sentry_app_installation_mark_installed_wrong_app(self): self.token = GrantExchanger.run( install=self.installation2, code=self.installation2.api_grant.code, client_id=self.unpublished_app.application.client_id, user=self.unpublished_app.proxy_user, ) self.url = reverse( 'sentry-api-0-sentry-app-installation-details', args=[self.installation.uuid], ) response = self.client.put( self.url, data={'status': 'installed'}, HTTP_AUTHORIZATION=u'Bearer {}'.format(self.token.token), format='json', ) assert response.status_code == 403
class TestGrantExchanger(TestCase): def setUp(self): self.install = self.create_sentry_app_installation() self.code = self.install.api_grant.code self.client_id = self.install.sentry_app.application.client_id self.user = self.install.sentry_app.proxy_user self.grant_exchanger = GrantExchanger( install=self.install, client_id=self.client_id, code=self.code, user=self.user, ) def test_happy_path(self): assert self.grant_exchanger.call() @patch('sentry.mediators.token_exchange.Validator.run') def test_validate_generic_token_exchange_requirements(self, validator): self.grant_exchanger.call() validator.assert_called_once_with( install=self.install, client_id=self.client_id, user=self.user, ) def test_grant_must_belong_to_installations(self): other_install = self.create_sentry_app_installation() self.grant_exchanger.code = other_install.api_grant.code with self.assertRaises(APIUnauthorized): self.grant_exchanger.call() def test_request_user_owns_api_grant(self): self.grant_exchanger.user = self.create_user() with self.assertRaises(APIUnauthorized): self.grant_exchanger.call() def test_grant_must_be_active(self): self.install.api_grant.update(expires_at=(datetime.utcnow() - timedelta(hours=1))) with self.assertRaises(APIUnauthorized): self.grant_exchanger.call() def test_grant_must_exist(self): self.grant_exchanger.code = '123' with self.assertRaises(APIUnauthorized): self.grant_exchanger.call() @patch('sentry.models.ApiGrant.application', side_effect=ApiApplication.DoesNotExist) def test_application_must_exist(self, _): with self.assertRaises(APIUnauthorized): self.grant_exchanger.call() @patch('sentry.models.ApiApplication.sentry_app', side_effect=SentryApp.DoesNotExist) def test_sentry_app_must_exist(self, _): with self.assertRaises(APIUnauthorized): self.grant_exchanger.call()
class TestGrantExchanger(TestCase): def setUp(self): self.install = self.create_sentry_app_installation() self.code = self.install.api_grant.code self.client_id = self.install.sentry_app.application.client_id self.user = self.install.sentry_app.proxy_user self.grant_exchanger = GrantExchanger(install=self.install, client_id=self.client_id, code=self.code, user=self.user) def test_happy_path(self): assert self.grant_exchanger.call() def test_adds_token_to_installation(self): token = self.grant_exchanger.call() assert SentryAppInstallation.objects.get( id=self.install.id).api_token == token @patch("sentry.mediators.token_exchange.Validator.run") def test_validate_generic_token_exchange_requirements(self, validator): self.grant_exchanger.call() validator.assert_called_once_with(install=self.install, client_id=self.client_id, user=self.user) def test_grant_must_belong_to_installations(self): other_install = self.create_sentry_app_installation() self.grant_exchanger.code = other_install.api_grant.code with self.assertRaises(APIUnauthorized): self.grant_exchanger.call() def test_request_user_owns_api_grant(self): self.grant_exchanger.user = self.create_user() with self.assertRaises(APIUnauthorized): self.grant_exchanger.call() def test_grant_must_be_active(self): self.install.api_grant.update(expires_at=(datetime.utcnow() - timedelta(hours=1))) with self.assertRaises(APIUnauthorized): self.grant_exchanger.call() def test_grant_must_exist(self): self.grant_exchanger.code = "123" with self.assertRaises(APIUnauthorized): self.grant_exchanger.call() @patch("sentry.models.ApiGrant.application", side_effect=ApiApplication.DoesNotExist) def test_application_must_exist(self, _): with self.assertRaises(APIUnauthorized): self.grant_exchanger.call() @patch("sentry.models.ApiApplication.sentry_app", side_effect=SentryApp.DoesNotExist) def test_sentry_app_must_exist(self, _): with self.assertRaises(APIUnauthorized): self.grant_exchanger.call() def test_deletes_grant_on_successful_exchange(self): grant_id = self.install.api_grant_id self.grant_exchanger.call() assert not ApiGrant.objects.filter(id=grant_id) @patch("sentry.analytics.record") def test_records_analytics(self, record): GrantExchanger.run(install=self.install, client_id=self.client_id, code=self.code, user=self.user) record.assert_called_with( "sentry_app.token_exchanged", sentry_app_installation_id=self.install.id, exchange_type="authorization", )
class TestGrantExchanger(TestCase): def setUp(self): self.install = self.create_sentry_app_installation() self.code = self.install.api_grant.code self.client_id = self.install.sentry_app.application.client_id self.user = self.install.sentry_app.proxy_user self.grant_exchanger = GrantExchanger( install=self.install, client_id=self.client_id, code=self.code, user=self.user, ) def test_happy_path(self): assert self.grant_exchanger.call() def test_adds_token_to_installation(self): token = self.grant_exchanger.call() assert SentryAppInstallation.objects.get(id=self.install.id).api_token == token @patch('sentry.mediators.token_exchange.Validator.run') def test_validate_generic_token_exchange_requirements(self, validator): self.grant_exchanger.call() validator.assert_called_once_with( install=self.install, client_id=self.client_id, user=self.user, ) def test_grant_must_belong_to_installations(self): other_install = self.create_sentry_app_installation() self.grant_exchanger.code = other_install.api_grant.code with self.assertRaises(APIUnauthorized): self.grant_exchanger.call() def test_request_user_owns_api_grant(self): self.grant_exchanger.user = self.create_user() with self.assertRaises(APIUnauthorized): self.grant_exchanger.call() def test_grant_must_be_active(self): self.install.api_grant.update(expires_at=(datetime.utcnow() - timedelta(hours=1))) with self.assertRaises(APIUnauthorized): self.grant_exchanger.call() def test_grant_must_exist(self): self.grant_exchanger.code = '123' with self.assertRaises(APIUnauthorized): self.grant_exchanger.call() @patch('sentry.models.ApiGrant.application', side_effect=ApiApplication.DoesNotExist) def test_application_must_exist(self, _): with self.assertRaises(APIUnauthorized): self.grant_exchanger.call() @patch('sentry.models.ApiApplication.sentry_app', side_effect=SentryApp.DoesNotExist) def test_sentry_app_must_exist(self, _): with self.assertRaises(APIUnauthorized): self.grant_exchanger.call() def test_deletes_grant_on_successful_exchange(self): grant_id = self.install.api_grant_id self.grant_exchanger.call() assert not ApiGrant.objects.filter(id=grant_id) @patch('sentry.analytics.record') def test_records_analytics(self, record): GrantExchanger.run( install=self.install, client_id=self.client_id, code=self.code, user=self.user, ) record.assert_called_with( 'sentry_app.token_exchanged', sentry_app_installation_id=self.install.id, exchange_type='authorization', )