Example #1
0
    def test_simple(self):
        project = self.create_project()

        self.login_as(user=self.user)

        plugins.get('webhooks').enable(project)

        url = reverse('sentry-api-0-project-plugin-details',
                      kwargs={
                          'organization_slug': project.organization.slug,
                          'project_slug': project.slug,
                          'plugin_id': 'webhooks',
                      })
        audit = AuditLogEntry.objects.filter(target_object=project.id)

        assert not audit

        response = self.client.delete(url)
        audit = AuditLogEntry.objects.get(target_object=project.id)

        assert audit.event == 112
        assert response.status_code == 204, (response.status_code,
                                             response.content)
        assert ProjectOption.objects.get(
            key='webhooks:enabled',
            project=project,
        ).value is False
    def test_simple(self):
        project = self.create_project()

        self.login_as(user=self.user)

        plugins.get('webhooks').enable(project)

        url = reverse(
            'sentry-api-0-project-plugin-details',
            kwargs={
                'organization_slug': project.organization.slug,
                'project_slug': project.slug,
                'plugin_id': 'webhooks',
            }
        )
        audit = AuditLogEntry.objects.filter(target_object=project.id)

        assert not audit

        response = self.client.delete(url)
        audit = AuditLogEntry.objects.get(target_object=project.id)

        assert audit.event == 112
        assert response.status_code == 204, (response.status_code, response.content)
        assert ProjectOption.objects.get(
            key='webhooks:enabled',
            project=project,
        ).value is False
    def test_simple(self, test_configuration):
        project = self.create_project()

        self.login_as(user=self.user)

        plugins.get('webhooks').disable(project)

        url = reverse(
            'sentry-api-0-project-plugin-details',
            kwargs={
                'organization_slug': project.organization.slug,
                'project_slug': project.slug,
                'plugin_id': 'webhooks',
            }
        )
        response = self.client.post(url)
        assert response.status_code == 201, (response.status_code, response.content)
        assert ProjectOption.objects.get(
            key='webhooks:enabled',
            project=project,
        ).value is True

        # Testing the Plugin
        response = self.client.post(url, {'test': True})
        test_configuration.assert_called_once_with(project)
        assert response.status_code == 200, (response.status_code, response.content)
    def test_exposes_plugins_across_all_org_projects(self):
        projectA = self.create_project()
        projectB = self.create_project(organization=projectA.organization)

        plugins.get('webhooks').enable(projectA)
        plugins.get('mail').enable(projectB)

        self.login_as(user=self.user)

        url = reverse(
            'sentry-api-0-organization-plugins',
            kwargs={'organization_slug': projectA.organization.slug}
        )

        response = self.client.get(url)

        assert response.status_code == 200, \
            (response.status_code, response.content)

        enabled_plugins = [
            (p['project']['id'], p['slug']) for p in
            filter(lambda p: p['enabled'], response.data)
        ]

        assert (projectA.id, 'webhooks') in enabled_plugins
        assert (projectB.id, 'mail') in enabled_plugins
    def setUp(self):
        self.projectA = self.create_project()
        self.projectB = self.create_project(organization=self.projectA.organization)

        plugins.get('webhooks').enable(self.projectA)
        plugins.get('mail').enable(self.projectB)

        self.login_as(user=self.user)
    def handle(self, request, organization, team, project, slug):
        try:
            plugin = plugins.get(slug)
        except KeyError:
            return self.redirect(reverse('sentry-manage-project', args=[project.organization.slug, project.slug]))

        if not plugin.can_configure_for_project(project):
            return self.redirect(reverse('sentry-manage-project', args=[project.organization.slug, project.slug]))

        react_plugin = None
        is_enabled = plugin.is_enabled(project)
        if isinstance(plugin, IssueTrackingPlugin2) or isinstance(plugin, NotificationPlugin):
            view = None
            response = client.get('/projects/{}/{}/plugins/{}/'.format(
                organization.slug,
                project.slug,
                slug,
            ), request=request)
            react_plugin = response.data
        else:
            view = plugin.configure(request=request, project=project)
            if isinstance(view, HttpResponse):
                return view

        context = {
            'page': 'plugin',
            'title': plugin.get_title(),
            'view': view,
            'plugin': plugin,
            'plugin_is_enabled': is_enabled,
            'react_plugin': react_plugin,
        }

        return self.respond('sentry/projects/plugins/configure.html', context)
Example #7
0
    def after(self, event, state):
        service = self.get_option('service')

        extra = {'event_id': event.id}
        if not service:
            self.logger.info('rules.fail.is_configured', extra=extra)
            return

        app = None
        try:
            app = SentryApp.objects.get(slug=service)
        except SentryApp.DoesNotExist:
            pass

        if app:
            kwargs = {'sentry_app': app}
            metrics.incr('notifications.sent', instance=app.slug, skip_internal=False)
            yield self.future(notify_sentry_app, **kwargs)
        else:
            plugin = plugins.get(service)
            if not plugin.is_enabled(self.project):
                extra['project_id'] = self.project.id
                self.logger.info('rules.fail.is_enabled', extra=extra)
                return

            group = event.group

            if not plugin.should_notify(group=group, event=event):
                extra['group_id'] = group.id
                self.logger.info('rule.fail.should_notify', extra=extra)
                return

            metrics.incr('notifications.sent', instance=plugin.slug, skip_internal=False)
            yield self.future(plugin.rule_notify)
