示例#1
0
class Creator(Mediator):
    name = Param(six.string_types)
    organization = Param('sentry.models.Organization')
    scopes = Param(Iterable)
    webhook_url = Param(six.string_types)

    def call(self):
        self.proxy = self._create_proxy_user()
        self.api_app = self._create_api_application()
        self.app = self._create_sentry_app()
        return self.app

    def _create_proxy_user(self):
        return User.objects.create(
            username=self.name.lower(),
            is_sentry_app=True,
        )

    def _create_api_application(self):
        return ApiApplication.objects.create(owner=self.proxy, )

    def _create_sentry_app(self):
        return SentryApp.objects.create(
            name=self.name,
            application=self.api_app,
            owner=self.organization,
            proxy_user=self.proxy,
            scope_list=self.scopes,
            webhook_url=self.webhook_url,
        )
示例#2
0
    def test_default_referencing_instance(self):
        class Target(object):
            user = {'name': 'Pete'}

        target = Target()
        name = Param(six.string_types, default=lambda self: self.user['name'])
        assert name.default(target) == 'Pete'
示例#3
0
class Updater(Mediator):
    sentry_app = Param('sentry.models.sentryapp.SentryApp')
    name = Param(six.string_types, required=False)
    scopes = Param(Iterable, required=False)
    webhook_url = Param(six.string_types, required=False)

    def call(self):
        self._update_name()
        self._update_scopes()
        self._update_webhook_url()
        self.sentry_app.save()
        return self.sentry_app

    @if_param('name')
    def _update_name(self):
        self.sentry_app.name = self.name

    @if_param('scopes')
    def _update_scopes(self):
        self._validate_only_added_scopes()
        self.sentry_app.scope_list = self.scopes

    @if_param('webhook_url')
    def _update_webhook_url(self):
        self.sentry_app.webhook_url = self.webhook_url

    def _validate_only_added_scopes(self):
        if any(self._scopes_removed):
            raise ValidationError('Cannot remove `scopes` already in use.')

    @property
    def _scopes_removed(self):
        return [s for s in self.sentry_app.scope_list if s not in self.scopes]
示例#4
0
class Destroyer(Mediator):
    install = Param('sentry.models.SentryAppInstallation')
    user = Param('sentry.models.User')

    def call(self):
        self._destroy_authorization()
        self._destroy_grant()
        self._destroy_service_hooks()
        self._destroy_installation()
        return self.install

    def _destroy_authorization(self):
        self.install.authorization.delete()

    def _destroy_grant(self):
        self.install.api_grant.delete()

    def _destroy_service_hooks(self):
        hooks = ServiceHook.objects.filter(
            application_id=self.install.sentry_app.application_id,
            actor_id=self.install.id,
        )
        for hook in hooks:
            service_hooks.Destroyer.run(service_hook=hook)

    def _destroy_installation(self):
        InstallationNotifier.run(
            install=self.install,
            user=self.user,
            action='deleted',
        )
        self.install.delete()
示例#5
0
class AlertRuleActionCreator(Mediator):
    install = Param("sentry.models.SentryAppInstallation")
    fields = Param(object, default=[])  # array of dicts

    def call(self):
        uri = self._fetch_sentry_app_uri()
        self._make_external_request(uri)
        return self.response

    def _fetch_sentry_app_uri(self):
        component = SentryAppComponent.objects.get(
            type="alert-rule-action", sentry_app=self.sentry_app
        )
        settings = component.schema.get("settings", {})
        return settings.get("uri")

    def _make_external_request(self, uri=None):
        if uri is None:
            raise APIError("Sentry App request url not found")

        self.response = external_requests.AlertRuleActionRequester.run(
            install=self.install,
            uri=uri,
            fields=self.fields,
        )

    @memoize
    def sentry_app(self):
        return self.install.sentry_app
示例#6
0
    def test_default_referencing_instance(self):
        class Target:
            user = {"name": "Pete"}

        target = Target()
        name = Param((str, ), default=lambda self: self.user["name"])
        assert name.default(target) == "Pete"
