software powering 0xdb.org and Pad.ma is called pandora now

This commit is contained in:
j 2010-02-16 15:52:34 +05:30
commit 7c0e365a0a
46 changed files with 30 additions and 21 deletions

View file

68
pandora/oxuser/models.py Normal file
View file

@ -0,0 +1,68 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from django.contrib.auth.models import User
from django.db import models
from django.db.models import signals
from django.dispatch import dispatcher
from django.utils import simplejson as json
class UserProfile(models.Model):
recover_key = models.TextField()
user = models.ForeignKey(User, unique=True)
def user_post_save(sender, instance, **kwargs):
profile, new = UserProfile.objects.get_or_create(user=instance)
models.signals.post_save.connect(user_post_save, sender=User)
class Preference(models.Model):
user = models.ForeignKey(User, related_name='preferences')
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
key = models.CharField(blank=True, max_length=255)
value = models.TextField(blank=True)
def getUserJSON(user):
json = {}
for key in ('username', ):
json[key] = getattr(user, key)
json['group'] = 'user'
if user.is_staff:
json['group'] = 'admin'
elif user.has_perm('0x.vip'): #FIXME: permissions
json['group'] = 'vip'
json['preferences'] = getPreferences(user)
return json
def getPreferences(user):
prefs = {}
for p in Preference.objects.filter(user=user):
prefs[p.key] = json.loads(p.value)
prefs['email'] = user.email
return prefs
def getPreference(user, key, value=None):
if key in ('email', ):
value = getattr(user, key)
else:
q = Preference.objects.filter(user=user, key=key)
if q.count() > 0:
value = json.loads(q[0].value)
return value
def setPreference(user, key, value):
if key in ('email', ):
setattr(user, key, value)
user.save()
else:
value = json.dumps(value)
q = Preference.objects.filter(user=user, key=key)
if q.count() > 0:
p = q[0]
p.value = value
p.save()
else:
p = Preference(user=user, key=key, value=value)
p.save()

View file

@ -0,0 +1,10 @@
Somebody requested a new password for your {{sitename}} account.
If it is you, and if you forgot your password, you can login
by clicking the following url:
{{recover_url}}
If you did not request a password, you can safely ignore this e-mail.
{{sitename}}

23
pandora/oxuser/tests.py Normal file
View file