Example #8
0
def configure_project_plugin(request, organization, project, slug):
    try:
        plugin = plugins.get(slug)
    except KeyError:
        return HttpResponseRedirect(reverse('sentry-manage-project', args=[project.organization.slug, project.slug]))

    if not plugin.can_configure_for_project(project):
        return HttpResponseRedirect(reverse('sentry-manage-project', args=[project.organization.slug, project.slug]))

    view = plugin.configure(request, project=project)
    if isinstance(view, HttpResponse):
        return view

    context = csrf(request)
    context.update({
        'organization': organization,
        'team': project.team,
        'page': 'plugin',
        'title': plugin.get_title(),
        'view': view,
        'project': project,
        'plugin': plugin,
        'plugin_is_enabled': plugin.is_enabled(project),
    })

    return render_to_response('sentry/projects/plugins/configure.html',
                              context, request)
Example #9
0
    def setupPluginTest(self):
        self.project = Project.objects.create(
            organization_id=self.organization.id,
        )

        self.plugin = plugins.get('vsts')
        self.plugin.enable(self.project)
Example #10
0
def configure_project_plugin(request, project, slug):
    try:
        plugin = plugins.get(slug)
    except KeyError:
        return HttpResponseRedirect(reverse('sentry-manage-project', args=[project.slug]))

    if not plugin.is_enabled(project):
        return HttpResponseRedirect(reverse('sentry-manage-project', args=[project.slug]))

    result = plugins.first('has_perm', request.user, 'configure_project_plugin', project, plugin)
    if result is False and not request.user.is_superuser:
        return HttpResponseRedirect(reverse('sentry'))

    form = plugin.project_conf_form
    if form is None:
        return HttpResponseRedirect(reverse('sentry-manage-project', args=[project.slug]))

    action, view = plugin_config(plugin, project, request)
    if action == 'redirect':
        return HttpResponseRedirect(request.path + '?success=1')

    context = csrf(request)
    context.update({
        'page': 'plugin',
        'title': plugin.get_title(),
        'view': view,
        'project': project,
        'plugin': plugin,
    })

    return render_to_response('sentry/projects/plugins/configure.html', context, request)
Example #11
0
    def test_disable_plugin_when_fully_migrated(self):
        self._stub_github()

        project = Project.objects.create(
            organization_id=self.organization.id,
        )

        plugin = plugins.get('github')
        plugin.enable(project)

        # Accessible to new Integration - mocked in _stub_github
        Repository.objects.create(
            organization_id=self.organization.id,
            name='Test-Organization/foo',
            url='https://github.com/Test-Organization/foo',
            provider='github',
            external_id='123',
            config={
                'name': 'Test-Organization/foo',
            },
        )

        # Enabled before
        assert 'github' in [p.slug for p in plugins.for_project(project)]

        with self.tasks():
            self.assert_setup_flow()

        # Disabled after Integration installed
        assert 'github' not in [p.slug for p in plugins.for_project(project)]
Example #12
0
    def test_integrated(self):
        event = self.create_event()

        action_data = {
            'id': 'sentry.rules.actions.notify_event.NotifyEventAction',
        }
        condition_data = {
            'id': 'sentry.rules.conditions.every_event.EveryEventCondition',
        }

        Rule.objects.filter(project=event.project).delete()
        rule = Rule.objects.create(
            project=event.project,
            data={
                'conditions': [condition_data],
                'actions': [action_data],
            }
        )

        rp = RuleProcessor(event, is_new=True, is_regression=True, is_sample=False)
        results = list(rp.apply())
        assert len(results) == 1
        callback, futures = results[0]
        assert callback == plugins.get('mail').rule_notify
        assert len(futures) == 1
        assert futures[0].rule == rule
        assert futures[0].kwargs == {}
Example #13
0
    def after(self, event, state):
        service = self.get_option('service')

        extra = {'event_id': event.id}
        if not service:
            self.logger.info('rules.fail.is_configured', extra=extra)
            return

        app = None
        try:
            app = SentryApp.objects.get(slug=service)
        except SentryApp.DoesNotExist:
            pass

        if app:
            kwargs = {'sentry_app': app}
            metrics.incr('notifications.sent', instance=app.slug)
            yield self.future(notify_sentry_app, **kwargs)
        else:
            plugin = plugins.get(service)
            if not plugin.is_enabled(self.project):
                extra['project_id'] = self.project.id
                self.logger.info('rules.fail.is_enabled', extra=extra)
                return

            group = event.group

            if not plugin.should_notify(group=group, event=event):
                extra['group_id'] = group.id
                self.logger.info('rule.fail.should_notify', extra=extra)
                return

            metrics.incr('notifications.sent', instance=plugin.slug)
            yield self.future(plugin.rule_notify)
