def test_webhook_subscription_created_once(self, mock_get_scopes):
        self.assert_installation()

        state = {
            "account": {"accountName": self.vsts_account_name, "accountId": self.vsts_account_id},
            "base_url": self.vsts_base_url,
            "identity": {
                "data": {
                    "access_token": self.access_token,
                    "expires_in": "3600",
                    "refresh_token": self.refresh_token,
                    "token_type": "jwt-bearer",
                }
            },
        }

        # The above already created the Webhook, so subsequent calls to
        # ``build_integration`` should omit that data.
        provider = VstsIntegrationProvider()
        pipeline = Mock()
        pipeline.organization = self.organization
        provider.set_pipeline(pipeline)
        data = provider.build_integration(state)
        assert "subscription" in data["metadata"]
        assert (
            Integration.objects.get(provider="vsts").metadata["subscription"]
            == data["metadata"]["subscription"]
        )
Beispiel #2
0
    def test_build_integration(self):
        state = {
            'account': {
                'accountName': self.vsts_account_name,
                'accountId': self.vsts_account_id,
            },
            'base_url': self.vsts_base_url,
            'identity': {
                'data': {
                    'access_token': self.access_token,
                    'expires_in': '3600',
                    'refresh_token': self.refresh_token,
                    'token_type': 'jwt-bearer',
                },
            },
        }

        integration = VstsIntegrationProvider()
        integration_dict = integration.build_integration(state)

        assert integration_dict['name'] == self.vsts_account_name
        assert integration_dict['external_id'] == self.vsts_account_id
        assert integration_dict['metadata']['domain_name'] == self.vsts_base_url

        assert integration_dict['user_identity']['type'] == 'vsts'
        assert integration_dict['user_identity']['external_id'] == \
            self.vsts_account_id
        assert integration_dict['user_identity']['scopes'] == sorted(
            VSTSIdentityProvider.oauth_scopes)
Beispiel #3
0
 def setUp(self):
     self.integration = VstsIntegrationProvider()
     responses.add(
         responses.GET,
         'https://app.vssps.visualstudio.com/_apis/profile/profiles/me?api-version=1.0',
         json={
             'id': 'user1',
             'displayName': 'Sentry User',
             'emailAddress': '*****@*****.**',
         },
     )
     responses.add(
         responses.GET,
         'https://app.vssps.visualstudio.com/_apis/connectionData/',
         json={
             'authenticatedUser': {
                 'subjectDescriptor': 'user1-subject-desc',
             },
         },
     )
     responses.add(
         responses.POST,
         'https://sentry.visualstudio.com/_apis/hooks/subscriptions',
         json=CREATE_SUBSCRIPTION,
     )
Beispiel #4
0
    def test_create_subscription_unauthorized(self, mock_get_scopes):
        responses.replace(
            responses.POST,
            f"https://{self.vsts_account_name.lower()}.visualstudio.com/_apis/hooks/subscriptions",
            status=401,
            json={
                "$id": 1,
                "message":
                "The user bob is not authorized to access this resource",
                "typeKey": "UnauthorizedRequestException",
                "errorCode": 0,
                "eventId": 3000,
            },
        )
        state = {
            "account": {
                "accountName": self.vsts_account_name,
                "accountId": self.vsts_account_id
            },
            "base_url": self.vsts_base_url,
            "identity": {
                "data": {
                    "access_token": self.access_token,
                    "expires_in": "3600",
                    "refresh_token": self.refresh_token,
                    "token_type": "jwt-bearer",
                }
            },
        }

        integration = VstsIntegrationProvider()

        with pytest.raises(IntegrationError) as err:
            integration.build_integration(state)
        assert "sufficient account access to create webhooks" in str(err)
Beispiel #5
0
    def test_build_integration(self):
        state = {
            'account': {
                'accountName': self.vsts_account_name,
                'accountId': self.vsts_account_id,
            },
            'base_url': self.vsts_base_url,
            'identity': {
                'data': {
                    'access_token': self.access_token,
                    'expires_in': '3600',
                    'refresh_token': self.refresh_token,
                    'token_type': 'jwt-bearer',
                },
            },
        }

        integration = VstsIntegrationProvider()
        integration_dict = integration.build_integration(state)

        assert integration_dict['name'] == self.vsts_account_name
        assert integration_dict['external_id'] == self.vsts_account_id
        assert integration_dict['metadata']['domain_name'] == self.vsts_base_url

        assert integration_dict['user_identity']['type'] == 'vsts'
        assert integration_dict['user_identity']['external_id'] == \
            self.vsts_account_id
        assert integration_dict['user_identity']['scopes'] == sorted(
            VSTSIdentityProvider.oauth_scopes)