@ -0,0 +1,23 @@
"""
This file demonstrates two different styles of tests (one doctest and one
unittest). These will both pass when you run "manage.py test".
Replace these with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.failUnlessEqual(1 + 1, 2)
__test__ = {"doctest": """
Another way to test that 1 + 1 is equal to 2.
>>> 1 + 1 == 2
True
"""}

14
pandora/oxuser/urls.py Normal file
View file

@ -0,0 +1,14 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from django.conf.urls.defaults import *
urlpatterns = patterns("oxdb.oxuser.views",
(r'^preferences', 'api_preferences'),
(r'^login', 'api_login'),
(r'^logout', 'api_logout'),
(r'^register', 'api_register'),
(r'^recover', 'api_recover'),
)

226
pandora/oxuser/views.py Normal file
View file

@ -0,0 +1,226 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
import uuid
import hashlib
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404, redirect
from django.template import RequestContext, loader, Context
from django.utils import simplejson as json
from django.conf import settings
from django.core.mail import send_mail, BadHeaderError
from oxdjango.shortcuts import render_to_json_response, json_response
from oxdjango.decorators import login_required_json
import models
class LoginForm(forms.Form):
username = forms.TextInput()
password = forms.TextInput()
def api_login(request):
'''
param data
{'username': username, 'password': password}
return {'status': {'code': int, 'text': string}}
'''
response = json_response(status=403, text='login failed')
data = json.loads(request.POST['data'])
form = LoginForm(data, request.FILES)
if form.is_valid():
user = authenticate(username=data['username'], password=data['password'])
if user is not None:
if user.is_active:
login(request, user)
user_json = models.getUserJSON(user)
response = json_response({'user': user_json},
text='You are logged in.')
else:
response = json_response(status=401,
text='Your account is disabled.')
else:
errors = json_errors(form)
response = json_response(errors,
status=401, text='Your username and password were incorrect.')
else:
response = json_response(status=400, text='invalid data')
return render_to_json_response(response)
def api_logout(request):
'''
param data
{}
return {'status': {'code': int, 'text': string}}
'''
response = json_response(text='logged out')
if request.user.is_authenticated():
logout(request)
return render_to_json_response(response)
class RegisterForm(forms.Form):
username = forms.TextInput()
password = forms.TextInput()
email = forms.TextInput()
def api_register(request):
'''
param data
{'username': username, 'password': password, 'email': email}
return {'status': {'code': int, 'text': string}}
'''
data = json.loads(request.POST['data'])
form = RegisterForm(data, request.FILES)
if form.is_valid():
if models.User.objects.filter(username=form.data['username']).count() > 0:
response = json_response(status=400, text='username or email exists')
elif models.User.objects.filter(email=form.data['email']).count() > 0:
response = json_response(status=400, text='username or email exists')
else:
user = models.User(username=form.data['username'], email=form.data['email'])
user.set_password(form.data['password'])
user.save()
user = authenticate(username=form.data['username'],
password=form.data['password'])
login(request, user)
response = json_response(text='account created')
else:
response = json_response(status=400, text='username exists')
return render_to_json_response(response)
class RecoverForm(forms.Form):
username_or_email = forms.TextInput()
def api_recover(request):
'''
param data
{'username_or_email': username}
return {'status': {'code': int, 'text': string}}
'''
data = json.loads(request.POST['data'])
form = RegisterForm(data, request.FILES)
if form.is_valid():
username = data['username_or_email']
user = None
q = models.User.objects.filter(username=username)
if q.count() > 0:
user = q[0]
else:
q = models.User.objects.filter(email=username)
if q.count() > 0:
user = q[0]
if user:
key = hashlib.sha1(str(uuid.uuid4())).hexdigest()
user_profile = user.get_profile()
user_profile.recover_key = key
user_profile.save()
template = loader.get_template('recover_email.txt')
context = RequestContext(request, {
'recover_url': request.build_absolute_uri("/r/%s" % key),
'sitename': settings.SITENAME,
})
message = template.render(context)
subject = '%s account recovery' % settings.SITENAME
user.email_user(subject, message)
response = json_response(text='recover email sent')
else:
response = json_response(status=404, text='username or email not found')
else:
response = json_response(status=400, text='invalid data')
return render_to_json_response(response)
def recover(request, key):
qs = models.UserProfile.objects.filter(recover_key=key)
if qs.count() == 1:
user = qs[0].user
user.set_password(key)
user.save()
user_profile = user.get_profile()
user_profile.recover_key = ''
user_profile.save()
user = authenticate(username=user.username, password=key)
login(request, user)
#FIXME: set message to notify user to update password
return redirect('/#settings')
return redirect('/')
class ContactForm(forms.Form):
email = forms.EmailField()
subject = forms.TextInput()
message = forms.TextInput()
def api_contact(request):
'''
param data
{'email': string, 'message': string}
return {'status': {'code': int, 'text': string}}
'''
data = json.loads(request.POST['data'])
form = ContactForm(data, request.FILES)
if form.is_valid():
email = data['email']
template = loader.get_template('contact_email.txt')
context = RequestContext(request, {
'sitename': settings.SITENAME,
'email': email,
'message': data['message'],
})
message = template.render(context)
subject = '%s contact: %s' % (settings.SITENAME, data['subject'])
response = json_response(text='message sent')
try:
send_mail(subject, message, email, [settings.DEFAULT_FROM_EMAIL, ])
except BadHeaderError:
response = json_response(status=400, text='invalid data')
else:
response = json_response(status=400, text='invalid data')
return render_to_json_response(response)
@login_required_json
def api_preferences(request):
'''
param data
string
array
object
return
if data is empy or {}
if data is string:
return preference with name
if data is array:
return preferences with names
if data is object:
set key values in dict as preferences
'''
response = json_response()
if 'data' not in request.POST:
response['data']['preferences'] = models.getPreferences(request.user)
else:
data = json.loads(request.POST['data'])
if isinstance(data, basestring):
response['data']['preferences'] = {}
response['data']['preferences'][data] = models.getPreference(request.user, data)
elif isinstance(data, list):
response['data']['preferences'] = {}
for preference in data:
response['preferences'][preference] = models.getPreference(request.user, preference)
elif isinstance(data, dict):
if not data:
response['data']['preferences'] = models.getPreferences(request.user)
else:
del response['data']
for key in data:
models.setPreference(request.user, key, data[key])
return render_to_json_response(response)