Example #14
0
    def test_get(self):
        project = self.create_project()

        issues = plugins.get('issuetrackingplugin2')
        with patch.object(issues, 'is_hidden', return_value=True):
            self.login_as(user=self.user)

            url = reverse(
                'sentry-api-0-project-plugins',
                kwargs={
                    'organization_slug': project.organization.slug,
                    'project_slug': project.slug,
                }
            )
            response = self.client.get(url)

        assert response.status_code == 200, (response.status_code, response.content)
        assert len(response.data) >= 9

        auto_tag = response.data[0]
        assert auto_tag['name'] == 'Auto Tag: Browsers'
        assert auto_tag['enabled'] is True
        assert auto_tag['isHidden'] is False
        self.assert_plugin_shape(auto_tag)

        issues = filter(lambda p: p['slug'] == 'issuetrackingplugin2', response.data)[0]
        assert issues['name'] == 'IssueTrackingPlugin2'
        assert issues['enabled'] is False
        assert issues['isHidden'] is True
        self.assert_plugin_shape(issues)
Example #15
0
    def post(self, request, plugin_id, project_id, signature):
        project = Project.objects.get_from_cache(id=project_id)

        token = ProjectOption.objects.get_value(project,
                                                'sentry:release-token')

        logger.info('Incoming webhook for project_id=%s, plugin_id=%s',
                    project_id, plugin_id)

        if not self.verify(plugin_id, project_id, token, signature):
            logger.warn('Unable to verify signature for release hook')
            return HttpResponse(status=403)

        if plugin_id == 'builtin':
            return self._handle_builtin(request, project)

        plugin = plugins.get(plugin_id)
        if not plugin.is_enabled(project):
            logger.warn(
                'Disabled release hook received for project_id=%s, plugin_id=%s',
                project_id, plugin_id)
            return HttpResponse(status=403)

        cls = plugin.get_release_hook()
        hook = cls(project)
        try:
            hook.handle(request)
        except HookValidationError as exc:
            return HttpResponse(
                status=400,
                content=json.dumps({'error': six.text_type(exc)}),
                content_type='application/json',
            )

        return HttpResponse(status=204)
    def post(self, request, organization, team, project, slug):
        try:
            plugin = plugins.get(slug)
        except KeyError:
            return self.redirect(
                reverse(
                    'sentry-configure-project-plugin',
                    args=[project.organization.slug, project.slug, slug]
                )
            )

        if plugin.is_enabled(project):
            return self.redirect(
                reverse(
                    'sentry-configure-project-plugin',
                    args=[project.organization.slug, project.slug, slug]
                )
            )

        plugin.enable(project=project)

        plugin_enabled.send(plugin=plugin, project=project, user=request.user, sender=self)

        return self.redirect(
            reverse(
                'sentry-configure-project-plugin',
                args=[project.organization.slug, project.slug, slug]
            )
        )
Example #17
0
    def post(self, request, plugin_id, project_id, signature):
        try:
            project = Project.objects.get_from_cache(id=project_id)
        except Project.DoesNotExist:
            logger.warn('release-webhook.invalid-project',
                        extra={
                            'project_id': project_id,
                            'plugin_id': plugin_id,
                        })
            return HttpResponse(status=404)

        logger.info('release-webhook.incoming',
                    extra={
                        'project_id': project_id,
                        'plugin_id': plugin_id,
                    })

        token = ProjectOption.objects.get_value(project,
                                                'sentry:release-token')

        if token is None:
            logger.warn('release-webhook.missing-token',
                        extra={
                            'project_id': project_id,
                            'plugin_id': plugin_id,
                        })
            return HttpResponse(status=403)

        if not self.verify(plugin_id, project_id, token, signature):
            logger.warn('release-webhook.invalid-signature',
                        extra={
                            'project_id': project_id,
                            'plugin_id': plugin_id,
                        })
            return HttpResponse(status=403)

        if plugin_id == 'builtin':
            return self._handle_builtin(request, project)

        plugin = plugins.get(plugin_id)
        if not plugin.is_enabled(project):
            logger.warn('release-webhook.plugin-disabled',
                        extra={
                            'project_id': project_id,
                            'plugin_id': plugin_id,
                        })
            return HttpResponse(status=403)

        cls = plugin.get_release_hook()
        hook = cls(project)
        try:
            hook.handle(request)
        except HookValidationError as exc:
            return HttpResponse(
                status=400,
                content=json.dumps({'error': six.text_type(exc)}),
                content_type='application/json',
            )

        return HttpResponse(status=204)
Example #18
0
    def test_disable_plugin_when_fully_migrated(self):
        self._stub_github()

        project = Project.objects.create(
            organization_id=self.organization.id, )

        plugin = plugins.get('github')
        plugin.enable(project)

        # Accessible to new Integration - mocked in _stub_github
        Repository.objects.create(
            organization_id=self.organization.id,
            name='Test-Organization/foo',
            url='https://github.com/Test-Organization/foo',
            provider='github',
            external_id='123',
            config={
                'name': 'Test-Organization/foo',
            },
        )

        # Enabled before
        assert 'github' in [p.slug for p in plugins.for_project(project)]

        with self.tasks():
            self.assert_setup_flow()

        # Disabled after Integration installed
        assert 'github' not in [p.slug for p in plugins.for_project(project)]
Example #19
0
 def _handle_disable_plugin(self, request, project):
     plugin = plugins.get(request.POST['plugin'])
     plugin.disable(project)
     messages.add_message(
         request, messages.SUCCESS,
         constants.OK_PLUGIN_DISABLED.format(name=plugin.get_title()),
     )
