Skip to content
Browse files

Working on auth system

  • Loading branch information...
1 parent fc8a17d commit b81954df53a3ca40c46761b5ec79b5cc020bc0c0 @ericflo ericflo committed Feb 24, 2010
Showing with 201 additions and 8 deletions.
  1. +1 −0 lib/__init__.py
  2. +20 −7 lib/database.py
  3. +7 −0 manage.py
  4. +1 −1 settings.py
  5. +12 −0 templates/base.html
  6. +21 −0 templates/users/login.html
  7. +6 −0 templates/users/logout.html
  8. +1 −0 tweets/__init__.py
  9. +1 −0 urls.py
  10. +1 −0 users/__init__.py
  11. +61 −0 users/forms.py
  12. +25 −0 users/middleware.py
  13. +1 −0 users/models.py
  14. +6 −0 users/urls.py
  15. +37 −0 users/views.py
View
1 lib/__init__.py
@@ -0,0 +1 @@
+
View
27 lib/database.py
@@ -16,7 +16,8 @@
__all__ = ['get_user_by_id', 'get_user_by_username', 'get_friend_ids',
'get_follower_ids', 'get_users_for_user_ids', 'get_friends',
'get_followers', 'get_timeline', 'get_userline', 'get_tweet', 'save_user',
- 'save_tweet', 'add_friends', 'remove_friends']
+ 'save_tweet', 'add_friends', 'remove_friends', 'DatabaseError',
+ 'NotFound', 'InvalidDictionary']
CLIENT = pycassa.connect_thread_local(framed_transport=True)
@@ -79,11 +80,17 @@ def _get_userline_or_timeline(cf, user_id, start, limit):
# QUERYING APIs
def get_user_by_id(user_id):
- user = USER.get(str(user_id))
+ try:
+ user = USER.get(str(user_id))
+ except NotFoundException:
+ raise NotFound('User %s not found' % (user_id,))
return dict(((k, json.loads(v)) for k, v in user.iteritems()))
def get_user_by_username(username):
- record = USERNAME.get(username.encode('utf-8'))
+ try:
+ record = USERNAME.get(username.encode('utf-8'))
+ except NotFoundException:
+ raise NotFound('User %s not found' % (username,))
if 'id' not in record:
raise NotFound('Username %s not found' % (username,))
return get_user_by_id(record['id'])
@@ -95,7 +102,10 @@ def get_follower_ids(user_id, count=5000):
return _get_friend_or_follower_ids(FOLLOWERS, user_id, count)
def get_users_for_user_ids(user_ids):
- users = USER.multiget(map(str, user_ids))
+ try:
+ users = USER.multiget(map(str, user_ids))
+ except NotFoundException:
+ raise NotFound('Users %s not found' % (user_ids,))
decoded = []
for user in users.values():
decoded.append(
@@ -118,7 +128,10 @@ def get_userline(user_id, start=None, limit=40):
return _get_userline_or_timeline(USERLINE, user_id, start, limit)
def get_tweet(tweet_id):
- tweet = TWEET.get(str(tweet_id))
+ try:
+ tweet = TWEET.get(str(tweet_id))
+ except NotFoundException:
+ raise NotFound('Tweet %s not found' % (tweet_id,))
try:
return dict(((k, json.loads(v)) for k, v in tweet.iteritems()))
except IndexError:
@@ -130,8 +143,8 @@ def get_tweet(tweet_id):
def save_user(user_id, user):
encoded = dict(((k, json.dumps(v)) for k, v in user.iteritems()))
USER.insert(str(user_id), encoded)
- if 'screen_name' in user:
- key = user['screen_name'].encode('utf-8')
+ if 'username' in user:
+ key = user['username'].encode('utf-8')
USERNAME.insert(key, {'id': str(user_id)})
def save_tweet(tweet_id, user_id, tweet):
View
7 manage.py
@@ -1,4 +1,11 @@
#!/usr/bin/env python
+
+import os
+import sys
+
+PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
+sys.path.insert(0, os.path.join(PROJECT_ROOT, 'deps'))
+
from django.core.management import execute_manager
try:
import settings # Assumed to be in the same directory.
View
2 settings.py
@@ -70,7 +70,7 @@
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
- 'django.middleware.transaction.TransactionMiddleware',
+ 'users.middleware.UserMiddleware',
)
ROOT_URLCONF = 'urls'
View
12 templates/base.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>{% block title %}Twissandra{% endblock %}</title>
+ <meta name="description" content="{% block description %}Twissandra is an example Twitter implementation, using Cassandra{% endblock %}" />
+ </head>
+ <body>
+ {% block content %}
+ {% endblock %}
+ </body>
+</html>
View
21 templates/users/login.html
@@ -0,0 +1,21 @@
+{% extends "base.html" %}
+
+{% block content %}
+ <h2>Sign In</h2>
+ <form method="POST">
+ <input type="hidden" name="kind" value="login" />
+ <ul>
+ {{ login_form.as_ul }}
+ </ul>
+ <input type="submit" value="Sign In" />
+ </form>
+
+ <h2>Sign Up</h2>
+ <form method="POST">
+ <input type="hidden" name="kind" value="register" />
+ <ul>
+ {{ register_form.as_ul }}
+ </ul>
+ <input type="submit" value="Sign Up" />
+ </form>
+{% endblock %}
View
6 templates/users/logout.html
@@ -0,0 +1,6 @@
+{% extends "base.html" %}
+
+{% block content %}
+ <h2>You have been logged out</h2>
+ <p>Thanks for using Twissandra.</p>
+{% endblock %}
View
1 tweets/__init__.py
@@ -0,0 +1 @@
+
View
1 urls.py
@@ -2,6 +2,7 @@
from django.conf import settings
urlpatterns = patterns('',
+ url('^auth/', include('users.urls')),
)
if settings.DEBUG:
View
1 users/__init__.py
@@ -0,0 +1 @@
+
View
61 users/forms.py
@@ -0,0 +1,61 @@
+import uuid
+
+from django import forms
+
+from lib.database import get_user_by_username, save_user, DatabaseError
+
+class LoginForm(forms.Form):
+ username = forms.CharField(max_length=30)
+ password = forms.CharField(widget=forms.PasswordInput(render_value=False))
+
+ def clean(self):
+ username = self.cleaned_data['username']
+ password = self.cleaned_data['password']
+ try:
+ user = get_user_by_username(username)
+ except DatabaseError:
+ raise forms.ValidationError(u'Invalid username and/or password')
+ if user.get('password') != password:
+ raise forms.ValidationError(u'Invalid username and/or password')
+ return self.cleaned_data
+
+ def get_user_id(self):
+ username = self.cleaned_data['username']
+ user = get_user_by_username(username)
+ return user['id']
+
+
+class RegistrationForm(forms.Form):
+ username = forms.RegexField(regex=r'^\w+$', max_length=30)
+ password1 = forms.CharField(widget=forms.PasswordInput(render_value=False))
+ password2 = forms.CharField(widget=forms.PasswordInput(render_value=False))
+
+ def clean_username(self):
+ username = self.cleaned_data['username']
+ try:
+ get_user_by_username(username)
+ raise forms.ValidationError(u'Username is already taken')
+ except DatabaseError:
+ pass
+ return username
+
+ def clean(self):
+ if ('password1' in self.cleaned_data and 'password2' in
+ self.cleaned_data):
+ password1 = self.cleaned_data['password1']
+ password2 = self.cleaned_data['password2']
+ if password1 != password2:
+ raise forms.ValidationError(
+ u'You must type the same password each time')
+ return self.cleaned_data
+
+ def save(self):
+ user_id = str(uuid.uuid1())
+ username = self.cleaned_data['username']
+ password = self.cleaned_data['password1']
+ save_user(user_id, {
+ 'id': user_id,
+ 'username': username,
+ 'password': password,
+ })
+ return user_id
View
25 users/middleware.py
@@ -0,0 +1,25 @@
+from lib.database import get_user_by_id, DatabaseError
+
+def get_user(request):
+ if 'user_id' in request.session:
+ try:
+ user = get_user_by_id(request.session['user_id'])
+ user['is_authenticated'] = True
+ except DatabaseError:
+ pass
+ return {
+ 'username': None,
+ 'password': None,
+ 'id': None,
+ 'is_authenticated': False,
+ }
+
+class LazyUser(object):
+ def __get__(self, request, obj_type=None):
+ if not hasattr(request, '_cached_user'):
+ request._cached_user = get_user(request)
+ return request._cached_user
+
+class UserMiddleware(object):
+ def process_request(self, request):
+ request.__class__.user = LazyUser()
View
1 users/models.py
@@ -0,0 +1 @@
+# Nope, we're using Cassandra :)
View
6 users/urls.py
@@ -0,0 +1,6 @@
+from django.conf.urls.defaults import patterns, url
+
+urlpatterns = patterns('users.views',
+ url('^login/$', 'login', name='login'),
+ url('^logout/$', 'logout', name='logout'),
+)
View
37 users/views.py
@@ -0,0 +1,37 @@
+from django.shortcuts import render_to_response
+from django.template import RequestContext
+from django.http import HttpResponseRedirect
+
+from users.forms import LoginForm, RegistrationForm
+
+def login(request):
+ login_form = LoginForm()
+ register_form = RegistrationForm()
+ if 'kind' in request.POST:
+ if request.POST['kind'] == 'login':
+ login_form = LoginForm(request.POST)
+ if login_form.is_valid():
+ user_id = login_form.get_user_id()
+ request.session['user_id'] = user_id
+ if 'next' in request.REQUEST:
+ return HttpResponseRedirect(request.REQUEST['next'])
+ return HttpResponseRedirect('/')
+ elif request.POST['kind'] == 'register':
+ register_form = RegistrationForm(request.POST)
+ if register_form.is_valid():
+ user_id = register_form.save()
+ request.session['user_id'] = user_id
+ if 'next' in request.REQUEST:
+ return HttpResponseRedirect(request.REQUEST['next'])
+ return HttpResponseRedirect('/')
+ context = {
+ 'login_form': login_form,
+ 'register_form': register_form,
+ }
+ return render_to_response('users/login.html', context,
+ context_instance=RequestContext(request))
+
+def logout(request):
+ request.session.pop('user_id', None)
+ return render_to_response('users/logout.html', {},
+ context_instance=RequestContext(request))

0 comments on commit b81954d

Please sign in to comment.
Something went wrong with that request. Please try again.