Beispiel #6
0
    def test_success(self, mock_get_scopes):
        state = {
            "account": {
                "accountName": self.vsts_account_name,
                "accountId": self.vsts_account_id
            },
            "base_url": self.vsts_base_url,
            "identity": {
                "data": {
                    "access_token": self.access_token,
                    "expires_in": "3600",
                    "refresh_token": self.refresh_token,
                    "token_type": "jwt-bearer",
                }
            },
        }

        integration = VstsIntegrationProvider()
        integration_dict = integration.build_integration(state)

        assert integration_dict["name"] == self.vsts_account_name
        assert integration_dict["external_id"] == self.vsts_account_id
        assert integration_dict["metadata"][
            "domain_name"] == self.vsts_base_url

        assert integration_dict["user_identity"]["type"] == "vsts"
        assert integration_dict["user_identity"][
            "external_id"] == self.vsts_account_id
        assert integration_dict["user_identity"]["scopes"] == FULL_SCOPES
 def setUp(self):
     self.integration = VstsIntegrationProvider()
     responses.add(
         responses.GET,
         'https://app.vssps.visualstudio.com/_apis/profile/profiles/me?api-version=1.0',
         json={
             'id': 'user1',
             'displayName': 'Sentry User',
             'emailAddress': '*****@*****.**',
         },
     )
Beispiel #8
0
    def test_webhook_subscription_created_once(self):
        self.assert_installation()

        state = {
            'account': {
                'accountName': self.vsts_account_name,
                'accountId': self.vsts_account_id,
            },
            'base_url': self.vsts_base_url,
            'identity': {
                'data': {
                    'access_token': self.access_token,
                    'expires_in': '3600',
                    'refresh_token': self.refresh_token,
                    'token_type': 'jwt-bearer',
                },
            },
        }

        # The above already created the Webhook, so subsequent calls to
        # ``build_integration`` should omit that data.
        data = VstsIntegrationProvider().build_integration(state)
        assert 'subscription' in data['metadata']
        assert Integration.objects.get(
            provider='vsts').metadata['subscription'] == data['metadata']['subscription']
Beispiel #9
0
 def test_fix_subscription(self):
     external_id = '1234567890'
     Integration.objects.create(
         metadata={},
         provider='vsts',
         external_id=external_id,
     )
     data = VstsIntegrationProvider().build_integration({
         'account': {
             'accountName': self.vsts_account_name,
             'accountId': external_id,
         },
         'base_url': self.vsts_base_url,
         'identity': {
             'data': {
                 'access_token': self.access_token,
                 'expires_in': '3600',
                 'refresh_token': self.refresh_token,
                 'token_type': 'jwt-bearer',
             },
         },
     })
     assert external_id == data['external_id']
     subscription = data['metadata']['subscription']
     assert subscription['id'] is not None and subscription['secret'] is not None
Beispiel #10
0
 def setUp(self):
     self.integration = VstsIntegrationProvider()
     responses.add(
         responses.GET,
         'https://app.vssps.visualstudio.com/_apis/profile/profiles/me?api-version=1.0',
         json={
             'id': 'user1',
             'displayName': 'Sentry User',
             'emailAddress': '*****@*****.**',
         },
     )
     responses.add(
         responses.GET,
         'https://app.vssps.visualstudio.com/_apis/connectionData/',
         json={
             'authenticatedUser': {
                 'subjectDescriptor': 'user1-subject-desc',
             },
         },
     )
     responses.add(
         responses.POST,
         'https://sentry.visualstudio.com/_apis/hooks/subscriptions',
         json=CREATE_SUBSCRIPTION,
     )