Example #20
0
    def post(self, request, plugin_id, project_id, signature):
        project = Project.objects.get_from_cache(id=project_id)

        token = ProjectOption.objects.get_value(project,
                                                'sentry:release-token')

        logging.info('Incoming webhook for project_id=%s, plugin_id=%s',
                     project_id, plugin_id)

        if not self.verify(plugin_id, project_id, token, signature):
            logging.warn('Unable to verify signature for release hook')
            return HttpResponse(status=403)

        if plugin_id == 'builtin':
            return self._handle_builtin(request, project)

        plugin = plugins.get(plugin_id)
        if not plugin.is_enabled(project):
            logging.warn(
                'Disabled release hook received for project_id=%s, plugin_id=%s',
                project_id, plugin_id)
            return HttpResponse(status=403)

        cls = plugin.get_release_hook()
        hook = cls(project)
        hook.handle(request)

        return HttpResponse(status=204)
    def handle(self, request, organization, team, project, slug):
        try:
            plugin = plugins.get(slug)
        except KeyError:
            return self.redirect(reverse('sentry-manage-project', args=[project.organization.slug, project.slug]))

        if not plugin.can_configure_for_project(project):
            return self.redirect(reverse('sentry-manage-project', args=[project.organization.slug, project.slug]))

        issue_v2_plugin = None
        is_enabled = plugin.is_enabled(project)
        if isinstance(plugin, IssueTrackingPlugin2):
            view = None
            issue_v2_plugin = {
                'title': plugin.get_title(),
                'slug': plugin.slug,
                'can_disable': plugin.can_disable,
                'is_enabled': is_enabled
            }
        else:
            view = plugin.configure(request=request, project=project)
            if isinstance(view, HttpResponse):
                return view

        context = {
            'page': 'plugin',
            'title': plugin.get_title(),
            'view': view,
            'plugin': plugin,
            'plugin_is_enabled': is_enabled,
            'issue_v2_plugin': issue_v2_plugin
        }

        return self.respond('sentry/projects/plugins/configure.html', context)
Example #22
0
def configure_project_plugin(request, project, slug):
    try:
        plugin = plugins.get(slug)
    except KeyError:
        return HttpResponseRedirect(reverse('sentry-manage-project', args=[project.slug]))

    if not plugin.is_enabled(project):
        return HttpResponseRedirect(reverse('sentry-manage-project', args=[project.slug]))

    result = plugins.first('has_perm', request.user, 'configure_project_plugin', project, plugin)
    if result is False and not request.user.is_superuser:
        return HttpResponseRedirect(reverse('sentry'))

    form = plugin.project_conf_form
    if form is None:
        return HttpResponseRedirect(reverse('sentry-manage-project', args=[project.slug]))

    action, view = plugin_config(plugin, project, request)
    if action == 'redirect':
        return HttpResponseRedirect(request.path + '?success=1')

    context = csrf(request)
    context.update({
        'page': 'plugin',
        'title': plugin.get_title(),
        'view': view,
        'project': project,
        'plugin': plugin,
    })

    return render_to_response('sentry/projects/plugins/configure.html', context, request)
    def handle(self, request, organization, team, project, slug):
        try:
            plugin = plugins.get(slug)
        except KeyError:
            return self.redirect(
                reverse('sentry-manage-project',
                        args=[project.organization.slug, project.slug]))

        if not plugin.can_configure_for_project(project):
            return self.redirect(
                reverse('sentry-manage-project',
                        args=[project.organization.slug, project.slug]))

        is_enabled = plugin.is_enabled(project)
        view = plugin.configure(request=request, project=project)
        if isinstance(view, HttpResponse):
            return view

        context = {
            'page': 'plugin',
            'title': plugin.get_title(),
            'view': view,
            'plugin': plugin,
            'plugin_is_enabled': is_enabled,
        }

        return self.respond('sentry/projects/plugins/configure.html', context)
Example #24
0
    def after(self, event, state):
        mail_plugin = plugins.get('mail')
        if not mail_plugin.is_enabled(event.project):
            return

        username = self.get_option('username')
        try:
            user = User.objects.get(username=username)
        except:
            return

        project = event.project
        group = event.group

        subject_prefix = mail_plugin.get_option('subject_prefix', project) or settings.EMAIL_SUBJECT_PREFIX

        interface_list = []
        for interface in event.interfaces.itervalues():
            body = interface.to_email_html(event)
            if not body:
                continue
            interface_list.append((interface.get_title(), mark_safe(body)))

        subject = group.get_email_subject()

        link = group.get_absolute_url()

        template = 'sentry/emails/error.txt'
        html_template = 'sentry/emails/error.html'

        context = {
            'group': group,
            'event': event,
            'tags': event.get_tags(),
            'link': link,
            'interfaces': interface_list,
            'rule': None,
            'rule_link': None,
        }

        headers = {
            'X-Sentry-Logger': group.logger,
            'X-Sentry-Logger-Level': group.get_level_display(),
            'X-Sentry-Project': project.name,
            'X-Sentry-Reply-To': group_id_to_email(group.id),
        }

        msg = MessageBuilder(
            subject='%s%s' % (subject_prefix, subject),
            template=template,
            html_template=html_template,
            body=body,
            headers=headers,
            context=context,
            reference=group,
        )


        msg.add_users([user.id], project=project)
        return msg.send()
