1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-04-27 19:05:16 +00:00

Let user specify ccnet user id when registration

This commit is contained in:
plt 2011-10-29 11:50:58 +08:00
parent e999ebe663
commit 2f7ee386e2
14 changed files with 299 additions and 29 deletions

View File

@ -1,6 +1,21 @@
from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login
from django.contrib.sites.models import RequestSite
from django.contrib.sites.models import Site
from registration import signals
from registration.forms import RegistrationForm
from registration.models import RegistrationProfile
from django import forms
from django.utils.translation import ugettext_lazy as _
from seahub.profile.models import UserProfile
class EmailOrUsernameModelBackend(object):
def authenticate(self, username=None, password=None):
if '@' in username:
@ -19,3 +34,197 @@ class EmailOrUsernameModelBackend(object):
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
class RegistrationBackend(object):
"""
A registration backend which follows a simple workflow:
1. User signs up, inactive account is created.
2. Email is sent to user with activation link.
3. User clicks activation link, account is now active.
Using this backend requires that
* ``registration`` be listed in the ``INSTALLED_APPS`` setting
(since this backend makes use of models defined in this
application).
* The setting ``ACCOUNT_ACTIVATION_DAYS`` be supplied, specifying
(as an integer) the number of days from registration during
which a user may activate their account (after that period
expires, activation will be disallowed).
* The creation of the templates
``registration/activation_email_subject.txt`` and
``registration/activation_email.txt``, which will be used for
the activation email. See the notes for this backends
``register`` method for details regarding these templates.
Additionally, registration can be temporarily closed by adding the
setting ``REGISTRATION_OPEN`` and setting it to
``False``. Omitting this setting, or setting it to ``True``, will
be interpreted as meaning that registration is currently open and
permitted.
Internally, this is accomplished via storing an activation key in
an instance of ``registration.models.RegistrationProfile``. See
that model and its custom manager for full documentation of its
fields and supported operations.
"""
def register(self, request, **kwargs):
"""
Given a username, email address and password, register a new
user account, which will initially be inactive.
Along with the new ``User`` object, a new
``registration.models.RegistrationProfile`` will be created,
tied to that ``User``, containing the activation key which
will be used for this account.
An email will be sent to the supplied email address; this
email should contain an activation link. The email will be
rendered using two templates. See the documentation for
``RegistrationProfile.send_activation_email()`` for
information about these templates and the contexts provided to
them.
After the ``User`` and ``RegistrationProfile`` are created and
the activation email is sent, the signal
``registration.signals.user_registered`` will be sent, with
the new ``User`` as the keyword argument ``user`` and the
class of this backend as the sender.
"""
email, password = kwargs['email'], kwargs['password1']
username = email
if Site._meta.installed:
site = Site.objects.get_current()
else:
site = RequestSite(request)
new_user = RegistrationProfile.objects.create_inactive_user(username, email,
password, site)
userid = kwargs['userid']
profile = UserProfile(user=new_user, ccnet_user_id=userid)
profile.save()
signals.user_registered.send(sender=self.__class__,
user=new_user,
request=request)
return new_user
def activate(self, request, activation_key):
"""
Given an an activation key, look up and activate the user
account corresponding to that key (if possible).
After successful activation, the signal
``registration.signals.user_activated`` will be sent, with the
newly activated ``User`` as the keyword argument ``user`` and
the class of this backend as the sender.
"""
activated = RegistrationProfile.objects.activate_user(activation_key)
if activated:
signals.user_activated.send(sender=self.__class__,
user=activated,
request=request)
# login the user
activated.backend='django.contrib.auth.backends.ModelBackend'
login(request, activated)
return activated
def registration_allowed(self, request):
"""
Indicate whether account registration is currently permitted,
based on the value of the setting ``REGISTRATION_OPEN``. This
is determined as follows:
* If ``REGISTRATION_OPEN`` is not specified in settings, or is
set to ``True``, registration is permitted.
* If ``REGISTRATION_OPEN`` is both specified and set to
``False``, registration is not permitted.
"""
return getattr(settings, 'REGISTRATION_OPEN', True)
def get_form_class(self, request):
"""
Return the default form class used for user registration.
"""
return RegistrationForm
def post_registration_redirect(self, request, user):
"""
Return the name of the URL to redirect to after successful
user registration.
"""
return ('registration_complete', (), {})
def post_activation_redirect(self, request, user):
"""
Return the name of the URL to redirect to after successful
account activation.
"""
return ('myhome', (), {})
class RegistrationForm(forms.Form):
"""
Form for registering a new user account.
Validates that the requested email is not already in use, and
requires the password to be entered twice to catch typos.
"""
attrs_dict = { 'class': 'required' }
email = forms.EmailField(widget=forms.TextInput(attrs=dict(attrs_dict,
maxlength=75)),
label=_("Email address"))
userid = forms.RegexField(regex=r'^\w+$',
max_length=40,
widget=forms.TextInput(attrs=attrs_dict),
label=_("Username"),
error_messages={ 'invalid': _("This value must be of length 40") })
password1 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict, render_value=False),
label=_("Password"))
password2 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict, render_value=False),
label=_("Password (again)"))
def clean_email(self):
try:
user = User.objects.get(email__iexact=self.cleaned_data['email'])
except User.DoesNotExist:
return self.cleaned_data['email']
raise forms.ValidationError(_("A user with this email alread"))
def clean_userid(self):
if len(self.cleaned_data['userid']) != 40:
raise forms.ValidationError(_("Invalid user id."))
return self.cleaned_data['userid']
def clean(self):
"""
Verifiy that the values entered into the two password fields
match. Note that an error here will end up in
``non_field_errors()`` because it doesn't apply to a single
field.
"""
if 'password1' in self.cleaned_data and 'password2' in self.cleaned_data:
if self.cleaned_data['password1'] != self.cleaned_data['password2']:
raise forms.ValidationError(_("The two password fields didn't match."))
return self.cleaned_data

