diff --git a/back/admin/settings/templates/settings_integrations.html b/back/admin/settings/templates/settings_integrations.html index 68bdab488..d0fa7fa3f 100644 --- a/back/admin/settings/templates/settings_integrations.html +++ b/back/admin/settings/templates/settings_integrations.html @@ -16,9 +16,14 @@ {% trans "Slack bot" %} {% if slack_bot is not None %} + + {% trans "Manually add Slack channel" %} + + {% if not disable_update_channels_list %} {% trans "Update Slack channels list" %} + {% endif %} Add to your Slack team diff --git a/back/admin/settings/templates/slack_channel_create.html b/back/admin/settings/templates/slack_channel_create.html new file mode 100644 index 000000000..6d488fc5e --- /dev/null +++ b/back/admin/settings/templates/slack_channel_create.html @@ -0,0 +1,39 @@ +{% extends 'settings_base.html' %} +{% load i18n %} +{% load crispy_forms_tags %} + +{% block actions %} + {% if object %} + + {% translate "Live edit and test" %} + + {% endif %} +{% endblock %} +{% block settings_content %} +
+
+
+

{% translate "Existing Slack channels" %}

+ {% if channels|length == 0 %} +

{% translate "No channels yet" %}

+ {% endif %} +
    + {% for item in channels %} +
  • + {{ item.name }} +
  • + {% endfor %} +
+
+
+
+
+
+ {% csrf_token %} + {{ form|crispy }} + +
+
+
+
+{% endblock %} diff --git a/back/admin/settings/tests.py b/back/admin/settings/tests.py index 11807cd0e..347483f7e 100644 --- a/back/admin/settings/tests.py +++ b/back/admin/settings/tests.py @@ -4,6 +4,7 @@ from django.conf import settings from django.contrib.auth import get_user_model from django.core.cache import cache +from django.test import override_settings from django.urls import reverse from django_q.models import Schedule @@ -572,9 +573,58 @@ def test_slack_channels_update_view(client, admin_factory): client.force_login(admin_user1) Integration.objects.create(integration=Integration.Type.SLACK_BOT) + # button is visible + url = reverse("settings:integrations") + response = client.get(url) + + assert "Update Slack channels list" in response.content.decode() + url = reverse("settings:slack-account-update-channels") response = client.get(url) assert "Newly added channels have been added." not in response.content.decode() assert SlackChannel.objects.all().count() == 3 assert SlackChannel.objects.filter(name="general", is_private=False).exists() + + +@pytest.mark.django_db +@override_settings(SLACK_DISABLE_AUTO_UPDATE_CHANNELS=True) +def test_disable_slack_channels_update_view(client, admin_factory): + admin_user1 = admin_factory() + client.force_login(admin_user1) + Integration.objects.create(integration=Integration.Type.SLACK_BOT) + + # button is not visible + url = reverse("settings:integrations") + response = client.get(url) + + assert "Update Slack channels list" not in response.content.decode() + + url = reverse("settings:slack-account-update-channels") + response = client.get(url) + + assert response.status_code == 404 + + +@pytest.mark.django_db +def test_manually_add_slack_channels(client, admin_factory): + admin_user1 = admin_factory() + client.force_login(admin_user1) + Integration.objects.create(integration=Integration.Type.SLACK_BOT) + + SlackChannel.objects.create(name="test_channel") + url = reverse("settings:slack-account-add-channel") + response = client.get(url) + + # channel shows up + assert "test_channel" in response.content.decode() + + # add channel + url = reverse("settings:slack-account-add-channel") + response = client.post( + url, data={"name": "test2_channel", "is_private": True}, follow=True + ) + + assert "test2_channel" in response.content.decode() + # general is created by default + assert SlackChannel.objects.all().count() == 3 diff --git a/back/admin/settings/urls.py b/back/admin/settings/urls.py index db1a00f6a..f7c625bb1 100644 --- a/back/admin/settings/urls.py +++ b/back/admin/settings/urls.py @@ -28,6 +28,11 @@ views.SlackChannelsUpdateView.as_view(), name="slack-account-update-channels", ), + path( + "integrations/add_channel/", + views.SlackChannelsCreateView.as_view(), + name="slack-account-add-channel", + ), path( "integrations/slack_bot/", views.SlackBotSetupView.as_view(), name="slack-bot" ), diff --git a/back/admin/settings/views.py b/back/admin/settings/views.py index d38b33034..249063d69 100644 --- a/back/admin/settings/views.py +++ b/back/admin/settings/views.py @@ -3,7 +3,7 @@ from django.contrib import messages from django.contrib.auth import get_user_model from django.contrib.messages.views import SuccessMessageMixin -from django.http import HttpResponse, HttpResponseRedirect +from django.http import Http404, HttpResponse, HttpResponseRedirect from django.shortcuts import get_object_or_404, render from django.urls import reverse_lazy from django.utils import translation @@ -337,6 +337,9 @@ def get_context_data(self, **kwargs): integration=Integration.Type.CUSTOM, is_active=False ) context["add_action"] = reverse_lazy("integrations:create") + context["disable_update_channels_list"] = ( + settings.SLACK_DISABLE_AUTO_UPDATE_CHANNELS + ) return context @@ -375,6 +378,8 @@ class SlackChannelsUpdateView(LoginRequiredMixin, AdminPermMixin, RedirectView): pattern_name = "settings:integrations" def get(self, request, *args, **kwargs): + if settings.SLACK_DISABLE_AUTO_UPDATE_CHANNELS: + raise Http404 SlackChannel.objects.update_channels() messages.success( request, @@ -384,3 +389,19 @@ def get(self, request, *args, **kwargs): ), ) return super().get(request, *args, **kwargs) + + +class SlackChannelsCreateView(LoginRequiredMixin, AdminPermMixin, CreateView): + template_name = "slack_channel_create.html" + model = SlackChannel + fields = ["name", "is_private"] + success_message = _("Slack channel has been added") + success_url = reverse_lazy("settings:slack-account-add-channel") + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["title"] = _("Slack channels") + context["subtitle"] = _("settings") + context["button_text"] = _("Enable") + context["channels"] = SlackChannel.objects.all() + return context diff --git a/back/back/settings.py b/back/back/settings.py index d8ee02d62..8d9e75fc8 100644 --- a/back/back/settings.py +++ b/back/back/settings.py @@ -110,6 +110,9 @@ SLACK_USE_SOCKET = env.bool("SLACK_USE_SOCKET", default=False) SLACK_APP_TOKEN = env("SLACK_APP_TOKEN", default="") SLACK_BOT_TOKEN = env("SLACK_BOT_TOKEN", default="") +SLACK_DISABLE_AUTO_UPDATE_CHANNELS = env.bool( + "SLACK_DISABLE_AUTO_UPDATE_CHANNELS", default=False +) MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", diff --git a/docs/config/slackbot.md b/docs/config/slackbot.md index b103438e8..fc7fb00e6 100644 --- a/docs/config/slackbot.md +++ b/docs/config/slackbot.md @@ -48,3 +48,13 @@ settings: 8. Go back to your Slack bot and go to "App Home". Then scroll down till you see: "Show Tabs". Enable the "message tab" and check the "Allow users to send Slash commands and messages from the messages tab". That's it! + + +## Slack channels +You can import all channels in one go if you click on the "Update Slack channels list" button in the settings. +In some cases, you might want to avoid this at all costs (if you have thousands of channels). You can do that by setting: + +`SLACK_DISABLE_AUTO_UPDATE_CHANNELS` + +Default: `False`. Setting this to `True` will remove the button and disable this option +