Beispiel #11
0
class VstsIntegrationProviderTest(TestCase):
    def setUp(self):
        self.integration = VstsIntegrationProvider()
        responses.add(
            responses.GET,
            'https://app.vssps.visualstudio.com/_apis/profile/profiles/me?api-version=1.0',
            json={
                'id': 'user1',
                'displayName': 'Sentry User',
                'emailAddress': '*****@*****.**',
            },
        )
        responses.add(
            responses.GET,
            'https://app.vssps.visualstudio.com/_apis/connectionData/',
            json={
                'authenticatedUser': {
                    'subjectDescriptor': 'user1-subject-desc',
                },
            },
        )

    @responses.activate
    def test_build_integration(self):
        state = {
            'account': {
                'AccountName': 'sentry',
                'AccountId': '123435'
            },
            'instance': 'sentry.visualstudio.com',
            'identity': {
                'data': {
                    'access_token': 'xxx-xxxx',
                    'expires_in': '3600',
                    'refresh_token': 'rxxx-xxxx',
                    'token_type': 'jwt-bearer',
                },
            },
        }
        integration_dict = self.integration.build_integration(state)
        assert integration_dict['name'] == 'sentry'
        assert integration_dict['external_id'] == '123435'
        assert integration_dict['metadata'][
            'domain_name'] == 'sentry.visualstudio.com'

        assert integration_dict['user_identity']['type'] == 'vsts'
        assert integration_dict['user_identity'][
            'external_id'] == 'user1-subject-desc'
        assert integration_dict['user_identity']['scopes'] == sorted(
            VSTSIdentityProvider.oauth_scopes)

        assert integration_dict['user_identity']['data'][
            'access_token'] == 'xxx-xxxx'
        assert isinstance(integration_dict['user_identity']['data']['expires'],
                          int)
        assert integration_dict['user_identity']['data'][
            'refresh_token'] == 'rxxx-xxxx'
        assert integration_dict['user_identity']['data'][
            'token_type'] == 'jwt-bearer'
Beispiel #12
0
    def test_get_pipeline_views(self):
        # Should be same as the VSTS integration, but with a different last
        # step.
        views = self.provider.get_pipeline_views()
        vsts_views = VstsIntegrationProvider().get_pipeline_views()

        assert isinstance(views[0], type(vsts_views[0]))
        assert isinstance(views[-1], VstsExtensionFinishedView)
Beispiel #13
0
    def test_build_integration__create_subscription_error(self):
        responses.replace(
            responses.POST,
            u'https://{}.visualstudio.com/_apis/hooks/subscriptions'.format(
                self.vsts_account_name.lower(),
            ),
            status=403,
            json={
                '$id': 1,
                'message': 'The user bob is not authorized to access this resource',
                'typeKey': 'UnauthorizedRequestException',
                'errorCode': 0,
                'eventId': 3000
            }
        )
        state = {
            'account': {
                'accountName': self.vsts_account_name,
                'accountId': self.vsts_account_id,
            },
            'base_url': self.vsts_base_url,
            'identity': {
                'data': {
                    'access_token': self.access_token,
                    'expires_in': '3600',
                    'refresh_token': self.refresh_token,
                    'token_type': 'jwt-bearer',
                },
            },
        }

        integration = VstsIntegrationProvider()

        with pytest.raises(IntegrationError) as err:
            integration.build_integration(state)
        assert 'sufficient account access to create webhooks' in six.text_type(err)