19
base/middleware.py Normal file
View File

@ -0,0 +1,19 @@
from seahub.profile.models import UserProfile
class UseridMiddleware(object):
def process_request(self, request):
if not request.user.is_authenticated():
return None
try:
profile = request.user.get_profile()
request.user.user_id = profile.ccnet_user_id
except UserProfile.DoesNotExist:
request.user.user_id = ''
return None
def process_response(self, request, response):
return response

37
base/registration_urls.py Normal file
View File

@ -0,0 +1,37 @@
from django.conf.urls.defaults import *
from django.views.generic.simple import direct_to_template
from registration.views import activate
from registration.views import register
from seahub.base.accounts import RegistrationForm
urlpatterns = patterns('',
url(r'^activate/complete/$',
direct_to_template,
{ 'template': 'registration/activation_complete.html' },
name='registration_activation_complete'),
# Activation keys get matched by \w+ instead of the more specific
# [a-fA-F0-9]{40} because a bad activation key should still get to the view;
# that way it can return a sensible "invalid key" message instead of a
# confusing 404.
url(r'^activate/(?P<activation_key>\w+)/$',
activate,
{ 'backend': 'seahub.base.accounts.RegistrationBackend', },
name='registration_activate'),
url(r'^register/$',
register,
{ 'backend': 'seahub.base.accounts.RegistrationBackend',
'form_class': RegistrationForm },
name='registration_register'),
url(r'^register/complete/$',
direct_to_template,
{ 'template': 'registration/registration_complete.html' },
name='registration_complete'),
url(r'^register/closed/$',
direct_to_template,
{ 'template': 'registration/registration_closed.html' },
name='registration_disallowed'),
(r'', include('registration.auth_urls')),
)

View File

