Skip to content

Commit 8bc8a5a

Browse files
authored
add slack to social auth (#4705)
* add slack to social auth * change scope to support webhooks * update changes to correct version
1 parent 1909f92 commit 8bc8a5a

File tree

3 files changed

+78
-1
lines changed

3 files changed

+78
-1
lines changed

CHANGES

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Version 8.18 (Unreleased)
1313
- Moved "create organization" into React.
1414
- Expanded React Form components (Form, ApiForm).
1515
- Moved "create team" into React.
16+
- add Slack to supported auth backends in social auth (for plugins)
1617

1718
Schema Changes
1819
~~~~~~~~~~~~~~

src/sentry/conf/server.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ def env(key, default='', type=None):
344344
'social_auth.backends.bitbucket.BitbucketBackend',
345345
'social_auth.backends.trello.TrelloBackend',
346346
'social_auth.backends.asana.AsanaBackend',
347+
'social_auth.backends.slack.SlackBackend',
347348
)
348349

349350
AUTH_PASSWORD_VALIDATORS = [
@@ -368,6 +369,7 @@ def env(key, default='', type=None):
368369
'social_auth.backends.bitbucket.BitbucketBackend',
369370
'social_auth.backends.trello.TrelloBackend',
370371
'social_auth.backends.asana.AsanaBackend',
372+
'social_auth.backends.slack.SlackBackend',
371373
)
372374

373375
SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
@@ -408,13 +410,15 @@ def env(key, default='', type=None):
408410
'trello': ('TRELLO_API_KEY', 'TRELLO_API_SECRET'),
409411
'bitbucket': ('BITBUCKET_CONSUMER_KEY', 'BITBUCKET_CONSUMER_SECRET'),
410412
'asana': ('ASANA_CLIENT_ID', 'ASANA_CLIENT_SECRET'),
413+
'slack': ('SLACK_CLIENT_ID', 'SLACK_CLIENT_SECRET'),
411414
}
412415

413416
AUTH_PROVIDER_LABELS = {
414417
'github': 'GitHub',
415418
'trello': 'Trello',
416419
'bitbucket': 'Bitbucket',
417-
'asana': 'Asana'
420+
'asana': 'Asana',
421+
'slack': 'Slack'
418422
}
419423

420424
import random

src/social_auth/backends/slack.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
"""
2+
Obtain
3+
SLACK_CLIENT_ID & SLACK_CLIENT_SECRET
4+
and put into sentry.conf.py
5+
"""
6+
from __future__ import absolute_import
7+
8+
import requests
9+
10+
from social_auth.backends import BaseOAuth2, OAuthBackend
11+
12+
SLACK_TOKEN_EXCHANGE_URL = 'https://slack.com/api/oauth.access'
13+
SLACK_AUTHORIZATION_URL = 'https://slack.com/oauth/authorize'
14+
SLACK_USER_DETAILS_URL = 'https://slack.com/api/auth.test'
15+
16+
17+
class SlackBackend(OAuthBackend):
18+
"""Slack OAuth authentication backend"""
19+
name = 'slack'
20+
EXTRA_DATA = [
21+
('email', 'email'),
22+
('name', 'full_name'),
23+
('id', 'id'),
24+
('refresh_token', 'refresh_token')
25+
]
26+
27+
def get_user_details(self, response):
28+
"""Return user details from Slack account"""
29+
30+
return {
31+
'email': response.get('email'),
32+
'id': response.get('id'),
33+
'full_name': response.get('name')
34+
}
35+
36+
37+
class SlackAuth(BaseOAuth2):
38+
"""Slack OAuth authentication mechanism"""
39+
AUTHORIZATION_URL = SLACK_AUTHORIZATION_URL
40+
ACCESS_TOKEN_URL = SLACK_TOKEN_EXCHANGE_URL
41+
AUTH_BACKEND = SlackBackend
42+
SETTINGS_KEY_NAME = 'SLACK_CLIENT_ID'
43+
SETTINGS_SECRET_NAME = 'SLACK_CLIENT_SECRET'
44+
REDIRECT_STATE = False
45+
DEFAULT_SCOPE = ['incoming-webhook']
46+
47+
def user_data(self, access_token, *args, **kwargs):
48+
"""Loads user data from service"""
49+
try:
50+
resp = requests.get(SLACK_USER_DETAILS_URL,
51+
params={'token': access_token})
52+
resp.raise_for_status()
53+
content = resp.json()
54+
return {
55+
'id': content['user_id'],
56+
'name': content['user']
57+
}
58+
except ValueError:
59+
return None
60+
61+
@classmethod
62+
def refresh_token(cls, token):
63+
params = cls.refresh_token_params(token)
64+
response = requests.post(cls.ACCESS_TOKEN_URL, data=params,
65+
headers=cls.auth_headers())
66+
response.raise_for_status()
67+
return response.json()
68+
69+
# Backend definition
70+
BACKENDS = {
71+
'slack': SlackAuth,
72+
}

0 commit comments

Comments
 (0)