Skip to content

Commit

Permalink
org: Add slack bot integration to send timelog updates. Fixes #2973. (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
apoorvapendse authored Dec 1, 2024
1 parent fabb2dc commit e7885ac
Show file tree
Hide file tree
Showing 15 changed files with 1,204 additions and 479 deletions.
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ DATABASE_URL=postgres://user:password@localhost:5432/dbname

#Sentry DSN
SENTRY_DSN=https://[email protected]/0


SLACK_CLIENT_ID=
SLACK_CLIENT_SECRET=
3 changes: 2 additions & 1 deletion blt/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

import comments.views
from blt import settings
from company.views import ShowBughuntView
from company.views import ShowBughuntView, SlackCallbackView
from website.api.views import (
ActivityLogViewSet,
AuthApiViewset,
Expand Down Expand Up @@ -237,6 +237,7 @@
re_path(r"^auth/github/connect/$", GithubConnect.as_view(), name="github_connect"),
re_path(r"^auth/google/connect/$", GoogleConnect.as_view(), name="google_connect"),
path("auth/github/url/", github_views.oauth2_login),
path("oauth/slack/callback/", SlackCallbackView.as_view(), name="slack_callback"),
path("auth/google/url/", google_views.oauth2_login),
path("auth/facebook/url/", facebook_views.oauth2_callback),
path("socialaccounts/", SocialAccountListView.as_view(), name="social_account_list"),
Expand Down
88 changes: 88 additions & 0 deletions company/templates/company/add_slack_integration.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
{% extends "company/company_dashboard_base.html" %}
{% block title %}
Add Slack Integration
{% endblock title %}
{% block body %}
<div class="bg-[#F3F5F7] flex flex-col items-center">
<div class="w-full mt-5">
<p class="text-red-700 font-satoshi font-bold text-[35px] px-8">Add Slack Integration</p>
</div>
<form method='post'
action="#"
class="w-[96%] bg-white rounded-2xl p-10 my-10 shadow-md">
{% csrf_token %}
<div class="pb-12">
<h2 class="text-base font-semibold leading-7 text-gray-900">Configure Slack Bot:</h2>
<div class="mt-10 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
<div class="sm:col-span-3">
<label for="bot_token"
class="block text-sm font-medium leading-6 text-gray-900">Bot Token</label>
<div class="mt-2">
<input type="text"
name="bot_token"
id="bot_token"
autocomplete="bot_token"
value="{{ slack_integration.bot_access_token }}"
disabled
class="block w-full rounded-md border-0 py-1.5 pl-3 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-red-600 sm:text-sm sm:leading-6" />
</div>
</div>
</div>
<div class="mt-10 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
<div class="sm:col-span-3">
<label class="block text-sm font-medium leading-6 text-gray-900"
for="target_channel">Select Channel to send messages to</label>
<div class="mt-2 space-y-4">
<select id="target_channel"
name="target_channel"
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
{% for channel_name in channels %}
<option value="{{ channel_name }}"
{% if slack_integration.default_channel_name == channel_name %}selected="selected"{% endif %}>
{{ channel_name }}
</option>
{% endfor %}
</select>
</div>
</div>
</div>
</div>
<div class=" grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
<div class="sm:col-span-3">
<label class="block text-sm font-medium leading-6 text-gray-900">Select Services</label>
<div class="items-center flex">
<input type="checkbox"
id="daily_sizzle_timelogs_status"
name="daily_sizzle_timelogs_status"
class="h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded"
{% if slack_integration.daily_updates == True %}checked{% endif %}>
<label for="daily_sizzle_timelogs_status"
class="ml-3 block text-sm font-medium text-gray-900">
Daily Sizzle Timelogs Status
</label>
</div>
</div>
<div class="sm:col-span-3 flex">
<select id="daily_sizzle_timelogs_hour"
name="daily_sizzle_timelogs_hour"
class="mt-2 block pl-3 pr-10 py-2 text-base focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md">
<option value="" disabled>Select Hour in UTC</option>
<!-- Loop to generate options from 0 to 23 -->
{% for hour in hours %}
<option value="{{ hour }}"
{% if slack_integration.daily_update_time == hour %}selected="selected"{% endif %}>
{{ hour }}
</option>
{% endfor %}
</select>
</div>
</div>
<div class="mt-6 flex items-center justify-end gap-x-6">
<button type="submit"
class="rounded-md bg-red-600 px-11 py-3 text-md font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600">
Save
</button>
</div>
</div>
</form>
{% endblock body %}
6 changes: 6 additions & 0 deletions company/templates/company/company_includes/sidebar.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ <h2 class="sidebar__logo-header font-bold">{{ company_obj.name | slice:":15" | c
<span>Roles</span>
</li>
</a>
<a href="{% url 'company_manage_integrations' company %}">
<li id="domains" class="side-nav__item">
<i class="fa fa-cog" aria-hidden="true"></i>
<span>Integrations</span>
</li>
</a>
</ul>
</div>
<ul class="side-nav">
Expand Down
81 changes: 81 additions & 0 deletions company/templates/company/company_integrations.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{% extends "company/company_dashboard_base.html" %}
{% load static %}
{% block title %}
Manage Integrations
{% endblock title %}
{% block body %}
<style>
.bottom-right {
position: absolute;
bottom: 10px;
right: 15px;
}
</style>
<div class="bottom-right">
<a href="https://github.com/OWASP-BLT/BLT/blob/main/company/templates/company/company_manage_domains.html">
<i class="fab fa-github"></i>
</a>
<a href="https://www.figma.com/file/s0xuxeU6O2guoWEfA9OElZ/Design?node-id=3%3A76&t=pqxWpF3hcYxjEDrs-1">
<i class="fab fa-figma"></i>
</a>
</div>
<div class="bg-[#F3F5F7] w-full h-full flex flex-col items-center">
<div class="flex items-center md:justify-between w-full md:h-max mt-5 flex-col md:flex-row">
<p class="text-red-700 font-satoshi font-bold text-[35px] px-8">Manage Integrations</p>
<div class="w-full md:w-[15%] flex justify-center md:justify-end mr-10">
<a href="{% url 'add_slack_integration' company %}"
class="flex items-center justify-center md:justify-center rounded-xl p-8 hover:opacity-80 transition-all">
<img src="{% static 'images/slack_icon.png' %}"
alt="BACON Project Image"
class="rounded-lg shadow-lg max-w-full md:w-1/3 lg:w-1/4 mb-6"
height="auto"
width="50%">
</a>
</div>
</div>
<div class="w-[96%] max-h-[70vh] p-4 mt-10 bg-white border border-gray-200 rounded-lg shadow-md sm:p-8">
<div class="flex-col items-center justify-between mb-4 ">
<h5 class="text-xl font-bold leading-none text-gray-900">All Integrations</h5>
<ul class="flex-col list-decimal">
{% if slack_integration %}
<li class="font-bold text-xl list-item ml-8 mt-2">
<div class="flex">
Slack
<img src="{% static 'images/slack_icon.png' %}"
class="h-8 ml-4"
height="30px"
width="30px"
alt="slack icon">
</div>
{% if slack_integration.daily_updates %}
<p class="text-base font-normal">
<span class="font-bold">Service Name</span>: Daily Sizzle Timelogs Status
</p>
<p class="text-base font-normal">
<span class="font-bold">Daily Update Time:</span> {{ slack_integration.daily_update_time }} (UTC)
</p>
<p class="text-base font-normal">
<span class="font-bold">Channel Name:</span> #{{ slack_integration.default_channel_name }}
</p>
{% endif %}
<a href="{% url 'add_slack_integration' company %}"
class="font-normal text-base">Edit <i class="fa fa-pencil" aria-hidden="true"></i></a>
<form method="post"
action="{% url 'add_slack_integration' company %}"
class="mt-2">
{% csrf_token %}
<input type="hidden" name="_method" value="delete">
<button type="submit"
class="rounded-md bg-red-600 px-1 py-1 text-md font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600">
Delete
</button>
</form>
{% else %}
<span>No integrations found.</span>
</li>
{% endif %}
</ul>
</div>
</div>
</div>
{% endblock body %}
12 changes: 12 additions & 0 deletions company/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
from company.views import (
AddDomainView,
AddHuntView,
AddSlackIntegrationView,
CompanyDashboardAnalyticsView,
CompanyDashboardIntegrations,
CompanyDashboardManageBughuntView,
CompanyDashboardManageBugsView,
CompanyDashboardManageDomainsView,
Expand All @@ -27,6 +29,11 @@
CompanyDashboardAnalyticsView.as_view(),
name="company_analytics",
),
path(
"<int:id>/dashboard/integrations/",
CompanyDashboardIntegrations.as_view(),
name="company_manage_integrations",
),
path(
"<int:id>/dashboard/bugs/",
CompanyDashboardManageBugsView.as_view(),
Expand All @@ -50,6 +57,11 @@
path("dashboard/end_bughunt/<int:pk>", EndBughuntView.as_view(), name="end_bughunt"),
path("<int:id>/dashboard/add_bughunt/", AddHuntView.as_view(), name="add_bughunt"),
path("<int:id>/dashboard/add_domain/", AddDomainView.as_view(), name="add_domain"),
path(
"<int:id>/dashboard/add_slack_integration/",
AddSlackIntegrationView.as_view(),
name="add_slack_integration",
),
path(
"<int:id>/dashboard/edit_domain/<int:domain_id>/",
AddDomainView.as_view(),
Expand Down
Loading

0 comments on commit e7885ac

Please sign in to comment.