@ -39,6 +39,8 @@ table.default tr.first { background-color: #00FF00; }
#header .top_operation a { font-weight:normal; font-size:13px; margin-left:2px; text-decoration: none; }
#header .top_operation a:hover { background:#0A0; color:#FFF; }
#logo { margin-top: 4px; }
#user-info { float: right; font-size: 12px; color: #808; font-style:normal; margin-bottom:10px; }
#user-info span { color: #888; display:inline-block; width:60px; text-align:right; margin-right:5px; }
#header #ident { margin-top: 8px; float: right; font-size: 12px; }
#header #ident p { color: #808; }
#header #ident label { color: #888; }

6
run-seahub.sh.template Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
export CCNET_CONF_DIR=/home/plt/dev/ccnet/seafile/tests/basic/conf2
export PYTHONPATH=/opt/lib/python2.6/site-packages:thirdpart
./manage.py runserver

View File

@ -66,6 +66,7 @@ MIDDLEWARE_CLASSES = (
'django.middleware.csrf.CsrfResponseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'seahub.base.middleware.UseridMiddleware',
)
SITE_ROOT_URLCONF = 'seahub.urls'

View File

@ -38,6 +38,11 @@
<div id="header">
<div class="logo">
<a href="/home/" id="logo"><img src="{{ MEDIA_URL }}img/logo.png" title="Seafile" alt="Seafile logo" /></a>
{% if request.user.is_authenticated %}
<div id="user-info">
<span>用户 ID:</span>{{user.user_id}}
</div>
{% endif %}
</div>
<div class="navs">
{% block nav %}

View File

@ -1,16 +1,6 @@
{% extends "myhome_base.html" %}
{% block right_panel %}
<h3>基本信息</h3>
<table class="default">
<tr>
<td>Seafile ID</td>
<td>{{ ccnet_user_id }}</td>
</tr>
<tr>
</tr>
</table>
<h3>我的文件盒</h3>
<table class="repo-list default">

View File

@ -17,3 +17,4 @@
-->
</ul>
{% endblock %}

View File

@ -0,0 +1,7 @@
{% extends "base.html" %}
{% block title %}Create an account{% endblock %}
{% block content %}
激活码错误。
{% endblock %}

View File

@ -3,10 +3,10 @@
{% block content %}
<h2>用户注册</h2>
<form action="" method="post" class="reg">
<label for="id_username">用户</label>
{{ form.username }}
{% if form.username.errors %}
{{ form.username.errors }}
<label for="id_username">用户 ID</label>
{{ form.userid }}
{% if form.userid.errors %}
{{ form.userid.errors }}
{% endif %}<br />
<label for="id_email">邮箱:</label>
{{ form.email }}<span>(我们将给您发送帐号激活邮件.)</span>

View File

@ -10,7 +10,6 @@ from django.template import RequestContext
from registration.backends import get_backend
def activate(request, backend,
template_name='registration/activate.html',
success_url=None, extra_context=None, **kwargs):
@ -191,7 +190,8 @@ def register(request, backend, success_url=None, form_class=None,
else:
return redirect(success_url)
else:
form = form_class()
userid = request.REQUEST.get('userid', '')
form = form_class(initial={'userid': userid })
if extra_context is None:
extra_context = {}

View File

@ -18,11 +18,11 @@ urlpatterns = patterns('',
# Uncomment the next line to enable the admin:
(r'^admin/', include(admin.site.urls)),
(r'^accounts/', include('registration.backends.default.urls')),
(r'^accounts/', include('base.registration_urls')),
(r'^$', root),
(r'^home/$', home),
(r'^home/my/$', myhome),
url(r'^home/my/$', myhome, name='myhome'),
(r'^peers/$', peers),
(r'^groups/$', groups),
url(r'^group/(?P<group_id>[^/]+)/$', group, name='view_group'),

View File

@ -150,19 +150,12 @@ def modify_token(request, repo_id):
@login_required
def myhome(request):
ccnet_user_id = ""
try:
profile = request.user.get_profile()
ccnet_user_id = profile.ccnet_user_id
except UserProfile.DoesNotExist:
pass
owned_repos = []
if ccnet_user_id:
owned_repos = seafile_rpc.list_owned_repos(ccnet_user_id)
user_id = request.user.user_id
if user_id:
owned_repos = seafile_rpc.list_owned_repos(user_id)
return render_to_response('myhome.html', {
"ccnet_user_id": ccnet_user_id,
"owned_repos": owned_repos,
}, context_instance=RequestContext(request))
@ -175,7 +168,7 @@ def mypeers(request):
@login_required
def myrepos(request):
cid = get_user_cid(request.user)
cid = request.user.user_id
owned_repos = seafile_rpc.list_owned_repos(cid)
return render_to_response('myrepos.html', {