1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-01 23:20:51 +00:00

Impove registration process and add user admin page

This commit is contained in:
plt
2012-02-21 17:11:58 +08:00
parent 67e0ce2fb6
commit 37db478448
9 changed files with 217 additions and 19 deletions

81
HACKING Normal file
View File

@@ -0,0 +1,81 @@
About Registration
==================
We use a customized registration process based on thirdpart/registration.
The customization begins with:
(r'^accounts/', include('base.registration_urls'))
See base.registration_urls to follow the code.
Registration is seperated into two phase: registration and activation.
Registration Page with Form -----> Registration Complete Page
(Notify User to check mail)
|
|
V
User check email and click activate link
|
|
V
User Home Page <----- Activate and login User.
The registration app provide two view functions, i.e., `register` and `activate`.
### Register
The actual registration of the account will be delegated to the
backend; it will be used as follows:
1. The backend's ``registration_allowed()`` method will be called,
passing the ``HttpRequest``, to determine whether registration of
an account is to be allowed; if not, a redirect is issued to the
view corresponding to the named URL pattern
``registration_disallowed``.
2. The form to use for account registration will be obtained by
calling the backend's ``get_form_class()`` method, passing the
``HttpRequest``.
3. If valid, the form's ``cleaned_data`` will be passed (as keyword
arguments, and along with the ``HttpRequest``) to the backend's
``register()`` method, which should return the new ``User`` object.
4. Upon successful registration, the backend's
``post_registration_redirect()`` method will be called, passing the
``HttpRequest`` and the new ``User``, to determine the URL to
redirect the user to.
We use a customized backend: seahub.base.accounts.RegistrationBackend
### Registration Process
Process 1:
1. User register
2. Admin activate
3. User login and bind ccnet ID
To Enable this process, just set
EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
EMAIL_FILE_PATH = '/tmp/app-messages'
Process 2:
1. User register and active account and bind ccnet ID
About Authentication
====================
We use a custimized authentication method. See
seahub.base.accounts.EmailOrUsernameModelBackend
AUTHENTICATION_BACKENDS = (
'seahub.base.accounts.EmailOrUsernameModelBackend',
'django.contrib.auth.backends.ModelBackend'
)

View File

@@ -14,7 +14,7 @@ from django import forms
from django.utils.translation import ugettext_lazy as _
from seahub.profile.models import UserProfile
from seaserv import ccnet_rpc
class EmailOrUsernameModelBackend(object):
def authenticate(self, username=None, password=None):
@@ -109,8 +109,9 @@ class RegistrationBackend(object):
password, site)
userid = kwargs['userid']
profile = UserProfile(user=new_user, ccnet_user_id=userid)
profile.save()
if userid:
profile = UserProfile(user=new_user, ccnet_user_id=userid)
profile.save()
signals.user_registered.send(sender=self.__class__,
user=new_user,
@@ -136,6 +137,12 @@ class RegistrationBackend(object):
# login the user
activated.backend='django.contrib.auth.backends.ModelBackend'
login(request, activated)
try:
profile = request.user.get_profile()
if profile.ccnet_user_id:
ccnet_rpc.add_client(ccnet_user_id)
except:
pass
return activated
@@ -192,7 +199,8 @@ class RegistrationForm(forms.Form):
label=_("Email address"))
userid = forms.RegexField(regex=r'^\w+$',
max_length=40,
widget=forms.TextInput(attrs=attrs_dict),
required=False,
widget=forms.TextInput(),
label=_("Username"),
error_messages={ 'invalid': _("This value must be of length 40") })
@@ -209,11 +217,9 @@ class RegistrationForm(forms.Form):
raise forms.ValidationError(_("A user with this email alread"))
def clean_userid(self):
if len(self.cleaned_data['userid']) != 40:
if self.cleaned_data['userid'] and len(self.cleaned_data['userid']) != 40:
raise forms.ValidationError(_("Invalid user id."))
return self.cleaned_data['userid']
def clean(self):

View File

@@ -147,3 +147,5 @@ div.home-page h2 { font-style: italic; }
.help-page img { display: block; margin: 20px auto; }
#id_repo_id { width:300px; }
span.role-remove-link { font-size: 9px; }

View File

@@ -10,7 +10,7 @@
<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery.simplemodal.1.4.1.min.js"></script>
{% block extra_style %}{% endblock %}
{% block extra_script %}{% endblock %}
</head>
<body>
@@ -96,5 +96,7 @@
</div>
</div><!-- wrapper -->
{% block extra_script %}{% endblock %}
</body>
</html>

View File

@@ -4,16 +4,13 @@
<li>
<a href="{{ SITE_ROOT }}home/my/">我的页面</a>
</li>
<li>
<a href="{{ SITE_ROOT }}share/">共享</a>
</li>
<li>
<a href="{{ SITE_ROOT }}contacts/">联系人</a>
</li>
{% if request.user.is_staff %}
<li>
<a href="{{ SITE_ROOT }}seafadmin/">中继管理</a>
</li>
<li>
<a href="{{ SITE_ROOT }}useradmin/">用户管理</a>
</li>
{% endif %}
<li>
<a href="http://www.gonggeng.org/seasite/help/">使用帮助</a>