class VSTSIntegrationTest(TestCase):
    def setUp(self):
        self.integration = VstsIntegrationProvider()

    def test_build_integration(self):
        state = {
            'identity': {
                'data': {
                    'access_token': 'xxx-xxxx',
                    'expires_in': '3600',
                    'refresh_token': 'rxxx-xxxx',
                    'token_type': 'jwt-bearer',
                },
                'account': {
                    'AccountName': 'sentry',
                    'AccountId': '123435'
                },
                'instance': 'sentry.visualstudio.com',
            },
            'project': {
                'name': 'My Project',
                'id': 'my-project-id'
            },
        }
        integration_dict = self.integration.build_integration(state)
        assert integration_dict['name'] == 'My Project'
        assert integration_dict['external_id'] == 'my-project-id'
        assert integration_dict['metadata']['scopes'] == list(
            VSTSIdentityProvider.oauth_scopes)
        assert integration_dict['metadata'][
            'domain_name'] == 'sentry.visualstudio.com'

        assert integration_dict['user_identity']['type'] == 'vsts'
        assert integration_dict['user_identity']['external_id'] == '123435'
        assert integration_dict['user_identity']['scopes'] == []

        assert integration_dict['user_identity']['data'][
            'access_token'] == 'xxx-xxxx'
        assert isinstance(integration_dict['user_identity']['data']['expires'],
                          int)
        assert integration_dict['user_identity']['data'][
            'refresh_token'] == 'rxxx-xxxx'
        assert integration_dict['user_identity']['data'][
            'token_type'] == 'jwt-bearer'
 def test_fix_subscription(self, mock_get_scopes):
     external_id = self.vsts_account_id
     Integration.objects.create(metadata={}, provider="vsts", external_id=external_id)
     data = VstsIntegrationProvider().build_integration(
         {
             "account": {"accountName": self.vsts_account_name, "accountId": external_id},
             "base_url": self.vsts_base_url,
             "identity": {
                 "data": {
                     "access_token": self.access_token,
                     "expires_in": "3600",
                     "refresh_token": self.refresh_token,
                     "token_type": "jwt-bearer",
                 }
             },
         }
     )
     assert external_id == data["external_id"]
     subscription = data["metadata"]["subscription"]
     assert subscription["id"] is not None and subscription["secret"] is not None
Beispiel #16
0
    def test_webhook_subscription_created_once(self):
        self.assert_installation()

        state = {
            'account': {
                'AccountName': self.vsts_account_name,
                'AccountId': self.vsts_account_id,
            },
            'instance': '{}.visualstudio.com'.format(self.vsts_account_name),
            'identity': {
                'data': {
                    'access_token': self.access_token,
                    'expires_in': '3600',
                    'refresh_token': self.refresh_token,
                    'token_type': 'jwt-bearer',
                },
            },
        }

        # The above already created the Webhook, so subsequent calls to
        # ``build_integration`` should omit that data.
        data = VstsIntegrationProvider().build_integration(state)
        assert 'subscription' not in data['metadata']
Beispiel #17
0
 def setUp(self):
     self.integration = VstsIntegrationProvider()
Beispiel #18
0
class VstsIntegrationProviderTest(TestCase):
    def setUp(self):
        self.integration = VstsIntegrationProvider()
        responses.add(
            responses.GET,
            'https://app.vssps.visualstudio.com/_apis/profile/profiles/me?api-version=1.0',
            json={
                'id': 'user1',
                'displayName': 'Sentry User',
                'emailAddress': '*****@*****.**',
            },
        )
        responses.add(
            responses.GET,
            'https://app.vssps.visualstudio.com/_apis/connectionData/',
            json={
                'authenticatedUser': {
                    'subjectDescriptor': 'user1-subject-desc',
                },
            },
        )
        responses.add(
            responses.POST,
            'https://sentry.visualstudio.com/_apis/hooks/subscriptions',
            json=CREATE_SUBSCRIPTION,
        )

    @responses.activate
    def test_build_integration(self):
        state = {
            'account': {'AccountName': 'sentry', 'AccountId': '123435'},
            'instance': 'sentry.visualstudio.com',
            'identity': {
                'data': {
                    'access_token': 'xxx-xxxx',
                    'expires_in': '3600',
                    'refresh_token': 'rxxx-xxxx',
                    'token_type': 'jwt-bearer',
                },
            },
        }
        integration_dict = self.integration.build_integration(state)
        assert integration_dict['name'] == 'sentry'
        assert integration_dict['external_id'] == '123435'
        assert integration_dict['metadata']['domain_name'] == 'sentry.visualstudio.com'
        assert integration_dict['metadata']['subscription']['id'] == CREATE_SUBSCRIPTION['publisherInputs']['tfsSubscriptionId']
        assert integration_dict['metadata']['subscription']['secret'] is not None

        assert integration_dict['user_identity']['type'] == 'vsts'
        assert integration_dict['user_identity']['external_id'] == 'user1-subject-desc'
        assert integration_dict['user_identity']['scopes'] == sorted(
            VSTSIdentityProvider.oauth_scopes)

        assert integration_dict['user_identity']['data']['access_token'] == 'xxx-xxxx'
        assert isinstance(integration_dict['user_identity']['data']['expires'], int)
        assert integration_dict['user_identity']['data']['refresh_token'] == 'rxxx-xxxx'
        assert integration_dict['user_identity']['data']['token_type'] == 'jwt-bearer'

    @responses.activate
    def test_subscription_created_once(self):
        external_id = '123-VSTS'
        Integration.objects.create(
            provider='vsts',
            external_id=external_id,
            name='vsts_name',
            metadata={},
        )
        state = {
            'account': {'AccountName': 'sentry', 'AccountId': external_id},
            'instance': 'sentry.visualstudio.com',
            'identity': {
                'data': {
                    'access_token': 'xxx-xxxx',
                    'expires_in': '3600',
                    'refresh_token': 'rxxx-xxxx',
                    'token_type': 'jwt-bearer',
                },
            },
        }
        integration_dict = self.integration.build_integration(state)
        assert 'subscription' not in integration_dict['metadata']