示例#7
0
class Updater(Mediator):
    sentry_app = Param('sentry.models.SentryApp')
    name = Param(six.string_types, required=False)
    scopes = Param(Iterable, required=False)
    webhook_url = Param(six.string_types, required=False)

    def call(self):
        self._update_name()
        self._update_scopes()
        self._update_webhook_url()
        self.sentry_app.save()
        return self.sentry_app

    @if_param('name')
    def _update_name(self):
        self.sentry_app.name = self.name

    @if_param('scopes')
    def _update_scopes(self):
        if self.sentry_app.status == SentryAppStatus.PUBLISHED:
            raise APIError('Cannot update scopes on published App.')
        self.sentry_app.scope_list = self.scopes

    @if_param('webhook_url')
    def _update_webhook_url(self):
        self.sentry_app.webhook_url = self.webhook_url
class InstallationNotifier(Mediator):
    install = Param('sentry.models.SentryAppInstallation')
    user = Param('sentry.models.User')

    def call(self):
        self._send_webhook()

    def _send_webhook(self):
        safe_urlread(
            safe_urlopen(self.sentry_app.webhook_url, json=self.body, timeout=5)
        )

    @property
    def body(self):
        data = SentryAppInstallationSerializer().serialize(
            self.install,
            attrs={'code': self.api_grant.code},
            user=self.user,
        )

        return app_platform_event(
            action='installation',
            install=self.install,
            data=data,
            actor=self.user,
        )

    @memoize
    def sentry_app(self):
        return self.install.sentry_app

    @memoize
    def api_grant(self):
        return self.install.api_grant
示例#9
0
    def test_default_referencing_instance(self):
        class Target(object):
            user = {"name": "Pete"}

        target = Target()
        name = Param(six.string_types, default=lambda self: self.user["name"])
        assert name.default(target) == "Pete"
示例#10
0
class MockMediator(Mediator):
    user = Param(dict)
    name = Param((str, ), default=lambda self: self.user["name"])
    age = Param(int, required=False)

    def call(self):
        with self.log():
            pass
示例#11
0
class MockMediator(Mediator):
    user = Param(dict)
    name = Param(six.string_types, default=lambda self: self.user['name'])
    age = Param(int, required=False)

    def call(self):
        with self.log():
            pass
示例#12
0
class Migrator(Mediator):
    integration = Param('sentry.models.integration.Integration')
    organization = Param('sentry.models.organization.Organization')

    def call(self):
        for project in self.projects:
            for plugin in plugins.for_project(project):
                if plugin.slug != self.integration.provider:
                    continue

                if self.all_repos_migrated(plugin.slug):
                    # Since repos are Org-level, if they're all migrated, we
                    # can disable the Plugin for all Projects. There'd be no
                    # Repos left, associated with the Plugin.
                    self.disable_for_all_projects(plugin)

    def all_repos_migrated(self, provider):
        provider = 'visualstudio' if provider == 'vsts' else provider

        return all(r.integration_id is not None
                   for r in self.repos_for_provider(provider))

    def disable_for_all_projects(self, plugin):
        for project in self.projects:
            try:
                self.log(at='disable',
                         project=project.slug,
                         plugin=plugin.slug)
                plugin.disable(project=project)
            except NotImplementedError:
                pass

    def repos_for_provider(self, provider):
        return filter(lambda r: r.provider == provider, self.repositories)

    @property
    def repositories(self):
        return Repository.objects.filter(
            organization_id=self.organization.id, )

    @memoize
    def projects(self):
        return list(self.organization.project_set.all())

    @property
    def plugins(self):
        return [
            plugins.configurable_for_project(project)
            for project in self.projects
        ]

    @property
    def _logging_context(self):
        return {
            'org': self.organization.slug,
            'integration_id': self.integration.id,
            'integration_provider': self.integration.provider,
        }
示例#13
0
class Preparer(Mediator):
    component = Param('sentry.models.SentryAppComponent')
    install = Param('sentry.models.SentryAppInstallation')
    project = Param('sentry.models.Project')

    def call(self):
        if self.component.type == 'issue-link':
            return self._prepare_issue_link()
        if self.component.type == 'stacktrace-link':
            return self._prepare_stacktrace_link()

    def _prepare_stacktrace_link(self):
        schema = self.component.schema
        uri = schema.get('uri')

        urlparts = list(urlparse(self.install.sentry_app.webhook_url))
        urlparts[2] = uri

        query = {'installationId': self.install.uuid}

        if self.project:
            query['projectSlug'] = self.project.slug

        urlparts[4] = urlencode(query)
        schema.update({'url': urlunparse(urlparts)})

    def _prepare_issue_link(self):
        schema = self.component.schema.copy()

        link = schema.get('link', {})
        create = schema.get('create', {})

        for field in link.get('required_fields', []):
            self._prepare_field(field)

        for field in link.get('optional_fields', []):
            self._prepare_field(field)

        for field in create.get('required_fields', []):
            self._prepare_field(field)

        for field in create.get('optional_fields', []):
            self._prepare_field(field)

    def _prepare_field(self, field):
        if 'options' in field:
            field.update({'choices': field['options']})

        if 'uri' in field:
            if 'async' not in field:
                field.update(self._request(field['uri']))

    def _request(self, uri):
        return SelectRequester.run(
            install=self.install,
            project=self.project,
            uri=uri,
        )
