Skip to content

Commit

Permalink
Added authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
dcramer committed Sep 2, 2010
1 parent 1ad7a92 commit 50445d5
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 8 deletions.
10 changes: 7 additions & 3 deletions README.rst
Expand Up @@ -2,9 +2,12 @@
django-sentry
--------------

Logs Django exceptions to your database handler.
Sentry provides you with a generic interface to view and interact with your error logs. By
default, it will catch any exception thrown by Django and store it in a database. With this
it allows you to interact and view near real-time information to discover issues and more
easily trace them in your application.

(This is a major refactor of django-db-log and is not backwards compatible)
* Note: Sentry has only been tested under a PostgreSQL environment.

==========
Screenshot
Expand All @@ -16,7 +19,6 @@ Screenshot
Requirements
============

- **postgresql**
- **Django >= 1.2** (to use a secondary database to store error logs)
- **pygooglechart** (to generate *optional* error reports)

Expand Down Expand Up @@ -55,6 +57,8 @@ Once installed, update your settings.py and add sentry to ``INSTALLED_APPS``::

Finally, run ``python manage.py syncdb`` to create the database tables.

(If you use South, you'll need to use ``python manage.py migrate sentry``)

=============
Configuration
=============
Expand Down
2 changes: 1 addition & 1 deletion example_project/settings.py
Expand Up @@ -2,7 +2,7 @@
import sys
# Django settings for example_project project.

DEBUG = False
DEBUG = True
TEMPLATE_DEBUG = True

ADMINS = (
Expand Down
18 changes: 17 additions & 1 deletion sentry/media/styles/global.css
Expand Up @@ -458,4 +458,20 @@ pre {
background: #fff url(../images/search.png);
text-indent: -9999em;
border: none;
}
}

.login-area {
width: 300px;
margin: 50px auto;
background: #eee;
border: 1px solid #ddd;
padding: 10px;
}
.login-form table {
border: 0;
margin: 1em 0;
background: inherit;
}
.login-form td input { width: 100%; }
.login-form table td { padding: 5px; }
.login-submit { text-align: right; }
5 changes: 4 additions & 1 deletion sentry/models.py
Expand Up @@ -85,7 +85,10 @@ class Meta:
unique_together = (('logger', 'view', 'checksum'),)
verbose_name_plural = _('grouped messages')
verbose_name = _('grouped message')

permissions = (
("can_view", "Can view"),
)

def __unicode__(self):
return "(%s) %s: %s" % (self.times_seen, self.class_name, self.error())

Expand Down
55 changes: 55 additions & 0 deletions sentry/templates/sentry/login.html
@@ -0,0 +1,55 @@
{% extends "sentry/index.html" %}

{% load sentry_helpers %}

{% block title %}Login | Django Sentry{% endblock %}

{% block body %}
<div id="header">
<div class="container">
<h1><a href="{% url sentry %}"><span class="sentry-logo" title="Django Sentry"><img src="{% url sentry-media "images/sentry.png" %}" border=0/></span></a></h1>
<h2>Login</h2>
</div>
</div>
<div id="content">
<div class="container">
<div id="body">
<div class="login-area">
<p>You must log in to continue</p>

{% if form.errors %}
<p class="error">Your username and password didn't match. Please try again.</p>
{% endif %}

<form method="post" action="" class="login-form">
<input type="hidden" name="next" value="{{ next }}" />

{% csrf_token %}
<table>
<colgroup>
<col width="100px"/>
<col/>
</colgroup>
<tr>
<td>{{ form.username.label_tag }}</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.password.label_tag }}</td>
<td>{{ form.password }}</td>
</tr>
</table>
<div class="login-submit">
<input type="submit" value="Login" />
</div>
</form>
</div>
</div>
</div>
</div>
<div id="footer">
<div class="container">
Powered by sexy Django magic.
</div>
</div>
{% endblock %}
1 change: 1 addition & 0 deletions sentry/urls.py
Expand Up @@ -14,6 +14,7 @@
urlpatterns = patterns('',
url(r'^feeds/%s/messages.xml$' % hashed_secret, MessageFeed(), name='sentry-feed-messages'),
url(r'^feeds/%s/summaries.xml$' % hashed_secret, SummaryFeed(), name='sentry-feed-summaries'),
url(r'^login$', views.login, name='sentry-login'),
url(r'^group/(\d+)$', views.group, name='sentry-group'),
url(r'^$', views.index, name='sentry'),
url(r'^jsapi/$', views.ajax_handler, name='sentry-ajax'),
Expand Down
40 changes: 38 additions & 2 deletions sentry/views.py
Expand Up @@ -6,19 +6,54 @@
except ImportError:
SimpleLineChart = None

# TODO: login
from django.core.context_processors import csrf
from django.core.urlresolvers import reverse
from django.db.models import Count
from django.http import HttpResponse, HttpResponseForbidden, HttpResponseRedirect
from django.shortcuts import render_to_response
from django.template.loader import render_to_string
from django.utils import simplejson
from django.utils.datastructures import SortedDict
from django.utils.safestring import mark_safe
from django.views.decorators.csrf import csrf_protect

from sentry.helpers import FakeRequest, ImprovedExceptionReporter, get_filters
from sentry.models import GroupedMessage, Message, LOG_LEVELS
from sentry.templatetags.sentry_helpers import with_priority

def login_required(func):
def wrapped(request, *args, **kwargs):
if not request.user.is_authenticated():
print "not authed"
return HttpResponseRedirect(reverse('sentry-login'))
if not request.user.has_perm('sentry_groupedmessage.can_view'):
print "no perms"
return HttpResponseRedirect(reverse('sentry-login'))
return func(request, *args, **kwargs)
return wrapped

@csrf_protect
def login(request):
from django.contrib.auth import authenticate, login as login_
from django.contrib.auth.forms import AuthenticationForm

if request.POST:
form = AuthenticationForm(request, request.POST)
if form.is_valid():
login_(request, form.get_user())
return HttpResponseRedirect(request.POST.get('next') or reverse('sentry'))
else:
request.session.set_test_cookie()
else:
form = AuthenticationForm(request)
request.session.set_test_cookie()


context = locals()
context.update(csrf(request))
return render_to_response('sentry/login.html', locals(), )

@login_required
def index(request):
filters = []
for filter_ in get_filters():
Expand Down Expand Up @@ -52,9 +87,9 @@ def index(request):
else:
realtime = False

print str(message_list.query)
return render_to_response('sentry/index.html', locals())

@login_required
def ajax_handler(request):
op = request.REQUEST.get('op')
if op == 'poll':
Expand Down Expand Up @@ -124,6 +159,7 @@ def ajax_handler(request):
response['Content-Type'] = 'application/json'
return response

@login_required
def group(request, group_id):
group = GroupedMessage.objects.get(pk=group_id)

Expand Down

0 comments on commit 50445d5

Please sign in to comment.