Skip to content

Commit

Permalink
Improve support for auth-backend plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
dcramer committed Sep 4, 2012
1 parent 11e5910 commit 2c8539f
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 32 deletions.
8 changes: 8 additions & 0 deletions src/sentry/conf/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,11 @@
# Buffer backend to use
BUFFER = 'sentry.buffer.Buffer'
BUFFER_OPTIONS = {}

# Auth engines and the settings required for them to be listed
AUTH_PROVIDERS = {
'twitter': ('TWITTER_CONSUMER_KEY', 'TWITTER_CONSUMER_SECRET'),
'facebook': ('FACEBOOK_APP_ID', 'FACEBOOK_API_SECRET'),
'github': ('GITHUB_APP_ID', 'GITHUB_API_SECRET'),
'google': ('GOOGLE_OAUTH2_CLIENT_ID', 'GOOGLE_OAUTH2_CLIENT_SECRET'),
}
26 changes: 22 additions & 4 deletions src/sentry/plugins/bases/issue.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
:copyright: (c) 2010-2012 by the Sentry Team, see AUTHORS for more details.
:license: BSD, see LICENSE for more details.
"""
from sentry.conf import settings
from sentry.models import GroupMeta
from sentry.plugins import Plugin
from django import forms
from django.core.urlresolvers import reverse
from django.utils.html import escape
from django.utils.safestring import mark_safe
from social_auth.models import UserSocialAuth
from sentry.utils.auth import get_auth_providers


class NewIssueForm(forms.Form):
Expand Down Expand Up @@ -118,14 +120,30 @@ def get_initial_form_data(self, request, group, event, **kwargs):
'title': self._get_group_title(request, group, event),
}

def has_auth_configured(self, **kwargs):
if not self.auth_provider:
return True

return self.auth_provider in get_auth_providers()

def view(self, request, group, **kwargs):
if not self.needs_auth(project=group.project, request=request):
return self.render(self.needs_auth_template, request, {
has_auth_configured = self.has_auth_configured()
if not (has_auth_configured and self.is_configured(project=group.project, request=request)):
if self.auth_provider:
required_auth_settings = settings.AUTH_PROVIDERS[self.auth_provider]
else:
required_auth_settings = None

return self.render(self.not_configured_template, {
'title': self.get_title(),
'project': group.project,
'has_auth_configured': has_auth_configured,
'required_auth_settings': required_auth_settings,
})

if not self.is_configured(project=group.project, request=request):
return self.render(self.not_configured_template, request, {
if self.needs_auth(project=group.project, request=request):
return self.render(self.needs_auth_template, {
'title': self.get_title(),
'project': group.project,
})

Expand Down
4 changes: 2 additions & 2 deletions src/sentry/templates/sentry/account/identities.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@
</tbody>
</table>
{% endif %}
{% if auth_engines %}
{% if AUTH_PROVIDERS %}
<fieldset>
<legend>Associate a New Account</legend>
</fieldset>
<ul class="auth-options">
{% for engine in auth_engines %}
{% for engine in AUTH_PROVIDERS %}
<li><a href="{% url socialauth_associate_begin engine %}?next={{ request.build_absolute_uri }}" class="auth-{{ engine }}">Identify with {{ engine|title }}</a></li>
{% endfor %}
</ul>
Expand Down
4 changes: 2 additions & 2 deletions src/sentry/templates/sentry/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
</fieldset>
</form>
</div>
{% if auth_engines %}
{% if AUTH_PROVIDERS %}
<div class="span6">
<fieldset>
<legend>Login{% if SOCIAL_AUTH_CREATE_USERS %} or Register{% endif %} with another account</legend>
Expand All @@ -53,7 +53,7 @@
<a href="{{ link }}">identities</a> page in your account settings (after you login).{% endblocktrans %}</p>
<br>
<ul class="auth-options">
{% for engine in auth_engines %}
{% for engine in AUTH_PROVIDERS %}
<li><a href="{% url socialauth_begin engine %}" class="auth-{{ engine }}">Sign in with {{ engine|title }}</a></li>
{% endfor %}
</ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
<div class="page-header">
<h3>{{ title }}</h3>
</div>
<div class="alert-message error">
<div class="alert alert-block">
{% url socialauth_associate_begin plugin.auth_provider as link %}
{% blocktrans %}You still need to <a href="{{ link }}">associate an identity</a> with {{ title }} first.{% endblocktrans %}
<p>{% blocktrans %}You still need to <a href="{{ link }}">associate an identity</a> with {{ title }} before you can
create issues with this service.{% endblocktrans %}</p>
</div>
</div>
{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,20 @@
<div class="page-header">
<h3>{{ title }}</h3>
</div>
<div class="alert-message error">
{% url sentry-configure-project-plugin project_id=project.id slug=plugin.slug as link %}
{% blocktrans %}You still need to <a href="{{ link }}">configure this plugin</a>.{% endblocktrans %}
<div class="alert alert-block">
{% if not has_auth_configured %}
<p>{% blocktrans with plugin.auth_provider as auth_provider %}Your server administrator will need to configure authentication with
<strong>{{ auth_provider }}</strong> before you can use this plugin.{% endblocktrans %}</p>
<p>The following settings must be configured:</p>
<ul>
{% for setting in required_auth_settings %}
<li><code>{{ setting }}</code></li>
{% endfor %}
</ul>
{% else %}
{% url sentry-configure-project-plugin project_id=project.id slug=plugin.slug as link %}
<p>{% blocktrans %}You still need to <a href="{{ link }}">configure this plugin</a> before you can use it.{% endblocktrans %}</p>
{% endif %}
</div>
</div>
{% endblock %}
8 changes: 8 additions & 0 deletions src/sentry/utils/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"""
import hashlib
import hmac
from django.conf import settings as dj_settings
from sentry.conf import settings