示例#14
0
文件: preparer.py 项目: pasala91/test
class Preparer(Mediator):
    component = Param("sentry.models.SentryAppComponent")
    install = Param("sentry.models.SentryAppInstallation")
    project = Param("sentry.models.Project")

    def call(self):
        if self.component.type == "issue-link":
            return self._prepare_issue_link()
        if self.component.type == "stacktrace-link":
            return self._prepare_stacktrace_link()

    def _prepare_stacktrace_link(self):
        schema = self.component.schema
        uri = schema.get("uri")

        urlparts = list(
            urlparse(force_str(self.install.sentry_app.webhook_url)))
        urlparts[2] = uri

        query = {"installationId": self.install.uuid}

        if self.project:
            query["projectSlug"] = self.project.slug

        urlparts[4] = urlencode(query)
        schema.update({"url": urlunparse(urlparts)})

    def _prepare_issue_link(self):
        schema = self.component.schema.copy()

        link = schema.get("link", {})
        create = schema.get("create", {})

        for field in link.get("required_fields", []):
            self._prepare_field(field)

        for field in link.get("optional_fields", []):
            self._prepare_field(field)

        for field in create.get("required_fields", []):
            self._prepare_field(field)

        for field in create.get("optional_fields", []):
            self._prepare_field(field)

    def _prepare_field(self, field):
        if "options" in field:
            field.update({"choices": field["options"]})

        if "uri" in field:
            if not field.get("skip_load_on_open"):
                field.update(self._request(field["uri"]))

    def _request(self, uri):
        return SelectRequester.run(install=self.install,
                                   project=self.project,
                                   uri=uri)
示例#15
0
    def test_setup(self):
        class Target(object):
            name = 1

        name = Param(six.string_types)
        name.setup(Target, 'name')

        assert not hasattr(Target, 'name')
        assert hasattr(Target, '_name')
        assert Target._name == name
示例#16
0
    def test_setup(self):
        class Target:
            name = 1

        name = Param((str, ))
        name.setup(Target, "name")

        assert not hasattr(Target, "name")
        assert hasattr(Target, "_name")
        assert Target._name == name
示例#17
0
class Destroyer(Mediator):
    install = Param('sentry.models.SentryAppInstallation')
    user = Param('sentry.models.User')
    request = Param('rest_framework.request.Request', required=False)

    def call(self):
        self._destroy_authorization()
        self._destroy_grant()
        self._destroy_service_hooks()
        self._destroy_installation()
        return self.install

    def _destroy_authorization(self):
        if self.install.authorization:
            self.install.authorization.delete()

    def _destroy_grant(self):
        if self.install.api_grant_id:
            self.install.api_grant.delete()

    def _destroy_service_hooks(self):
        hooks = ServiceHook.objects.filter(
            application_id=self.install.sentry_app.application_id,
            actor_id=self.install.id,
        )
        for hook in hooks:
            service_hooks.Destroyer.run(service_hook=hook)

    def _destroy_installation(self):
        InstallationNotifier.run(
            install=self.install,
            user=self.user,
            action='deleted',
        )
        self.install.delete()

    def audit(self):
        if self.request:
            create_audit_entry(
                request=self.request,
                organization=self.install.organization,
                target_object=self.install.organization.id,
                event=AuditLogEntryEvent.SENTRY_APP_UNINSTALL,
                data={
                    'sentry_app': self.install.sentry_app.name,
                },
            )

    def record_analytics(self):
        analytics.record(
            'sentry_app.uninstalled',
            user_id=self.user.id,
            organization_id=self.install.organization_id,
            sentry_app=self.install.sentry_app.slug,
        )