Example #25
0
    def post(self, request, plugin_id, project_id, signature):
        project = Project.objects.get_from_cache(id=project_id)

        token = ProjectOption.objects.get_value(project, 'sentry:release-token')

        logger.info('Incoming webhook for project_id=%s, plugin_id=%s',
                    project_id, plugin_id)

        if not self.verify(plugin_id, project_id, token, signature):
            logger.warn('Unable to verify signature for release hook')
            return HttpResponse(status=403)

        if plugin_id == 'builtin':
            return self._handle_builtin(request, project)

        plugin = plugins.get(plugin_id)
        if not plugin.is_enabled(project):
            logger.warn('Disabled release hook received for project_id=%s, plugin_id=%s',
                        project_id, plugin_id)
            return HttpResponse(status=403)

        cls = plugin.get_release_hook()
        hook = cls(project)
        hook.handle(request)

        return HttpResponse(status=204)
Example #26
0
    def test_disable_plugin_when_fully_migrated(self):
        self._stub_github()

        project = Project.objects.create(organization_id=self.organization.id)

        plugin = plugins.get("github")
        plugin.enable(project)

        # Accessible to new Integration - mocked in _stub_github
        Repository.objects.create(
            organization_id=self.organization.id,
            name="Test-Organization/foo",
            url="https://github.com/Test-Organization/foo",
            provider="github",
            external_id="123",
            config={"name": "Test-Organization/foo"},
        )

        # Enabled before
        assert "github" in [p.slug for p in plugins.for_project(project)]

        with self.tasks():
            self.assert_setup_flow()

        # Disabled after Integration installed
        assert "github" not in [p.slug for p in plugins.for_project(project)]
Example #27
0
def configure_project_plugin(request, project, slug):
    try:
        plugin = plugins.get(slug)
    except KeyError:
        return HttpResponseRedirect(reverse("sentry-manage-project", args=[project.slug]))

    if not plugin.is_enabled(project):
        return HttpResponseRedirect(reverse("sentry-manage-project", args=[project.slug]))

    result = plugins.first("has_perm", request.user, "configure_project_plugin", project, plugin)
    if result is False and not request.user.is_superuser:
        return HttpResponseRedirect(reverse("sentry"))

    form = plugin.project_conf_form
    if form is None:
        return HttpResponseRedirect(reverse("sentry-manage-project", args=[project.slug]))

    action, view = plugin_config(plugin, project, request)
    if action == "redirect":
        return HttpResponseRedirect(request.path + "?success=1")

    context = csrf(request)
    context.update({"page": "plugin", "title": plugin.get_title(), "view": view, "project": project, "plugin": plugin})

    return render_to_response("sentry/projects/plugins/configure.html", context, request)
    def test_get(self):
        project = self.create_project()

        issues = plugins.get('issuetrackingplugin2')
        with patch.object(issues, 'is_hidden', return_value=True):
            self.login_as(user=self.user)

            url = reverse('sentry-api-0-project-plugins',
                          kwargs={
                              'organization_slug': project.organization.slug,
                              'project_slug': project.slug,
                          })
            response = self.client.get(url)

        assert response.status_code == 200, (response.status_code,
                                             response.content)
        assert len(response.data) >= 9

        auto_tag = response.data[0]
        assert auto_tag['name'] == 'Auto Tag: Browsers'
        assert auto_tag['enabled'] is True
        assert auto_tag['isHidden'] is False
        self.assert_plugin_shape(auto_tag)

        issues = filter(lambda p: p['slug'] == 'issuetrackingplugin2',
                        response.data)[0]
        assert issues['name'] == 'IssueTrackingPlugin2'
        assert issues['enabled'] is False
        assert issues['isHidden'] is True
        self.assert_plugin_shape(issues)
Example #29
0
 def _handle_disable_plugin(self, request, project):
     plugin = plugins.get(request.POST['plugin'])
     plugin.set_option('enabled', False, project)
     messages.add_message(
         request, messages.SUCCESS,
         constants.OK_PLUGIN_DISABLED.format(name=plugin.get_title()),
     )
Example #30
0
    def post(self, request, plugin_id, project_id, signature):
        project = Project.objects.get_from_cache(id=project_id)

        token = ProjectOption.objects.get_value(project, 'sentry:release-token')

        logger.info('Incoming webhook for project_id=%s, plugin_id=%s',
                    project_id, plugin_id)

        if not self.verify(plugin_id, project_id, token, signature):
            logger.warn('Unable to verify signature for release hook')
            return HttpResponse(status=403)

        if plugin_id == 'builtin':
            return self._handle_builtin(request, project)

        plugin = plugins.get(plugin_id)
        if not plugin.is_enabled(project):
            logger.warn('Disabled release hook received for project_id=%s, plugin_id=%s',
                        project_id, plugin_id)
            return HttpResponse(status=403)

        cls = plugin.get_release_hook()
        hook = cls(project)
        try:
            hook.handle(request)
        except HookValidationError as exc:
            return HttpResponse(
                status=400,
                content=json.dumps({'error': six.text_type(exc)}),
                content_type='application/json',
            )

        return HttpResponse(status=204)
Example #31
0
 def handle(self, request, organization, project):
     # store project and org in session
     # redirect user to hipchat page
     request.session[HIPCHAT_ORG_PREFERENCE] = organization.id
     request.session[HIPCHAT_PROJECT_PREFERENCE] = project.id
     plugin = plugins.get('hipchat-ac')
     return HttpResponseRedirect(plugin.get_install_url())