Beispiel #19
0
class VstsIntegrationProviderTest(TestCase):
    def setUp(self):
        self.integration = VstsIntegrationProvider()
        responses.add(
            responses.GET,
            'https://app.vssps.visualstudio.com/_apis/profile/profiles/me?api-version=1.0',
            json={
                'id': 'user1',
                'displayName': 'Sentry User',
                'emailAddress': '*****@*****.**',
            },
        )
        responses.add(
            responses.GET,
            'https://app.vssps.visualstudio.com/_apis/connectionData/',
            json={
                'authenticatedUser': {
                    'subjectDescriptor': 'user1-subject-desc',
                },
            },
        )
        responses.add(
            responses.POST,
            'https://sentry.visualstudio.com/_apis/hooks/subscriptions',
            json=CREATE_SUBSCRIPTION,
        )

    @responses.activate
    def test_build_integration(self):
        state = {
            'account': {
                'AccountName': 'sentry',
                'AccountId': '123435'
            },
            'instance': 'sentry.visualstudio.com',
            'identity': {
                'data': {
                    'access_token': 'xxx-xxxx',
                    'expires_in': '3600',
                    'refresh_token': 'rxxx-xxxx',
                    'token_type': 'jwt-bearer',
                },
            },
        }
        integration_dict = self.integration.build_integration(state)
        assert integration_dict['name'] == 'sentry'
        assert integration_dict['external_id'] == '123435'
        assert integration_dict['metadata'][
            'domain_name'] == 'sentry.visualstudio.com'
        assert integration_dict['metadata']['subscription'][
            'id'] == CREATE_SUBSCRIPTION['publisherInputs'][
                'tfsSubscriptionId']
        assert integration_dict['metadata']['subscription'][
            'secret'] is not None

        assert integration_dict['user_identity']['type'] == 'vsts'
        assert integration_dict['user_identity'][
            'external_id'] == 'user1-subject-desc'
        assert integration_dict['user_identity']['scopes'] == sorted(
            VSTSIdentityProvider.oauth_scopes)

        assert integration_dict['user_identity']['data'][
            'access_token'] == 'xxx-xxxx'
        assert isinstance(integration_dict['user_identity']['data']['expires'],
                          int)
        assert integration_dict['user_identity']['data'][
            'refresh_token'] == 'rxxx-xxxx'
        assert integration_dict['user_identity']['data'][
            'token_type'] == 'jwt-bearer'

    @responses.activate
    def test_subscription_created_once(self):
        external_id = '123-VSTS'
        Integration.objects.create(
            provider='vsts',
            external_id=external_id,
            name='vsts_name',
            metadata={},
        )
        state = {
            'account': {
                'AccountName': 'sentry',
                'AccountId': external_id
            },
            'instance': 'sentry.visualstudio.com',
            'identity': {
                'data': {
                    'access_token': 'xxx-xxxx',
                    'expires_in': '3600',
                    'refresh_token': 'rxxx-xxxx',
                    'token_type': 'jwt-bearer',
                },
            },
        }
        integration_dict = self.integration.build_integration(state)
        assert 'subscription' not in integration_dict['metadata']