示例#18
0
文件: creator.py 项目: sugusbs/sentry
class Creator(Mediator):
    name = Param(six.string_types)
    environment = Param(int, required=False)
    project = Param("sentry.models.Project")
    action_match = Param(six.string_types)
    filter_match = Param(six.string_types, required=False)
    actions = Param(Iterable)
    conditions = Param(Iterable)
    frequency = Param(int)
    request = Param("rest_framework.request.Request", required=False)

    def call(self):
        self.rule = self._create_rule()
        return self.rule

    def _create_rule(self):
        kwargs = self._get_kwargs()
        rule = Rule.objects.create(**kwargs)
        return rule

    def _get_kwargs(self):
        data = {
            "filter_match": self.filter_match,
            "action_match": self.action_match,
            "actions": self.actions,
            "conditions": self.conditions,
            "frequency": self.frequency,
        }
        _kwargs = {
            "label": self.name,
            "environment_id": self.environment or None,
            "project": self.project,
            "data": data,
        }
        return _kwargs
示例#19
0
class Updater(Mediator):
    rule = Param("sentry.models.Rule")
    name = Param(six.string_types, required=False)
    environment = Param(int, required=False)
    project = Param("sentry.models.Project")
    action_match = Param(six.string_types, required=False)
    filter_match = Param(six.string_types, required=False)
    actions = Param(Iterable, required=False)
    conditions = Param(Iterable, required=False)
    frequency = Param(int, required=False)
    request = Param("rest_framework.request.Request", required=False)

    def call(self):
        self._update_name()
        self._update_environment()
        self._update_project()
        self._update_actions()
        self._update_action_match()
        self._update_filter_match()
        self._update_conditions()
        self._update_frequency()
        self.rule.save()
        return self.rule

    @if_param("name")
    def _update_name(self):
        self.rule.label = self.name

    def _update_environment(self):
        # environment can be None so we don't use the if_param decorator
        self.rule.environment_id = self.environment

    @if_param("project")
    def _update_project(self):
        self.rule.project = self.project

    @if_param("actions")
    def _update_actions(self):
        self.rule.data["actions"] = self.actions

    @if_param("action_match")
    def _update_action_match(self):
        self.rule.data["action_match"] = self.action_match

    @if_param("filter_match")
    def _update_filter_match(self):
        self.rule.data["filter_match"] = self.filter_match

    @if_param("conditions")
    def _update_conditions(self):
        self.rule.data["conditions"] = self.conditions

    @if_param("frequency")
    def _update_frequency(self):
        self.rule.data["frequency"] = self.frequency
示例#20
0
class Creator(Mediator):
    organization = Param('sentry.models.Organization')
    slug = Param(six.string_types)
    user = Param('sentry.models.User')

    def call(self):
        self._create_authorization()
        self._create_api_grant()
        self._create_install()
        self._create_service_hooks()
        self._notify_service()
        self.install.is_new = True
        return self.install

    def _create_authorization(self):
        self.authorization = ApiAuthorization.objects.create(
            application_id=self.api_application.id,
            user_id=self.sentry_app.proxy_user.id,
            scope_list=self.sentry_app.scope_list,
        )

    def _create_install(self):
        self.install = SentryAppInstallation.objects.create(
            organization_id=self.organization.id,
            sentry_app_id=self.sentry_app.id,
            authorization_id=self.authorization.id,
            api_grant_id=self.api_grant.id,
        )

    def _create_api_grant(self):
        self.api_grant = ApiGrant.objects.create(
            user_id=self.sentry_app.proxy_user.id,
            application_id=self.api_application.id,
        )

    def _create_service_hooks(self):
        service_hooks.Creator.run(
            application=self.api_application,
            actor=self.install,
            projects=[],
            organization=self.organization,
            events=self.sentry_app.events,
            url=self.sentry_app.webhook_url,
        )

    def _notify_service(self):
        installation_webhook.delay(self.install.id, self.user.id)

    @memoize
    def api_application(self):
        return self.sentry_app.application

    @memoize
    def sentry_app(self):
        return SentryApp.objects.get(slug=self.slug)