Example #32
0
def configure_project_plugin(request, organization, project, slug):
    try:
        plugin = plugins.get(slug)
    except KeyError:
        return HttpResponseRedirect(reverse('sentry-manage-project', args=[project.organization.slug, project.slug]))

    if not plugin.can_enable_for_projects():
        return HttpResponseRedirect(reverse('sentry-manage-project', args=[project.organization.slug, project.slug]))

    form = plugin.project_conf_form
    if form is None:
        return HttpResponseRedirect(reverse('sentry-manage-project', args=[project.organization.slug, project.slug]))

    action, view = plugin_config(plugin, project, request)
    if action == 'redirect':
        messages.add_message(
            request, messages.SUCCESS,
            _('Your settings were saved successfully.'))

        return HttpResponseRedirect(request.path)

    context = csrf(request)
    context.update({
        'organization': organization,
        'team': project.team,
        'page': 'plugin',
        'title': plugin.get_title(),
        'view': view,
        'project': project,
        'plugin': plugin,
        'plugin_is_enabled': plugin.is_enabled(project),
    })

    return render_to_response('sentry/projects/plugins/configure.html', context, request)
    def post(self, request, organization, team, project, slug):
        try:
            plugin = plugins.get(slug)
        except KeyError:
            return self.redirect(
                reverse(
                    'sentry-configure-project-plugin',
                    args=[project.organization.slug, project.slug, slug]
                )
            )

        if not plugin.is_enabled(project):
            return self.redirect(
                reverse(
                    'sentry-configure-project-plugin',
                    args=[project.organization.slug, project.slug, slug]
                )
            )

        plugin.disable(project=project)

        return self.redirect(
            reverse(
                'sentry-configure-project-plugin',
                args=[project.organization.slug, project.slug, slug]
            )
        )
Example #34
0
 def _handle_enable_plugin(self, request, project):
     plugin = plugins.get(request.POST['plugin'])
     plugin.enable(project)
     messages.add_message(
         request, messages.SUCCESS,
         constants.OK_PLUGIN_ENABLED.format(name=plugin.get_title()),
     )
Example #35
0
    def test_integrated(self):
        event = self.create_event()

        action_data = {
            'id': 'sentry.rules.actions.notify_event.NotifyEventAction',
        }
        condition_data = {
            'id': 'sentry.rules.conditions.every_event.EveryEventCondition',
        }

        Rule.objects.filter(project=event.project).delete()
        rule = Rule.objects.create(project=event.project,
                                   data={
                                       'conditions': [condition_data],
                                       'actions': [action_data],
                                   })

        rp = RuleProcessor(event,
                           is_new=True,
                           is_regression=True,
                           is_sample=False)
        results = list(rp.apply())
        assert len(results) == 1
        callback, futures = results[0]
        assert callback == plugins.get('mail').rule_notify
        assert len(futures) == 1
        assert futures[0].rule == rule
        assert futures[0].kwargs == {}
Example #36
0
    def after(self, event, state):
        service = self.get_option('service')

        extra = {
            'event_id': event.id
        }
        if not service:
            self.logger.info('rules.fail.is_configured', extra=extra)
            return

        plugin = plugins.get(service)
        if not plugin.is_enabled(self.project):
            extra['project_id'] = self.project.id
            self.logger.info('rules.fail.is_enabled', extra=extra)
            return

        group = event.group

        if not plugin.should_notify(group=group, event=event):
            extra['group_id'] = group.id
            self.logger.info('rule.fail.should_notify', extra=extra)
            return

        metrics.incr('notifications.sent', instance=plugin.slug)
        yield self.future(plugin.rule_notify)
Example #37
0
    def test_simple(self, test_configuration):
        project = self.create_project()

        self.login_as(user=self.user)

        plugins.get('webhooks').disable(project)

        url = reverse('sentry-api-0-project-plugin-details',
                      kwargs={
                          'organization_slug': project.organization.slug,
                          'project_slug': project.slug,
                          'plugin_id': 'webhooks',
                      })
        audit = AuditLogEntry.objects.filter(target_object=project.id)

        assert not audit

        response = self.client.post(url)
        audit = AuditLogEntry.objects.get(target_object=project.id)

        assert audit.event == 110
        assert response.status_code == 201, (response.status_code,
                                             response.content)
        assert ProjectOption.objects.get(
            key='webhooks:enabled',
            project=project,
        ).value is True
        audit.delete()

        # Testing the Plugin
        response = self.client.post(url, {'test': True})
        test_configuration.assert_called_once_with(project)
        assert response.status_code == 200, (response.status_code,
                                             response.content)

        # Reset the plugin
        response = self.client.post(url, {'reset': True})
        audit = AuditLogEntry.objects.get(target_object=project.id)
        test_configuration.assert_called_once_with(project)
        assert audit.event == 111
        assert response.status_code == 200, (response.status_code,
                                             response.content)

        configs = response.data.get('config')

        for config in configs:
            assert config.get('value') is None