Expand All @@ -30,3 +31,10 @@ def get_auth_header(signature, timestamp, client, api_key=None):

def parse_auth_header(header):
return dict(map(lambda x: x.strip().split('='), header.split(' ', 1)[1].split(',')))


def get_auth_providers():
return [key
for key, cfg_names
in settings.AUTH_PROVIDERS.iteritems()
if all(getattr(dj_settings, c, None) for c in cfg_names)]
25 changes: 6 additions & 19 deletions src/sentry/web/frontend/accounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,15 @@
from django.http import HttpResponseRedirect
from django.views.decorators.csrf import csrf_protect

from sentry.conf import settings
from sentry.plugins import plugins
from sentry.web.decorators import login_required
from sentry.web.forms.accounts import AccountSettingsForm, NotificationSettingsForm
from sentry.web.helpers import render_to_response
from sentry.utils.auth import get_auth_providers
from sentry.utils.safe import safe_execute


AUTH_ENGINES = {
'twitter': ('TWITTER_CONSUMER_KEY', 'TWITTER_CONSUMER_SECRET'),
'facebook': ('FACEBOOK_APP_ID', 'FACEBOOK_API_SECRET'),
'github': ('GITHUB_APP_ID', 'GITHUB_API_SECRET'),
'google': ('GOOGLE_OAUTH2_CLIENT_ID', 'GOOGLE_OAUTH2_CLIENT_SECRET'),
}


def get_auth_engines():
return [key
for key, cfg_names
in AUTH_ENGINES.iteritems()
if all(getattr(dj_settings, c, None) for c in cfg_names)]


@csrf_protect
def login(request):
from django.contrib.auth import login as login_
Expand All @@ -49,13 +36,13 @@ def login(request):
else:
request.session.set_test_cookie()

auth_engines = get_auth_engines()
AUTH_PROVIDERS = get_auth_providers()

context = csrf(request)
context.update({
'form': form,
'next': request.session.get('_next'),
'auth_engines': auth_engines,
'AUTH_PROVIDERS': AUTH_PROVIDERS,
'SOCIAL_AUTH_CREATE_USERS': dj_settings.SOCIAL_AUTH_CREATE_USERS,
})
return render_to_response('sentry/login.html', context, request)
Expand Down Expand Up @@ -141,12 +128,12 @@ def list_identities(request):

identity_list = list(UserSocialAuth.objects.filter(user=request.user))

auth_engines = get_auth_engines()
AUTH_PROVIDERS = get_auth_providers()

context = csrf(request)
context.update({
'identity_list': identity_list,
'page': 'identities',
'auth_engines': auth_engines,
'AUTH_PROVIDERS': AUTH_PROVIDERS,
})
return render_to_response('sentry/account/identities.html', context, request)

0 comments on commit 2c8539f

Please sign in to comment.