示例#21
0
文件: creator.py 项目: snow842/sentry
class Creator(Mediator):
    sentry_app_installation = Param('sentry.models.SentryAppInstallation')
    expires_at = Param(datetime.date, default=None, required=False)
    # analytics and audit params
    generate_audit = Param(bool, default=False)
    user = Param('sentry.models.User')
    request = Param('rest_framework.request.Request', required=False)

    def call(self):
        self._create_api_token()
        self._create_sentry_app_installation_token()
        return self.sentry_app_installation_token

    def _create_api_token(self):
        self.api_token = ApiToken.objects.create(
            user=self.sentry_app.proxy_user,
            application_id=self.sentry_app.application.id,
            scope_list=self.sentry_app.scope_list,
            expires_at=self.expires_at,
        )

    def _create_sentry_app_installation_token(self):
        self.sentry_app_installation_token = SentryAppInstallationToken.objects.create(
            api_token=self.api_token,
            sentry_app_installation=self.sentry_app_installation)

    def audit(self):
        from sentry.utils.audit import create_audit_entry
        if self.request and self.generate_audit:
            create_audit_entry(
                request=self.request,
                organization=self.organization,
                target_object=self.sentry_app_installation_token.id,
                event=AuditLogEntryEvent.INTERNAL_INTEGRATION_ADD_TOKEN,
                data={'sentry_app': self.sentry_app.name},
            )

    def record_analytics(self):
        from sentry import analytics
        analytics.record(
            'sentry_app_installation_token.created',
            user_id=self.user.id,
            organization_id=self.organization.id,
            sentry_app_installation_id=self.sentry_app_installation.id,
            sentry_app=self.sentry_app.slug,
        )

    @memoize
    def sentry_app(self):
        return self.sentry_app_installation.sentry_app

    @memoize
    def organization(self):
        return self.sentry_app_installation.organization
示例#22
0
class InstallationNotifier(Mediator):
    install = Param('sentry.models.SentryAppInstallation')
    user = Param('sentry.models.User')
    action = Param(six.string_types)

    def call(self):
        self._verify_action()
        self._send_webhook()

    def _verify_action(self):
        if self.action not in ['created', 'deleted']:
            raise APIUnauthorized(u"Invalid action '{}'".format(self.action))

    def _send_webhook(self):
        safe_urlread(
            safe_urlopen(
                url=self.sentry_app.webhook_url,
                data=self.request.body,
                headers=self.request.headers,
                timeout=5,
            ))

    @property
    def request(self):
        attrs = {}

        if self.install.is_new and self.api_grant:
            attrs['code'] = self.api_grant.code

        data = SentryAppInstallationSerializer().serialize(
            self.install,
            attrs=attrs,
            user=self.user,
        )

        return AppPlatformEvent(
            resource='installation',
            action=self.action,
            install=self.install,
            data={'installation': data},
            actor=self.user,
        )

    @memoize
    def sentry_app(self):
        return self.install.sentry_app

    @memoize
    def api_grant(self):
        return self.install.api_grant_id and self.install.api_grant
示例#23
0
class Destroyer(Mediator):
    api_token = Param("sentry.models.ApiToken")
    generate_audit = Param(bool, default=False)
    user = Param("sentry.models.User")
    request = Param("rest_framework.request.Request", required=False)

    def call(self):
        self._destroy_sentry_app_installation_token()
        self._destroy_api_token()
        return self.api_token

    def _destroy_api_token(self):
        self.api_token.delete()

    def _destroy_sentry_app_installation_token(self):
        install_token = SentryAppInstallationToken.objects.get(
            api_token=self.api_token)
        self.sentry_app_installation = install_token.sentry_app_installation
        install_token.delete()

    def audit(self):
        from sentry.utils.audit import create_audit_entry

        if self.request and self.generate_audit:
            create_audit_entry(
                request=self.request,
                organization=self.organization,
                target_object=self.api_token.id,
                event=AuditLogEntryEvent.INTERNAL_INTEGRATION_REMOVE_TOKEN,
                data={"sentry_app": self.sentry_app.name},
            )

    def record_analytics(self):
        from sentry import analytics

        analytics.record(
            "sentry_app_installation_token.deleted",
            user_id=self.user.id,
            organization_id=self.organization.id,
            sentry_app_installation_id=self.sentry_app_installation.id,
            sentry_app=self.sentry_app.slug,
        )

    @memoize
    def sentry_app(self):
        return self.sentry_app_installation.sentry_app

    @memoize
    def organization(self):
        return self.sentry_app_installation.organization