Example #38
0
    def test_simple(self, test_configuration):
        project = self.create_project()

        self.login_as(user=self.user)

        plugins.get("webhooks").disable(project)

        url = reverse(
            "sentry-api-0-project-plugin-details",
            kwargs={
                "organization_slug": project.organization.slug,
                "project_slug": project.slug,
                "plugin_id": "webhooks",
            },
        )
        audit = AuditLogEntry.objects.filter(target_object=project.id)

        assert not audit

        response = self.client.post(url)
        audit = AuditLogEntry.objects.get(target_object=project.id)

        assert audit.event == 110
        assert response.status_code == 201, (response.status_code,
                                             response.content)
        assert ProjectOption.objects.get(key="webhooks:enabled",
                                         project=project).value is True
        audit.delete()

        # Testing the Plugin
        response = self.client.post(url, {"test": True})
        test_configuration.assert_called_once_with(project)
        assert response.status_code == 200, (response.status_code,
                                             response.content)

        # Reset the plugin
        response = self.client.post(url, {"reset": True})
        audit = AuditLogEntry.objects.get(target_object=project.id)
        test_configuration.assert_called_once_with(project)
        assert audit.event == 111
        assert response.status_code == 200, (response.status_code,
                                             response.content)

        configs = response.data.get("config")

        for config in configs:
            assert config.get("value") is None
    def test_simple(self, test_configuration):
        project = self.create_project()

        self.login_as(user=self.user)

        plugins.get('webhooks').disable(project)

        url = reverse(
            'sentry-api-0-project-plugin-details',
            kwargs={
                'organization_slug': project.organization.slug,
                'project_slug': project.slug,
                'plugin_id': 'webhooks',
            }
        )
        audit = AuditLogEntry.objects.filter(target_object=project.id)

        assert not audit

        response = self.client.post(url)
        audit = AuditLogEntry.objects.get(target_object=project.id)

        assert audit.event == 110
        assert response.status_code == 201, (response.status_code, response.content)
        assert ProjectOption.objects.get(
            key='webhooks:enabled',
            project=project,
        ).value is True
        audit.delete()

        # Testing the Plugin
        response = self.client.post(url, {'test': True})
        test_configuration.assert_called_once_with(project)
        assert response.status_code == 200, (response.status_code, response.content)

        # Reset the plugin
        response = self.client.post(url, {'reset': True})
        audit = AuditLogEntry.objects.get(target_object=project.id)
        test_configuration.assert_called_once_with(project)
        assert audit.event == 111
        assert response.status_code == 200, (response.status_code, response.content)

        configs = response.data.get('config')

        for config in configs:
            assert config.get('value') is None
Example #40
0
 def _handle_enable_plugin(self, request, project):
     plugin = plugins.get(request.POST['plugin'])
     plugin.set_option('enabled', True, project)
     messages.add_message(
         request,
         messages.SUCCESS,
         constants.OK_PLUGIN_ENABLED.format(name=plugin.get_title()),
     )
Example #41
0
def plugin_post_process_group(plugin_slug, event, **kwargs):
    """
    Fires post processing hooks for a group.
    """
    Raven.tags_context({
        'project': event.project_id,
    })
    plugin = plugins.get(plugin_slug)
    safe_execute(plugin.post_process, event=event, group=event.group, **kwargs)
Example #42
0
 def setUp(self):
     super(IssuePlugin2GroupAction, self).setUp()
     self.project = self.create_project()
     self.group = self.create_group(project=self.project)
     self.plugin_instance = plugins.get(slug='issuetrackingplugin2')
     self.event = self.create_event(
         event_id='a',
         group=self.group,
     )
Example #43
0
 def setUp(self):
     super(IssuePlugin2GroupAction, self).setUp()
     self.project = self.create_project()
     self.group = self.create_group(project=self.project)
     self.plugin_instance = plugins.get(slug='issuetrackingplugin2')
     self.event = self.create_event(
         event_id='a',
         group=self.group,
     )
Example #44
0
 def setUp(self):
     super(IssuePlugin2GroupActionTest, self).setUp()
     self.project = self.create_project()
     self.plugin_instance = plugins.get(slug="issuetrackingplugin2")
     min_ago = iso_format(before_now(minutes=1))
     self.event = self.store_event(
         data={"timestamp": min_ago, "fingerprint": ["group-1"]}, project_id=self.project.id
     )
     self.group = self.event.group
Example #45
0
    def test_disable_for_all_projects(self):
        plugin = plugins.get('example')
        plugin.enable(self.project)

        assert plugin in plugins.for_project(self.project)

        self.migrator.disable_for_all_projects(plugin)

        assert plugin not in plugins.for_project(self.project)
Example #46
0
    def post(self, request, organization, team, project, slug):
        try:
            plugin = plugins.get(slug)
        except KeyError:
            return self.redirect(reverse('sentry-configure-project-plugin', args=[project.organization.slug, project.slug, slug]))

        plugin.reset_options(project=project)

        return self.redirect(reverse('sentry-configure-project-plugin', args=[project.organization.slug, project.slug, slug]))
Example #47
0
    def test_disable_for_all_projects(self):
        plugin = plugins.get('example')
        plugin.enable(self.project)

        assert plugin in plugins.for_project(self.project)

        self.migrator.disable_for_all_projects(plugin)

        assert plugin not in plugins.for_project(self.project)
Example #48
0
def plugin_post_process_group(plugin_slug, event, **kwargs):
    """
    Fires post processing hooks for a group.
    """
    Raven.tags_context({
        'project': event.project_id,
    })
    plugin = plugins.get(plugin_slug)
    safe_execute(plugin.post_process, event=event, group=event.group, **kwargs)