View File

@@ -3,8 +3,8 @@
{% block main_panel %}
<h2>用户注册</h2>
<form action="" method="post" class="reg">
<label for="id_username">用户 ID</label>
{{ form.userid }}
<label for="id_username">Ccnet 公钥 ID</label>
{{ form.userid }} (可以以后再绑定)
{% if form.userid.errors %}
{{ form.userid.errors }}
{% endif %}<br />

59
templates/useradmin.html Normal file
View File

@@ -0,0 +1,59 @@
{% extends "myhome_base.html" %}
{% block right_panel %}
<h2>所有用户</h2>
<table class="user-list default">
<tr>
<th>邮件</th>
<td>激活</td>
<td>Ccnet ID</td>
<td>角色</td>
<td>操作</td>
</tr>
{% for user in users %}
<tr>
<td>{{ user.email }}</td>
<td>{{ user.is_active }}</td>
{% if user.profile %}
<td>{{ user.profile.ccnet_user_id }}</td>
<td>
{% for role in user.role_list %}
{{ role }}<span class="role-remove-link">(<a href="{{ SITE_ROOT }}useradmin/{{ user.profile.ccnet_user_id }}/role/remove/?role={{ role }}">删除</a>)</span>
{% endfor %}
</td>
<td><button class="add-role-btn" userid="{{ user.profile.ccnet_user_id }}" email="{{ user.email }}">添加角色</button></td>
{% endif %}
</tr>
{% endfor %}
</table>
<div class="hidden">
<form id="add-role-form" action="" method="post">
<p><span id="user_email"></span> 的新角色 (即 MyClient 等)</p>
<input id="id_role" type="text" name="role" /><br/>
<input id="id_summit" type="submit" value="Submit" />
</form>
</div>
{% endblock %}
{% block extra_script %}
<script>
$(function() {
$(".add-role-btn").each(function(index, item) {
item.onclick = function() {
url = "{{ SITE_ROOT }}useradmin/" + $(item).attr("userid") + "/role/add/";
$("#add-role-form").attr( { action: url } );
$("#add-role-form #user_email").html($(item).attr("email"));
$("#add-role-form").modal({appendTo: "#main"});
}
});
});
</script>
{% endblock %}

View File

@@ -3,7 +3,8 @@ from django.conf import settings
from django.views.generic.simple import direct_to_template
from seahub.views import root, peers, groups, myhome, \
repo, group, modify_token, remove_repo, seafadmin
repo, group, modify_token, remove_repo, seafadmin, useradmin, \
role_add, role_remove
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
@@ -30,6 +31,9 @@ urlpatterns = patterns('',
(r'^repo/remove/(?P<repo_id>[^/]+)/$', remove_repo),
(r'^seafadmin/$', seafadmin),
(r'^useradmin/$', useradmin),
(r'^useradmin/(?P<user_id>[^/]+)/role/add/$', role_add),
(r'^useradmin/(?P<user_id>[^/]+)/role/remove/$', role_remove),
(r'^avatar/', include('avatar.urls')),
(r'^profile/', include('seahub.profile.urls')),

View File

@@ -4,6 +4,7 @@ from django.core.urlresolvers import reverse
from django.template import RequestContext
from django.contrib.auth.decorators import login_required
from django.db import IntegrityError
from django.contrib.auth.models import User
from seaserv import cclient, ccnet_rpc, get_groups, get_users, get_repos, \
get_repo, get_commits, get_branches, \
@@ -176,3 +177,49 @@ def seafadmin(request):
'repos': repos,
},
context_instance=RequestContext(request))
@login_required
def useradmin(request):
if not request.user.is_staff:
raise Http404
users = User.objects.all()
for user in users:
try:
user.profile = user.get_profile()
user.ccnet_user = ccnet_rpc.get_user(user.profile.ccnet_user_id)
user.role_list = user.ccnet_user.props.role_list.split(',')
except UserProfile.DoesNotExist:
user.profile = None
user.ccnet_user = None
return render_to_response(
'useradmin.html', {
'users': users,
},
context_instance=RequestContext(request))
@login_required
def role_add(request, user_id):
if not request.user.is_staff:
raise Http404
if request.method == 'POST':
role = request.POST.get('role', '')
if role and len(role) <= 16:
ccnet_rpc.add_role(user_id, role)
return HttpResponseRedirect(request.META['HTTP_REFERER'])
@login_required
def role_remove(request, user_id):
if not request.user.is_staff:
raise Http404
role = request.REQUEST.get('role', '')
if role and len(role) <= 16:
ccnet_rpc.remove_role(user_id, role)
return HttpResponseRedirect(request.META['HTTP_REFERER'])