示例#24
0
class Creator(Mediator):
    name = Param(six.string_types)
    organization = Param('sentry.models.Organization')
    scopes = Param(Iterable)
    events = Param(Iterable, default=lambda self: [])
    webhook_url = Param(six.string_types)
    redirect_url = Param(six.string_types, required=False)
    is_alertable = Param(bool, default=False)
    schema = Param(dict, default=lambda self: {})
    overview = Param(six.string_types, required=False)

    def call(self):
        self.proxy = self._create_proxy_user()
        self.api_app = self._create_api_application()
        self.app = self._create_sentry_app()
        self._create_ui_components()
        return self.app

    def _create_proxy_user(self):
        return User.objects.create(
            username=self.name.lower(),
            is_sentry_app=True,
        )

    def _create_api_application(self):
        return ApiApplication.objects.create(
            owner_id=self.proxy.id,
        )

    def _create_sentry_app(self):
        from sentry.mediators.service_hooks.creator import expand_events

        return SentryApp.objects.create(
            name=self.name,
            application_id=self.api_app.id,
            owner_id=self.organization.id,
            proxy_user_id=self.proxy.id,
            scope_list=self.scopes,
            events=expand_events(self.events),
            schema=self.schema or {},
            webhook_url=self.webhook_url,
            redirect_url=self.redirect_url,
            is_alertable=self.is_alertable,
            overview=self.overview,
        )

    def _create_ui_components(self):
        schema = self.schema or {}

        for element in schema.get('elements', []):
            SentryAppComponent.objects.create(
                type=element['type'],
                sentry_app_id=self.app.id,
                schema=element,
            )
示例#25
0
文件: destroyer.py 项目: yndxz/sentry
class Destroyer(Mediator):
    sentry_app = Param('sentry.models.SentryApp')
    request = Param('rest_framework.request.Request', required=False)
    user = Param('sentry.models.User')

    def call(self):
        self._destroy_api_application()
        self._destroy_sentry_app_installations()
        self._destroy_proxy_user()
        self._destroy_sentry_app()
        return self.sentry_app

    def _destroy_sentry_app_installations(self):
        for install in self.sentry_app.installations.all():
            notify = False if self.sentry_app.is_internal else True
            sentry_app_installations.Destroyer.run(
                install=install,
                user=self.sentry_app.proxy_user,
                notify=notify,
            )

    def _destroy_api_application(self):
        self.sentry_app.application.delete()

    def _destroy_proxy_user(self):
        self.sentry_app.proxy_user.delete()

    def _destroy_sentry_app(self):
        self.sentry_app.delete()

    def audit(self):
        if self.request:
            create_audit_entry(
                request=self.request,
                organization=self.sentry_app.owner,
                target_object=self.sentry_app.owner.id,
                event=AuditLogEntryEvent.SENTRY_APP_REMOVE,
                data={
                    'sentry_app': self.sentry_app.name,
                },
            )

    def record_analytics(self):
        analytics.record(
            'sentry_app.deleted',
            user_id=self.user.id,
            organization_id=self.sentry_app.owner.id,
            sentry_app=self.sentry_app.slug,
        )
示例#26
0
class Updater(Mediator):
    sentry_app = Param('sentry.models.SentryApp')
    name = Param(six.string_types, required=False)
    scopes = Param(Iterable, required=False)
    events = Param(Iterable, required=False)
    webhook_url = Param(six.string_types, required=False)
    redirect_url = Param(six.string_types, required=False)
    is_alertable = Param(bool, required=False)
    overview = Param(six.string_types, required=False)

    def call(self):
        self._update_name()
        self._update_scopes()
        self._update_events()
        self._update_webhook_url()
        self._update_redirect_url()
        self._update_is_alertable()
        self._update_overview()
        self.sentry_app.save()
        return self.sentry_app

    @if_param('name')
    def _update_name(self):
        self.sentry_app.name = self.name

    @if_param('scopes')
    def _update_scopes(self):
        if self.sentry_app.status == SentryAppStatus.PUBLISHED:
            raise APIError('Cannot update scopes on published App.')
        self.sentry_app.scope_list = self.scopes

    @if_param('events')
    def _update_events(self):
        for event in self.events:
            needed_scope = REQUIRED_EVENT_PERMISSIONS[event]
            if needed_scope not in self.sentry_app.scope_list:
                raise APIError(
                    u'{} webhooks require the {} permission.'.format(
                        event, needed_scope), )

        from sentry.mediators.service_hooks.creator import expand_events
        self.sentry_app.events = expand_events(self.events)

    @if_param('webhook_url')
    def _update_webhook_url(self):
        self.sentry_app.webhook_url = self.webhook_url

    @if_param('redirect_url')
    def _update_redirect_url(self):
        self.sentry_app.redirect_url = self.redirect_url

    @if_param('is_alertable')
    def _update_is_alertable(self):
        self.sentry_app.is_alertable = self.is_alertable

    @if_param('overview')
    def _update_overview(self):
        self.sentry_app.overview = self.overview