Example #49
0
def plugin_post_process_group(plugin_slug, event, **kwargs):
    """
    Fires post processing hooks for a group.
    """
    with configure_scope() as scope:
        scope.set_tag("project", event.project_id)

    plugin = plugins.get(plugin_slug)
    safe_execute(plugin.post_process, event=event, group=event.group, **kwargs)
Example #50
0
    def post(self, request, plugin_id, project_id, signature):
        try:
            project = Project.objects.get_from_cache(id=project_id)
        except Project.DoesNotExist:
            logger.warn('release-webhook.invalid-project', extra={
                'project_id': project_id,
                'plugin_id': plugin_id,
            })
            return HttpResponse(status=404)

        logger.info('release-webhook.incoming', extra={
            'project_id': project_id,
            'plugin_id': plugin_id,
        })

        token = ProjectOption.objects.get_value(project, 'sentry:release-token')

        if token is None:
            logger.warn('release-webhook.missing-token', extra={
                'project_id': project_id,
                'plugin_id': plugin_id,
            })
            return HttpResponse(status=403)

        if not self.verify(plugin_id, project_id, token, signature):
            logger.warn('release-webhook.invalid-signature', extra={
                'project_id': project_id,
                'plugin_id': plugin_id,
            })
            return HttpResponse(status=403)

        if plugin_id == 'builtin':
            return self._handle_builtin(request, project)

        plugin = plugins.get(plugin_id)
        if not plugin.is_enabled(project):
            logger.warn('release-webhook.plugin-disabled', extra={
                'project_id': project_id,
                'plugin_id': plugin_id,
            })
            return HttpResponse(status=403)

        cls = plugin.get_release_hook()
        hook = cls(project)
        try:
            hook.handle(request)
        except HookValidationError as exc:
            return HttpResponse(
                status=400,
                content=json.dumps({
                    'error': six.text_type(exc)
                }),
                content_type='application/json',
            )

        return HttpResponse(status=204)
Example #51
0
    def _handle_enable_plugin(self, request, project):
        plugin = plugins.get(request.POST['plugin'])
        plugin.enable(project)

        plugin_enabled.send(plugin=plugin, project=project, user=request.user, sender=self)

        messages.add_message(
            request, messages.SUCCESS,
            constants.OK_PLUGIN_ENABLED.format(name=plugin.get_title()),
        )
Example #52
0
def reset_project_plugin(request, organization, project, slug):
    try:
        plugin = plugins.get(slug)
    except KeyError:
        return HttpResponseRedirect(reverse('sentry-configure-project-plugin', args=[project.organization.slug, project.slug, slug]))

    if not plugin.is_enabled(project):
        return HttpResponseRedirect(reverse('sentry-configure-project-plugin', args=[project.organization.slug, project.slug, slug]))

    plugin.reset_options(project=project)

    return HttpResponseRedirect(reverse('sentry-configure-project-plugin', args=[project.organization.slug, project.slug, slug]))
Example #53
0
def group_plugin_action(request, project, group, slug):
    try:
        plugin = plugins.get(slug)
    except KeyError:
        raise Http404("Plugin not found")

    response = plugin.get_view_response(request, group)
    if response:
        return response
    return HttpResponseRedirect(
        request.META.get("HTTP_REFERER") or reverse("sentry", kwargs={"project_id": group.project.slug})
    )
Example #54
0
def group_plugin_action(request, project, group_id, slug):
    group = get_object_or_404(Group, pk=group_id, project=project)

    try:
        plugin = plugins.get(slug)
    except KeyError:
        raise Http404('Plugin not found')

    response = plugin.get_view_response(request, group)
    if response:
        return response
    return HttpResponseRedirect(request.META.get('HTTP_REFERER') or reverse('sentry', kwargs={'project_id': group.project.slug}))
    def after(self, event, state):
        service = self.get_option('service')

        plugin = plugins.get(service)
        if not plugin.is_enabled(self.project):
            return

        group = event.group

        if not plugin.should_notify(group=group, event=event):
            return

        plugin.notify_users(group=group, event=event)
Example #56
0
def configure_plugin(request, slug):
    plugin = plugins.get(slug)
    if not plugin.has_site_conf():
        return HttpResponseRedirect(reverse("sentry"))

    action, view = plugin_config(plugin, None, request)
    if action == "redirect":
        return HttpResponseRedirect(request.path)

    return render_to_response(
        "sentry/admin/plugins/configure.html",
        {"plugin": plugin, "title": plugin.get_conf_title(), "slug": plugin.slug, "view": view},
        request,
    )
Example #57
0
def disable_project_plugin(request, organization, project, slug):
    try:
        plugin = plugins.get(slug)
    except KeyError:
        return HttpResponseRedirect(reverse('sentry-manage-project-plugins', args=[project.organization.slug, project.slug]))

    redirect_to = reverse('sentry-configure-project-plugin', args=[project.organization.slug, project.slug, slug])

    if not (plugin.can_disable and plugin.is_enabled(project) and plugin.can_enable_for_projects()):
        return HttpResponseRedirect(redirect_to)

    plugin.set_option('enabled', False, project)

    return HttpResponseRedirect(redirect_to)