示例#27
0
class Destroyer(Mediator):
    sentry_app = Param('sentry.models.SentryApp')

    def call(self):
        self._destroy_sentry_app_installations()
        self._destroy_api_application()
        self._destroy_proxy_user()
        self._destroy_sentry_app()
        return self.sentry_app

    def _destroy_sentry_app_installations(self):
        for install in self.sentry_app.installations.all():
            sentry_app_installations.Destroyer.run(
                install=install,
                user=self.sentry_app.proxy_user,
            )

    def _destroy_api_application(self):
        self.sentry_app.application.delete()

    def _destroy_proxy_user(self):
        self.sentry_app.proxy_user.delete()

    def _destroy_sentry_app(self):
        self.sentry_app.delete()
示例#28
0
class IssueLinkCreator(Mediator):
    install = Param('sentry.models.SentryAppInstallation')
    group = Param('sentry.models.Group')
    action = Param(six.string_types)
    fields = Param(object)
    uri = Param(six.string_types)

    def call(self):
        self._verify_action()
        self._make_external_request()
        self._create_external_issue()
        return self.external_issue

    def _verify_action(self):
        if self.action not in ['link', 'create']:
            return APIUnauthorized()

    def _make_external_request(self):
        self.response = external_requests.IssueLinkRequester.run(
            install=self.install,
            uri=self.uri,
            group=self.group,
            fields=self.fields,
        )

    def _format_response_data(self):
        web_url = self.response['webUrl']

        display_name = u'{}#{}'.format(
            self.response['project'],
            self.response['identifier'],
        )

        return [web_url, display_name]

    def _create_external_issue(self):
        web_url, display_name = self._format_response_data()
        self.external_issue = PlatformExternalIssue.objects.create(
            group_id=self.group.id,
            service_type=self.sentry_app.slug,
            display_name=display_name,
            web_url=web_url,
        )

    @memoize
    def sentry_app(self):
        return self.install.sentry_app
示例#29
0
class Destroyer(Mediator):
    service_hook = Param("sentry.models.ServiceHook")

    def call(self):
        self._destroy_service_hook()
        return self.service_hook

    def _destroy_service_hook(self):
        self.service_hook.delete()
示例#30
0
class Creator(Mediator):
    organization = Param('sentry.models.Organization')
    slug = Param(six.string_types)
    user = Param('sentry.models.User')

    def call(self):
        self._create_authorization()
        self._create_api_grant()
        self._create_install()
        self._notify_service()
        self.install.is_new = True
        return (self.install, self.api_grant)

    def _create_authorization(self):
        self.authorization = ApiAuthorization.objects.create(
            application=self.api_application,
            user=self.sentry_app.proxy_user,
            scope_list=self.sentry_app.scope_list,
        )

    def _create_install(self):
        self.install = SentryAppInstallation.objects.create(
            organization=self.organization,
            sentry_app=self.sentry_app,
            authorization=self.authorization,
            api_grant=self.api_grant,
        )

    def _create_api_grant(self):
        self.api_grant = ApiGrant.objects.create(
            user=self.sentry_app.proxy_user,
            application=self.api_application,
        )

    def _notify_service(self):
        installation_webhook.delay(self.install.id, self.user.id)

    @memoize
    def api_application(self):
        return self.sentry_app.application

    @memoize
    def sentry_app(self):
        return SentryApp.objects.get(slug=self.slug)
示例#31
0
 def test_lambda_default(self):
     _name = 'Steve'
     name = Param(six.string_types, default=lambda self: _name)
     assert name.default(None) == 'Steve'
示例#32
0
    def test_validate_required(self):
        name = Param(six.string_types)

        with self.assertRaises(AttributeError):
            name.validate(None, 'name', None)
示例#33
0
    def test_validate_default_type(self):
        name = Param(six.string_types, default=1)

        with self.assertRaises(TypeError):
            name.validate(None, 'name', None)
示例#34
0
 def test_validate_user_defined_type(self):
     user = Param('sentry.models.user.User')
     assert user.validate(None, 'user', User())
示例#35
0
 def test_default(self):
     name = Param(six.string_types, default='Pete')
     assert name.default(None) == 'Pete'