mirror of
https://github.com/haiwen/seahub.git
synced 2025-07-31 06:40:39 +00:00
Add org account feature
This commit is contained in:
parent
5b96dc2ab2
commit
9c4a54931f
155
base/accounts.py
155
base/accounts.py
@ -9,7 +9,7 @@ from django.contrib.sites.models import Site
|
||||
from auth.models import get_hexdigest, check_password
|
||||
from auth import authenticate, login
|
||||
from registration import signals
|
||||
from registration.forms import RegistrationForm
|
||||
#from registration.forms import RegistrationForm
|
||||
from registration.models import RegistrationProfile
|
||||
from seaserv import ccnet_rpc, get_ccnetuser
|
||||
|
||||
@ -29,13 +29,15 @@ def convert_to_ccnetuser(emailuser):
|
||||
ccnetuser.is_staff = emailuser.props.is_staff
|
||||
ccnetuser.is_active = emailuser.props.is_active
|
||||
ccnetuser.ctime = emailuser.props.ctime
|
||||
|
||||
ccnetuser.org = emailuser.org
|
||||
|
||||
return ccnetuser
|
||||
|
||||
class CcnetUser(object):
|
||||
is_staff = False
|
||||
is_active = False
|
||||
objects = UserManager()
|
||||
org = None
|
||||
|
||||
def __init__(self, username, raw_password):
|
||||
self.username = username
|
||||
@ -225,12 +227,6 @@ class RegistrationBackend(object):
|
||||
# login the user
|
||||
activated.backend='auth.backends.ModelBackend'
|
||||
login(request, activated)
|
||||
# TODO: user.user_id should be change
|
||||
try:
|
||||
if request.user.user_id:
|
||||
ccnet_rpc.add_client(ccnet_user_id)
|
||||
except:
|
||||
pass
|
||||
|
||||
return activated
|
||||
|
||||
@ -323,3 +319,146 @@ class RegistrationForm(forms.Form):
|
||||
raise forms.ValidationError(_("The two password fields didn't match."))
|
||||
return self.cleaned_data
|
||||
|
||||
class OrgRegistrationForm(RegistrationForm):
|
||||
"""
|
||||
Form for registering a business user account.
|
||||
|
||||
Validates that the requested email is not already in use, and
|
||||
requires the password to be entered twice to catch typos.
|
||||
"""
|
||||
|
||||
org_name = forms.CharField(max_length=256,
|
||||
widget=forms.TextInput(),
|
||||
label=_("Organization Name"))
|
||||
url_prefix = forms.RegexField(label=_("Url Prefix"), max_length=20,
|
||||
regex=r'^[a-z0-9]+$',
|
||||
error_message=_("This value must contain only letters or numbers."))
|
||||
|
||||
def clean_url_prefix(self):
|
||||
url_prefix = self.cleaned_data['url_prefix']
|
||||
org = ccnet_rpc.get_org_by_url_prefix(url_prefix)
|
||||
if not org:
|
||||
return url_prefix
|
||||
else:
|
||||
raise forms.ValidationError(_("A organization with this url prefix already"))
|
||||
|
||||
class OrgRegistrationBackend(object):
|
||||
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
|
||||
org_name, url_prefix = kwargs['org_name'], kwargs['url_prefix']
|
||||
|
||||
if Site._meta.installed:
|
||||
site = Site.objects.get_current()
|
||||
else:
|
||||
site = RequestSite(request)
|
||||
|
||||
|
||||
if settings.ACTIVATE_AFTER_REGISTRATION:
|
||||
# since user will be activated after registration,
|
||||
# so we will not use email sending, just create acitvated user
|
||||
new_user = RegistrationProfile.objects.create_active_user(username, email,
|
||||
password, site,
|
||||
send_email=False)
|
||||
# create orgnization account
|
||||
try:
|
||||
ccnet_rpc.create_org(org_name, url_prefix, username)
|
||||
except SearpcError, e:
|
||||
pass
|
||||
else:
|
||||
# login the user
|
||||
new_user.backend='auth.backends.ModelBackend'
|
||||
login(request, new_user)
|
||||
else:
|
||||
# create inactive user, user can be activated by admin, or through activated email
|
||||
new_user = RegistrationProfile.objects.create_inactive_user(username, email,
|
||||
password, site,
|
||||
send_email=settings.REGISTRATION_SEND_MAIL)
|
||||
|
||||
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='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', (), {})
|
||||
|
@ -15,5 +15,6 @@ def base(request):
|
||||
"""
|
||||
return {
|
||||
'seafile_version': settings.SEAFILE_VERSION,
|
||||
'seahub_title': settings.SEAHUB_TITLE,
|
||||
'seahub_title': settings.SEAHUB_TITLE,
|
||||
'account_type': settings.ACCOUNT_TYPE,
|
||||
}
|
||||
|
@ -47,4 +47,3 @@ class InfobarMiddleware(object):
|
||||
|
||||
def process_response(self, request, response):
|
||||
return response
|
||||
|
||||
|
@ -6,13 +6,20 @@ from registration.views import activate
|
||||
from registration.views import register
|
||||
|
||||
from seahub.base.accounts import RegistrationForm
|
||||
from seahub.base.accounts import OrgRegistrationForm
|
||||
|
||||
reg_dict = { 'backend': 'seahub.base.accounts.RegistrationBackend',
|
||||
'form_class': RegistrationForm,
|
||||
}
|
||||
|
||||
org_reg_dict = { 'backend': 'seahub.base.accounts.OrgRegistrationBackend',
|
||||
'form_class': OrgRegistrationForm,
|
||||
'template_name': 'registration/org_registration_form.html',
|
||||
}
|
||||
|
||||
if settings.ACTIVATE_AFTER_REGISTRATION == True:
|
||||
reg_dict['success_url'] = settings.SITE_ROOT
|
||||
org_reg_dict['success_url'] = settings.SITE_ROOT
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^activate/complete/$',
|
||||
@ -40,5 +47,11 @@ urlpatterns = patterns('',
|
||||
direct_to_template,
|
||||
{ 'template': 'registration/registration_closed.html' },
|
||||
name='registration_disallowed'),
|
||||
|
||||
url(r'^business/register/$',
|
||||
register,
|
||||
org_reg_dict,
|
||||
name='registration_register'),
|
||||
|
||||
(r'', include('registration.auth_urls')),
|
||||
)
|
||||
|
@ -8,7 +8,7 @@
|
||||
<form action="" method="post">
|
||||
{{ form.user_email.as_hidden }}
|
||||
<label>邮箱:</label>
|
||||
{{ form.contact_email }}
|
||||
<input id="id_contact_email" type="text" maxlength="255" value="{{ old_contact_email }}" name="contact_email" readonly="readonly">
|
||||
<label>名字(可选):</label>
|
||||
{{ form.contact_name }}
|
||||
<label>备注(可选):</label>
|
||||
|
@ -35,8 +35,12 @@ def contact_add(request):
|
||||
elif contact_email == request.user.username:
|
||||
error_msg = u"不能添加自己为联系人"
|
||||
elif Contact.objects.filter(user_email=request.user.username,
|
||||
contact_email=contact_email).count() > 0:
|
||||
contact_email=contact_email).count() > 0:
|
||||
error_msg = u"联系人列表中已有该用户"
|
||||
elif request.user.org and \
|
||||
not ccnet_rpc.org_user_exists(request.user.org.org_id,
|
||||
contact_email):
|
||||
error_msg = u"当前企业不存在该用户"
|
||||
else:
|
||||
contact = Contact()
|
||||
contact.user_email = request.user.username
|
||||
@ -69,9 +73,9 @@ def contact_edit(request):
|
||||
emailuser = ccnet_rpc.get_emailuser(contact_email)
|
||||
if not emailuser:
|
||||
error_msg = u"用户不存在"
|
||||
elif cmp(contact_email, request.user.username) == 0:
|
||||
elif contact_email == request.user.username:
|
||||
error_msg = u"不能添加自己为联系人"
|
||||
elif cmp(old_contact_email, contact_email) != 0 and \
|
||||
elif old_contact_email != contact_email and \
|
||||
Contact.objects.filter(user_email=request.user.username,
|
||||
contact_email=contact_email).count() > 0:
|
||||
error_msg = u"联系人列表中已有该用户"
|
||||
|
@ -25,8 +25,12 @@ def group_list(request):
|
||||
return go_error(request, u'小组名称只能包含中英文字符,数字及下划线')
|
||||
|
||||
try:
|
||||
ccnet_rpc.create_group(group_name.encode('utf-8'),
|
||||
group_id = ccnet_rpc.create_group(group_name.encode('utf-8'),
|
||||
request.user.username)
|
||||
# TODO: transaction?
|
||||
if request.user.org and group_id > 0:
|
||||
ccnet_rpc.add_org_group(request.user.org.org_id,
|
||||
group_id)
|
||||
except SearpcError, e:
|
||||
error_msg = e.msg
|
||||
return go_error(request, error_msg)
|
||||
@ -62,11 +66,17 @@ def group_remove(request, group_id):
|
||||
try:
|
||||
ccnet_rpc.remove_group(group_id_int, request.user.username)
|
||||
seafserv_threaded_rpc.remove_repo_group(group_id_int, None)
|
||||
|
||||
if request.user.org:
|
||||
ccnet_rpc.remove_org_group(request.user.org.org_id,
|
||||
group_id_int)
|
||||
except SearpcError, e:
|
||||
return go_error(request, e.msg)
|
||||
|
||||
if request.GET.get('src', '') == 'groupadmin':
|
||||
return HttpResponseRedirect(reverse('group_admin'))
|
||||
if request.GET.get('src', '') == 'orggroupadmin':
|
||||
return HttpResponseRedirect(reverse('org_group_admin'))
|
||||
elif request.GET.get('src', '') == 'sysgroupadmin':
|
||||
return HttpResponseRedirect(reverse('sys_group_admin'))
|
||||
else:
|
||||
return HttpResponseRedirect(reverse('group_list', args=[]))
|
||||
|
||||
@ -178,17 +188,31 @@ def group_members(request, group_id):
|
||||
continue
|
||||
member_name_dict[member_name] = member_name
|
||||
|
||||
for member_name in member_name_dict.keys():
|
||||
if not validate_emailuser(member_name):
|
||||
err_msg = u'用户 %s 不存在' % member_name
|
||||
return go_error(request, err_msg)
|
||||
else:
|
||||
try:
|
||||
ccnet_rpc.group_add_member(group_id_int,
|
||||
request.user.username,
|
||||
member_name)
|
||||
except SearpcError, e:
|
||||
return go_error(request, e.msg)
|
||||
if request.user.org:
|
||||
for member_name in member_name_dict.keys():
|
||||
if not ccnet_rpc.org_user_exists(request.user.org.org_id,
|
||||
member_name):
|
||||
err_msg = u'当前企业不存在 %s 用户' % member_name
|
||||
return go_error(request, err_msg)
|
||||
else:
|
||||
try:
|
||||
ccnet_rpc.group_add_member(group_id_int,
|
||||
request.user.username,
|
||||
member_name)
|
||||
except SearpcError, e:
|
||||
return go_error(request, e.msg)
|
||||
else:
|
||||
for member_name in member_name_dict.keys():
|
||||
if not validate_emailuser(member_name):
|
||||
err_msg = u'用户 %s 不存在' % member_name
|
||||
return go_error(request, err_msg)
|
||||
else:
|
||||
try:
|
||||
ccnet_rpc.group_add_member(group_id_int,
|
||||
request.user.username,
|
||||
member_name)
|
||||
except SearpcError, e:
|
||||
return go_error(request, e.msg)
|
||||
|
||||
members = ccnet_rpc.get_group_members(group_id_int)
|
||||
contacts = Contact.objects.filter(user_email=request.user.username)
|
||||
|
@ -365,3 +365,14 @@ h2.repo-history {
|
||||
|
||||
/* notification admin */
|
||||
.cur-note { color: red; font-size: 75%; }
|
||||
|
||||
/* org */
|
||||
.org-member .avatar {
|
||||
border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.org-member .avatar,
|
||||
.org-member-name {
|
||||
vertical-align:middle;
|
||||
}
|
||||
|
@ -68,6 +68,7 @@ MIDDLEWARE_CLASSES = (
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'auth.middleware.AuthenticationMiddleware',
|
||||
'seahub.base.middleware.InfobarMiddleware',
|
||||
'seahub.subdomain.middleware.SubdomainMiddleware',
|
||||
# 'seahub.base.middleware.UseridMiddleware',
|
||||
)
|
||||
|
||||
@ -110,6 +111,7 @@ INSTALLED_APPS = (
|
||||
'seahub.contacts',
|
||||
'seahub.group',
|
||||
'seahub.share',
|
||||
'seahub.subdomain',
|
||||
)
|
||||
|
||||
AUTHENTICATION_BACKENDS = (
|
||||
@ -160,6 +162,13 @@ FILEEXT_ICON_MAP = {
|
||||
'default' : 'file-icon-24.png',
|
||||
}
|
||||
|
||||
SITE_SUBDOMAIN = 'cloud'
|
||||
SITE_BASE_NAME = 'seafile.com.cn' if not DEBUG else 'localhost.localdomain'
|
||||
SESSION_COOKIE_DOMAIN = '.' + SITE_BASE_NAME
|
||||
|
||||
# account type is `personal` or `business`
|
||||
ACCOUNT_TYPE = 'personal'
|
||||
|
||||
try:
|
||||
import local_settings
|
||||
except ImportError:
|
||||
|
@ -1,5 +1,5 @@
|
||||
{% autoescape off %}
|
||||
亲爱的:{{ anon_email }} 您好!
|
||||
亲爱的 {{ anon_email }}:
|
||||
|
||||
{{ email }} 在SeaCloud上共享了一个同步目录给你,请点击以下链接查看:
|
||||
|
||||
|
0
subdomain/__init__.py
Normal file
0
subdomain/__init__.py
Normal file
37
subdomain/middleware.py
Normal file
37
subdomain/middleware.py
Normal file
@ -0,0 +1,37 @@
|
||||
from django.http import HttpResponseRedirect, Http404
|
||||
|
||||
from seahub.settings import SITE_BASE_NAME, SITE_SUBDOMAIN
|
||||
|
||||
class SubdomainMiddleware(object):
|
||||
|
||||
def process_request(self, request):
|
||||
if not request.user.is_authenticated():
|
||||
return None
|
||||
|
||||
host = request.META.get('HTTP_HOST', '')
|
||||
http_or_https = request.is_secure() and 'https://' or 'http://'
|
||||
has_subdomain = True if host.replace(SITE_BASE_NAME, '', 1).find('.') >= 0 else False
|
||||
full_path = request.get_full_path()
|
||||
|
||||
if request.user.org:
|
||||
# business account
|
||||
url_prefix = request.user.org.url_prefix
|
||||
if not has_subdomain:
|
||||
host = request.user.org.url_prefix + '.' + host
|
||||
return HttpResponseRedirect(http_or_https + host + full_path)
|
||||
elif host.split('.')[0] != url_prefix:
|
||||
host = url_prefix + '.' + '.'.join(host.split('.')[1:])
|
||||
return HttpResponseRedirect(http_or_https + host + full_path)
|
||||
else:
|
||||
# personal account
|
||||
if not has_subdomain:
|
||||
host = SITE_SUBDOMAIN + '.' + host
|
||||
return HttpResponseRedirect(http_or_https + host + full_path)
|
||||
elif host.split('.')[0] != SITE_SUBDOMAIN:
|
||||
host = SITE_SUBDOMAIN + '.' + '.'.join(host.split('.')[1:])
|
||||
return HttpResponseRedirect(http_or_https + host + full_path)
|
||||
|
||||
return None
|
||||
|
||||
def process_response(self, request, response):
|
||||
return response
|
3
subdomain/models.py
Normal file
3
subdomain/models.py
Normal file
@ -0,0 +1,3 @@
|
||||
from django.db import models
|
||||
|
||||
# Create your models here.
|
23
subdomain/tests.py
Normal file
23
subdomain/tests.py
Normal 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
|
||||
"""}
|
||||
|
1
subdomain/views.py
Normal file
1
subdomain/views.py
Normal file
@ -0,0 +1 @@
|
||||
# Create your views here.
|
@ -1,4 +1,4 @@
|
||||
{% extends "admin_base.html" %}
|
||||
{% extends base_template %}
|
||||
{% block title %}添加用户{% endblock %}
|
||||
{% block nav_useradmin_class %}class="cur"{% endblock %}
|
||||
{% block main_panel %}
|
||||
@ -15,9 +15,9 @@
|
||||
{{ form.email.errors }}
|
||||
{{ form.password1.errors }}
|
||||
{{ form.password2.errors }}
|
||||
<p class="error hide" id="error"></p>
|
||||
<p class="error hide" id="error"></p>
|
||||
|
||||
<input type="submit" value="提交" class="submit" />
|
||||
<input type="submit" value="添加" class="submit" />
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
@ -4,16 +4,19 @@
|
||||
<ul class="nav w100 ovhd">
|
||||
{% if request.user.is_staff %}
|
||||
<li>
|
||||
<a href="{{ SITE_ROOT }}seafadmin/" {% block nav_seafadmin_class %}{% endblock %}>目录管理</a>
|
||||
<a href="{{ SITE_ROOT }}sys/seafadmin/" {% block nav_seafadmin_class %}{% endblock %}>目录管理</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ SITE_ROOT }}useradmin/" {% block nav_useradmin_class %}{% endblock %}>用户管理</a>
|
||||
<a href="{{ SITE_ROOT }}sys/useradmin/" {% block nav_useradmin_class %}{% endblock %}>用户管理</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ SITE_ROOT }}groupadmin/" {% block nav_groupadmin_class %}{% endblock %}>小组管理</a>
|
||||
<a href="{{ SITE_ROOT }}sys/groupadmin/" {% block nav_groupadmin_class %}{% endblock %}>小组管理</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ SITE_ROOT }}notificationadmin/" {% block nav_notificationadmin_class %}{% endblock %}>通知管理</a>
|
||||
<a href="{{ SITE_ROOT }}sys/orgadmin/" {% block nav_orgadmin_class %}{% endblock %}>企业管理</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ SITE_ROOT }}sys/notificationadmin/" {% block nav_notificationadmin_class %}{% endblock %}>通知管理</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
@ -25,10 +25,15 @@
|
||||
<div id="top-bar">
|
||||
<div class="top-bar">
|
||||
<div class="top-bar-in w100 ovhd">
|
||||
{% if request.user.is_staff %}
|
||||
{% if request.user.is_staff or request.user.org.is_staff %}
|
||||
<div class="fleft">
|
||||
<a href="{{ SITE_ROOT }}seafadmin/"{% block top_bar_manager_class %}{% endblock %}>管理员控制台</a>
|
||||
<a href="{{ SITE_ROOT }}home/my/"{% block top_bar_myaccount_class %}{% endblock %}>我的帐号</a>
|
||||
{% if request.user.is_staff %}
|
||||
<a href="{{ SITE_ROOT }}sys/seafadmin/"
|
||||
{% else %}
|
||||
<a href="{{ SITE_ROOT }}seafadmin/"
|
||||
{% endif %}
|
||||
{% block top_bar_manager_class %}{% endblock %}>管理员控制台</a>
|
||||
<a href="{{ SITE_ROOT }}home/my/"{% block top_bar_myaccount_class %}{% endblock %}>我的帐号</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@ -43,9 +48,13 @@
|
||||
-->
|
||||
<a href="{{ SITE_ROOT }}accounts/logout/">退出</a>
|
||||
{% else %}
|
||||
<a href="{{ SITE_ROOT }}accounts/login/">登录</a>
|
||||
<a href="{{ SITE_ROOT }}accounts/login/">登录</a>
|
||||
{% if account_type == 'business' %}
|
||||
<a href="{{ SITE_ROOT }}accounts/business/register/">注册</a>
|
||||
{% else %}
|
||||
<a href="{{ SITE_ROOT }}accounts/register/">注册</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,6 +4,11 @@
|
||||
{% block nav_myhome_class %}class="cur"{% endblock %}
|
||||
{% block left_panel %}
|
||||
|
||||
{% if request.user.org %}
|
||||
<h3>所属企业</h3>
|
||||
<p>{{ request.user.org.org_name }}</p>
|
||||
{% endif %}
|
||||
|
||||
<h3>已用空间</h3>
|
||||
<p>{{ quota_usage|filesizeformat }} / 2 GB</p>
|
||||
|
||||
|
@ -5,6 +5,11 @@
|
||||
<li>
|
||||
<a href="{{ SITE_ROOT }}home/my/" {% block nav_myhome_class %}{% endblock %}>我的页面</a>
|
||||
</li>
|
||||
{% if request.user.org %}
|
||||
<li>
|
||||
<a href="{{ SITE_ROOT }}org/" {% block nav_org_class %}{% endblock %}>企业</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li>
|
||||
<a href="{{ SITE_ROOT }}group/" {% block nav_group_class %}{% endblock %}>小组</a>
|
||||
</li>
|
||||
|
18
templates/org_admin_base.html
Normal file
18
templates/org_admin_base.html
Normal file
@ -0,0 +1,18 @@
|
||||
{% extends "base.html" %}
|
||||
{% block top_bar_manager_class %} class="cur"{% endblock %}
|
||||
{% block nav %}
|
||||
<ul class="nav w100 ovhd">
|
||||
{% if request.user.org.is_staff %}
|
||||
<li>
|
||||
<a href="{{ SITE_ROOT }}seafadmin/" {% block nav_seafadmin_class %}{% endblock %}>目录管理</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ SITE_ROOT }}useradmin/" {% block nav_useradmin_class %}{% endblock %}>用户管理</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ SITE_ROOT }}groupadmin/" {% block nav_groupadmin_class %}{% endblock %}>小组管理</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
</ul>
|
||||
{% endblock %}
|
60
templates/org_group_admin.html
Normal file
60
templates/org_group_admin.html
Normal file
@ -0,0 +1,60 @@
|
||||
{% extends "org_admin_base.html" %}
|
||||
{% load seahub_tags %}
|
||||
|
||||
{% block nav_groupadmin_class %}class="cur"{% endblock %}
|
||||
|
||||
{% block right_panel %}
|
||||
<h3>所有小组</h3>
|
||||
{% if groups %}
|
||||
<table>
|
||||
<tr>
|
||||
<th width="30%">名字</th>
|
||||
<th width="40%">创建者</th>
|
||||
<th width="23%">创建时间</th>
|
||||
<th width="7%">操作</th>
|
||||
</tr>
|
||||
{% for group in groups %}
|
||||
<tr>
|
||||
<td><a href="{{ SITE_ROOT }}group/{{ group.props.id }}/">{{ group.props.group_name }}</a></td>
|
||||
<td>{{ group.props.creator_name }}</td>
|
||||
<td>{{ group.props.timestamp|tsstr_sec }}</td>
|
||||
<td><button data="{{ SITE_ROOT}}group/{{ group.id }}/?op=delete&src=orggroupadmin" class="group-remove-btn">删除</button></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
<div id="paginator">
|
||||
{% if current_page != 1 %}
|
||||
<a href="{{ SITE_ROOT }}groupadmin/?page={{ prev_page }}&per_page={{ per_page }}">上一页</a>
|
||||
{% endif %}
|
||||
{% if page_next %}
|
||||
<a href="{{ SITE_ROOT }}groupadmin/?page={{ next_page }}&per_page={{ per_page }}">下一页</a>
|
||||
{% endif %}
|
||||
<span>每页:</span>
|
||||
{% if per_page == 25 %}
|
||||
<span> 25 </span>
|
||||
{% else %}
|
||||
<a href="{{ SITE_ROOT }}groupadmin/?per_page=25" class="per-page">25</a>
|
||||
{% endif %}
|
||||
{% if per_page == 50 %}
|
||||
<span> 50 </span>
|
||||
{% else %}
|
||||
<a href="{{ SITE_ROOT }}groupadmin/?per_page=50" class="per-page">50</a>
|
||||
{% endif %}
|
||||
{% if per_page == 100 %}
|
||||
<span> 100 </span>
|
||||
{% else %}
|
||||
<a href="{{ SITE_ROOT }}groupadmin/?per_page=100" class="per-page">100</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<p>暂无</p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script type="text/javascript">
|
||||
addConfirmTo($('.group-remove-btn'), '确定要删除小组?')
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
103
templates/org_info.html
Normal file
103
templates/org_info.html
Normal file
@ -0,0 +1,103 @@
|
||||
{% extends "myhome_base.html" %}
|
||||
{% load seahub_tags avatar_tags %}
|
||||
|
||||
{% block nav_org_class %}class="cur"{% endblock %}
|
||||
|
||||
{% block main_panel %}
|
||||
<h2>{{ org.org_name }}</h2>
|
||||
<div class="side fright">
|
||||
<h3>企业成员</h3>
|
||||
{% if org_users %}
|
||||
<ul>
|
||||
{% for member in org_users %}
|
||||
<li class="org-member">{% avatar member.user_name 16 %}<span class="org-member-name">{{ member.short_username }}</span></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<p>暂无</p>
|
||||
{% endif %}
|
||||
|
||||
{% if is_join %}
|
||||
<h3>操作</h3>
|
||||
<ul class="with-bg">
|
||||
{% if is_staff %}
|
||||
<li><a id="group-mgr" href="{{ SITE_ROOT }}group/{{ group.id }}/members/">小组管理</a></li>
|
||||
{% else %}
|
||||
<li><a id="quit-group" href="#" data="{{ SITE_ROOT }}group/{{ group.id }}/?op=quit">退出小组</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="main fleft">
|
||||
<h3>企业里公开的同步目录</h3>
|
||||
{% if repos %}
|
||||
<table>
|
||||
<tr>
|
||||
<th width="20%">名字</th>
|
||||
<th width="48%">描述</th>
|
||||
<th width="22%">共享来源</th>
|
||||
<th width="10%">操作</th>
|
||||
</tr>
|
||||
|
||||
{% for repo in repos %}
|
||||
<tr>
|
||||
<td><a href="{{ SITE_ROOT }}repo/{{ repo.props.id }}/">{{ repo.props.name }}</a></td>
|
||||
<td>{{ repo.props.desc }}</td>
|
||||
<td>{{ repo.share_from }}</td>
|
||||
<td>
|
||||
<img src="{{ MEDIA_URL }}img/download-20.png" class="download vh" data="{{ SITE_ROOT }}seafile_access_check/?repo_id={{ repo.props.id }}" alt="下载" title="下载" />
|
||||
{% if is_staff or repo.share_from_me %}
|
||||
<img src="{{ MEDIA_URL }}img/delete-20.png" class="cancel-share vh" data="{{ SITE_ROOT }}shareadmin/removeshare/?repo_id={{ repo.props.id }}&from={{ repo.share_from }}&gid={{ group.id }}" title="取消共享" alt="取消共享" />
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
<p>暂无</p>
|
||||
{% endif %}
|
||||
|
||||
<h3>企业里的小组</h3>
|
||||
{% if groups %}
|
||||
<table>
|
||||
<tr>
|
||||
<th width="30%">名字</th>
|
||||
<th widht="40%">创建者</th>
|
||||
<th width="30%">创建时间</th>
|
||||
</tr>
|
||||
|
||||
{% for group in groups %}
|
||||
<tr>
|
||||
<td>{{ group.group_name }}</td>
|
||||
<td>{{ group.creator_name }}</td>
|
||||
<td>{{ group.timestamp|tsstr_sec }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
</table>
|
||||
{% else %}
|
||||
<p>暂无</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script type="text/javascript">
|
||||
addConfirmTo($('#quit-group'), '确定要退出?');
|
||||
addConfirmTo($('.cancel-share'), '确定要取消共享该目录?');
|
||||
|
||||
$("table tr:gt(0)").hover(
|
||||
function() {
|
||||
$(this).find('img').css('cursor', 'pointer').removeClass('vh');
|
||||
},
|
||||
function() {
|
||||
$(this).find('img').addClass('vh');
|
||||
}
|
||||
);
|
||||
|
||||
$('.download').click(function() {
|
||||
window.open($(this).attr('data'));
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
58
templates/org_seafadmin.html
Normal file
58
templates/org_seafadmin.html
Normal file
@ -0,0 +1,58 @@
|
||||
{% extends "org_admin_base.html" %}
|
||||
{% block nav_seafadmin_class %}class="cur"{% endblock %}
|
||||
|
||||
{% block right_panel %}
|
||||
<h3>所有同步目录</h3>
|
||||
{% if repos %}
|
||||
<table>
|
||||
<tr>
|
||||
<th width="25%">名字</th>
|
||||
<th width="28%">拥有者</th>
|
||||
<th width="40%">描述</th>
|
||||
<th width="7%">操作</th>
|
||||
</tr>
|
||||
{% for repo in repos %}
|
||||
<tr>
|
||||
<td><a href="{{ SITE_ROOT }}repo/{{ repo.props.id }}/">{{ repo.props.name }}</a></td>
|
||||
<td><a href="{{ SITE_ROOT }}useradmin/info/{{ repo.owner }}/">{{ repo.owner}}</a></td>
|
||||
<td>{{ repo.props.desc }}</td>
|
||||
<td><button data="{{ SITE_ROOT }}repo/remove/{{ repo.props.id }}/?next={{ request.path }}" class="repo-delete-btn">删除</button></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
<div id="paginator">
|
||||
{% if current_page != 1 %}
|
||||
<a href="{{ SITE_ROOT }}seafadmin/?page={{ prev_page }}&per_page={{ per_page }}">上一页</a>
|
||||
{% endif %}
|
||||
{% if page_next %}
|
||||
<a href="{{ SITE_ROOT }}seafadmin/?page={{ next_page }}&per_page={{ per_page }}">下一页</a>
|
||||
{% endif %}
|
||||
<span>每页:</span>
|
||||
{% if per_page == 25 %}
|
||||
<span> 25 </span>
|
||||
{% else %}
|
||||
<a href="{{ SITE_ROOT }}seafadmin/?per_page=25" class="per-page">25</a>
|
||||
{% endif %}
|
||||
{% if per_page == 50 %}
|
||||
<span> 50 </span>
|
||||
{% else %}
|
||||
<a href="{{ SITE_ROOT }}seafadmin/?per_page=50" class="per-page">50</a>
|
||||
{% endif %}
|
||||
{% if per_page == 100 %}
|
||||
<span> 100 </span>
|
||||
{% else %}
|
||||
<a href="{{ SITE_ROOT }}seafadmin/?per_page=100" class="per-page">100</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<p>暂无</p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script type="text/javascript">
|
||||
addConfirmTo($('.repo-delete-btn'));
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% extends "admin_base.html" %}
|
||||
{% extends "org_admin_base.html" %}
|
||||
|
||||
{% block nav_useradmin_class %}class="cur"{% endblock %}
|
||||
{% block left_panel %}
|
||||
@ -10,6 +10,18 @@
|
||||
|
||||
|
||||
{% block right_panel %}
|
||||
{% if messages %}
|
||||
<ul class="messages">
|
||||
{% for message in messages %}
|
||||
{% if message.tags == 'info' %}
|
||||
<li class="notification">邮件发送成功。</li>
|
||||
{% endif %}
|
||||
{% if message.tags == 'error' %}
|
||||
<li class="error">邮件发送失败。</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
<h3>所有用户</h3>
|
||||
<table>
|
||||
@ -32,7 +44,7 @@
|
||||
<!-- <button class="add-role-btn" userid="{{ user.profile.ccnet_user_id }}" email="{{ user.email }}">添加角色</button> -->
|
||||
{% endif %}
|
||||
{% if not user.is_self %}
|
||||
<button class="remove-user-btn" data="{{ SITE_ROOT }}useradmin/{{ user.props.id }}/user/remove/">删除</button>
|
||||
<button class="remove-user-btn" data="{{ SITE_ROOT }}useradmin/remove/{{ user.props.id }}/">删除</button>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
52
templates/registration/org_registration_form.html
Normal file
52
templates/registration/org_registration_form.html
Normal file
@ -0,0 +1,52 @@
|
||||
{% extends "myhome_base.html" %}
|
||||
{% block title %}注册{% endblock %}
|
||||
{% block main_panel %}
|
||||
<div class="narrow-panel">
|
||||
{% if request.user.is_authenticated %}
|
||||
<h2>欢迎回来,您已登录。</h2>
|
||||
{% else %}
|
||||
<h2>注册企业帐号</h2>
|
||||
<form action="" method="post">
|
||||
<label for="id_email">邮箱:</label>
|
||||
{{ form.email }}
|
||||
<label for="id_password1">密码:</label>
|
||||
{{ form.password1 }}
|
||||
<label for="id_password2">确认密码:</label>
|
||||
{{ form.password2 }}
|
||||
<label for="id_org_name">企业名称:</label>
|
||||
{{ form.org_name}}
|
||||
<lable for="id_url_prefix">域名前缀:</label>
|
||||
{{ form.url_prefix }}
|
||||
<p class="error hide"></p>
|
||||
{{ form.email.errors }}
|
||||
{{ form.password1.errors }}
|
||||
{{ form.password2.errors }}
|
||||
{{ form.url_prefix.errors }}
|
||||
<input type="submit" value="提交" class="submit" />
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script type="text/javascript">
|
||||
$('input[type="submit"]').click(function(){
|
||||
if (!$.trim($('input[name="email"]').attr('value'))) {
|
||||
$('.error').removeClass('hide').html('请输入邮箱。');
|
||||
return false;
|
||||
}
|
||||
if (!$.trim($('input[name="password1"]').attr('value'))) {
|
||||
$('.error').removeClass('hide').html('请输入密码。');
|
||||
return false;
|
||||
}
|
||||
if (!$.trim($('input[name="password2"]').attr('value'))) {
|
||||
$('.error').removeClass('hide').html('请确认密码。');
|
||||
return false;
|
||||
}
|
||||
if ($.trim($('input[name="password1"]').attr('value')) != $.trim($('input[name="password2"]').attr('value'))) {
|
||||
$('.error').removeClass('hide').html('两次输入的密码不一致。');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
@ -18,7 +18,7 @@
|
||||
<td><a href="{{ SITE_ROOT }}group/{{ group.props.id }}/">{{ group.props.group_name }}</a></td>
|
||||
<td>{{ group.props.creator_name }}</td>
|
||||
<td>{{ group.props.timestamp|tsstr_sec }}</td>
|
||||
<td><button data="{{ SITE_ROOT}}group/{{ group.id }}/?op=delete&src=groupadmin" class="group-remove-btn">删除</button></td>
|
||||
<td><button data="{{ SITE_ROOT}}group/{{ group.id }}/?op=delete&src=sysgroupadmin" class="group-remove-btn">删除</button></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
64
templates/sys_org_admin.html
Normal file
64
templates/sys_org_admin.html
Normal file
@ -0,0 +1,64 @@
|
||||
{% extends "admin_base.html" %}
|
||||
{% load seahub_tags %}
|
||||
|
||||
{% block nav_orgadmin_class %}class="cur"{% endblock %}
|
||||
|
||||
{% block right_panel %}
|
||||
<h3>所有企业</h3>
|
||||
{% if orgs %}
|
||||
<table>
|
||||
<tr>
|
||||
<th width="20%">名字</th>
|
||||
<th width="30%">域名前缀</th>
|
||||
<th width="20%">创建者</th>
|
||||
<th width="23%">创建时间</th>
|
||||
<th width="7%">操作</th>
|
||||
</tr>
|
||||
{% for org in orgs %}
|
||||
<tr>
|
||||
<td>{{ org.org_name }}</td>
|
||||
<td>{{ org.url_prefix }}</td>
|
||||
<td>{{ org.creator }}</td>
|
||||
<td>{{ org.ctime|tsstr_sec }}</td>
|
||||
<td><button data="{{ SITE_ROOT}}org/remove/{{ org.org_id }}/" class="org-remove-btn">删除</button></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
<!--
|
||||
<div id="paginator">
|
||||
{% if current_page != 1 %}
|
||||
<a href="{{ SITE_ROOT }}groupadmin/?page={{ prev_page }}&per_page={{ per_page }}">上一页</a>
|
||||
{% endif %}
|
||||
{% if page_next %}
|
||||
<a href="{{ SITE_ROOT }}groupadmin/?page={{ next_page }}&per_page={{ per_page }}">下一页</a>
|
||||
{% endif %}
|
||||
<span>每页:</span>
|
||||
{% if per_page == 25 %}
|
||||
<span> 25 </span>
|
||||
{% else %}
|
||||
<a href="{{ SITE_ROOT }}groupadmin/?per_page=25" class="per-page">25</a>
|
||||
{% endif %}
|
||||
{% if per_page == 50 %}
|
||||
<span> 50 </span>
|
||||
{% else %}
|
||||
<a href="{{ SITE_ROOT }}groupadmin/?per_page=50" class="per-page">50</a>
|
||||
{% endif %}
|
||||
{% if per_page == 100 %}
|
||||
<span> 100 </span>
|
||||
{% else %}
|
||||
<a href="{{ SITE_ROOT }}groupadmin/?per_page=100" class="per-page">100</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
-->
|
||||
{% else %}
|
||||
<p>暂无</p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script type="text/javascript">
|
||||
addConfirmTo($('.org-remove-btn'), '确定要删除该企业?');
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
87
templates/sys_useradmin.html
Normal file
87
templates/sys_useradmin.html
Normal file
@ -0,0 +1,87 @@
|
||||
{% extends "admin_base.html" %}
|
||||
|
||||
{% block nav_useradmin_class %}class="cur"{% endblock %}
|
||||
{% block left_panel %}
|
||||
<h3>操作</h3>
|
||||
<ul class="with-bg">
|
||||
<li><a href="{{ SITE_ROOT }}useradmin/add/">添加用户</a></li>
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block right_panel %}
|
||||
{% if messages %}
|
||||
<ul class="messages">
|
||||
{% for message in messages %}
|
||||
{% if message.tags == 'info' %}
|
||||
<li class="notification">邮件发送成功。</li>
|
||||
{% endif %}
|
||||
{% if message.tags == 'error' %}
|
||||
<li class="error">邮件发送失败。</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
<h3>所有用户</h3>
|
||||
<table>
|
||||
<tr>
|
||||
<th width="50%">邮箱</th>
|
||||
<th width="20%">是否激活</th>
|
||||
<th width="20%">是否企业帐号</th>
|
||||
<th width="10%">操作</th>
|
||||
</tr>
|
||||
|
||||
{% for user in users %}
|
||||
<tr>
|
||||
<td><a href="{{ SITE_ROOT }}useradmin/info/{{ user.props.email }}/">{{ user.props.email }}</a></td>
|
||||
{% if user.props.is_active %}
|
||||
<td>已激活</td>
|
||||
{% else %}
|
||||
<td><button data="{{ SITE_ROOT }}useradmin/activate/{{ user.props.id }}/" class="activate">激活</button></td>
|
||||
{% endif %}
|
||||
{% if user.is_org_user %}
|
||||
<td>是</td>
|
||||
{% else %}
|
||||
<td></td>
|
||||
{% endif %}
|
||||
<td>
|
||||
{% if user.profile %}
|
||||
<!-- <button class="add-role-btn" userid="{{ user.profile.ccnet_user_id }}" email="{{ user.email }}">添加角色</button> -->
|
||||
{% endif %}
|
||||
{% if not user.is_self %}
|
||||
<button class="remove-user-btn" data="{{ SITE_ROOT }}useradmin/remove/{{ user.props.id }}/">删除</button>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
<form id="add-role-form" action="" method="post" class="hide">
|
||||
<p><span id="user_email"></span> 的新角色 (即 MyClient 等):</p>
|
||||
<input id="id_role" type="text" name="role" /><br/>
|
||||
<input id="id_summit" type="submit" value="提交" />
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script type="text/javascript">
|
||||
$('.activate').each(function(){
|
||||
$(this).click(function(){
|
||||
location.href = $(this).attr('data');
|
||||
});
|
||||
});
|
||||
$(".add-role-btn").each(function() {
|
||||
$(this).click(function() {
|
||||
var url = "{{ SITE_ROOT }}useradmin/" + $(this).attr("userid") + "/role/add/";
|
||||
$("#add-role-form").attr('action', url);
|
||||
$("#user_email").html($(this).attr("email"));
|
||||
$("#add-role-form").modal({appendTo: "#main"});
|
||||
});
|
||||
});
|
||||
|
||||
//delete confirm
|
||||
addConfirmTo($('.remove-user-btn'));
|
||||
addConfirmTo($('.role-delete-btn'));
|
||||
</script>
|
||||
{% endblock %}
|
19
templates/user_add_email.html
Normal file
19
templates/user_add_email.html
Normal file
@ -0,0 +1,19 @@
|
||||
{% autoescape off %}
|
||||
亲爱的 {{ email }}:
|
||||
{% if org %}
|
||||
{{ user }} 在 SeaCloud 云存储上将您加入到企业 {{ org.org_name }}!
|
||||
{% else %}
|
||||
{{ user }} 将您加入 SeaCloud 云存储!
|
||||
{% endif %}
|
||||
以下是您的登录信息:
|
||||
用户名: {{ email }}
|
||||
密码: {{ password }}
|
||||
|
||||
请点击以下链接登录:
|
||||
{{ protocol }}://{{ domain }}{% url auth_login %}
|
||||
|
||||
感谢使用我们的网站!
|
||||
|
||||
Seafile团队
|
||||
|
||||
{% endautoescape %}
|
@ -50,7 +50,6 @@ def login(request, template_name='registration/login.html',
|
||||
# Okay, security checks complete. Log the user in.
|
||||
auth_login(request, form.get_user())
|
||||
|
||||
|
||||
if request.session.test_cookie_worked():
|
||||
request.session.delete_test_cookie()
|
||||
|
||||
|
@ -304,6 +304,10 @@ def get_ccnetuser(username=None, userid=None):
|
||||
emailuser = ccnet_rpc.get_emailuser_by_id(userid)
|
||||
if not emailuser:
|
||||
return None
|
||||
|
||||
# Check whether is business account
|
||||
org = ccnet_rpc.get_org_by_user(emailuser.email)
|
||||
emailuser.org = org
|
||||
|
||||
# And convert to ccnetuser
|
||||
from seahub.base.accounts import convert_to_ccnetuser
|
||||
|
33
urls.py
33
urls.py
@ -3,12 +3,13 @@ from django.conf import settings
|
||||
from django.views.generic.simple import direct_to_template
|
||||
|
||||
from seahub.views import root, peers, myhome, \
|
||||
repo, repo_history, modify_token, remove_repo, seafadmin, useradmin, \
|
||||
activate_user, user_add, user_remove, \
|
||||
repo, repo_history, modify_token, remove_repo, sys_seafadmin, sys_useradmin, \
|
||||
org_seafadmin, org_useradmin, org_group_admin, org_remove, \
|
||||
activate_user, user_add, user_remove, sys_group_admin, sys_org_admin, \
|
||||
ownerhome, repo_history_dir, repo_history_revert, \
|
||||
user_info, repo_set_access_property, repo_access_file, \
|
||||
repo_remove_share, repo_download, \
|
||||
seafile_access_check, back_local, group_admin, repo_history_changes
|
||||
repo_remove_share, repo_download, org_info, \
|
||||
seafile_access_check, back_local, repo_history_changes
|
||||
from seahub.notifications.views import notification_list
|
||||
from seahub.share.views import share_admin
|
||||
|
||||
@ -50,25 +51,33 @@ urlpatterns = patterns('',
|
||||
(r'^repo/(?P<repo_id>[^/]+)/(?P<obj_id>[^/]+)/$', repo_access_file),
|
||||
(r'^download/repo/$', repo_download),
|
||||
(r'^seafile_access_check/$', seafile_access_check),
|
||||
url(r'^org/remove/(?P<org_id>[\d]+)/$', org_remove, name="org_remove"),
|
||||
(r'^org/$', org_info),
|
||||
(r'^back/local/$', back_local),
|
||||
|
||||
(r'^seafadmin/$', seafadmin),
|
||||
url(r'^useradmin/$', useradmin, name='useradmin'),
|
||||
(r'^useradmin/add/$', user_add),
|
||||
(r'^useradmin/remove/(?P<user_id>[^/]+)/$', user_remove),
|
||||
(r'^useradmin/info/(?P<email>[^/]+)/$', user_info),
|
||||
# (r'^useradmin/(?P<user_id>[^/]+)/role/add/$', role_add),
|
||||
# (r'^useradmin/(?P<user_id>[^/]+)/role/remove/$', role_remove),
|
||||
(r'^useradmin/(?P<user_id>[^/]+)/user/remove/$', user_remove),
|
||||
(r'^useradmin/activate/(?P<user_id>[^/]+)/$', activate_user),
|
||||
|
||||
### Apps ###
|
||||
(r'^avatar/', include('avatar.urls')),
|
||||
(r'^notification/', include('notifications.urls')),
|
||||
url(r'^notificationadmin/', notification_list, name='notification_list'),
|
||||
url(r'^sys/notificationadmin/', notification_list, name='notification_list'),
|
||||
(r'^contacts/', include('contacts.urls')),
|
||||
(r'^group/', include('seahub.group.urls')),
|
||||
url(r'^groupadmin/$', group_admin, name='group_admin'),
|
||||
(r'^profile/', include('seahub.profile.urls')),
|
||||
|
||||
(r'^back/local/$', back_local),
|
||||
### SeaHub admin ###
|
||||
(r'^sys/seafadmin/$', sys_seafadmin),
|
||||
url(r'^sys/useradmin/$', sys_useradmin, name='sys_useradmin'),
|
||||
url(r'^sys/orgadmin/$', sys_org_admin, name='sys_org_admin'),
|
||||
url(r'^sys/groupadmin/$', sys_group_admin, name='sys_group_admin'),
|
||||
|
||||
### Org admin ###
|
||||
(r'^seafadmin/$', org_seafadmin),
|
||||
url(r'^useradmin/$', org_useradmin, name='org_useradmin'),
|
||||
url(r'^groupadmin/$', org_group_admin, name='org_group_admin'),
|
||||
)
|
||||
|
||||
if settings.DEBUG:
|
||||
|
23
utils.py
23
utils.py
@ -9,7 +9,7 @@ from django.utils.hashcompat import sha_constructor
|
||||
|
||||
def go_permission_error(request, msg=None):
|
||||
"""
|
||||
return permisson error page
|
||||
Return permisson error page.
|
||||
|
||||
"""
|
||||
return render_to_response('permission_error.html', {
|
||||
@ -18,7 +18,7 @@ def go_permission_error(request, msg=None):
|
||||
|
||||
def go_error(request, msg=None):
|
||||
"""
|
||||
return normal error page
|
||||
Return normal error page.
|
||||
|
||||
"""
|
||||
return render_to_response('error.html', {
|
||||
@ -27,20 +27,15 @@ def go_error(request, msg=None):
|
||||
|
||||
def list_to_string(l):
|
||||
"""
|
||||
return string of a list
|
||||
Return string of a list.
|
||||
|
||||
"""
|
||||
tmp_str = ''
|
||||
for e in l[:-1]:
|
||||
tmp_str = tmp_str + e + ', '
|
||||
tmp_str = tmp_str + l[-1]
|
||||
|
||||
return tmp_str
|
||||
return ','.join(l)
|
||||
|
||||
def get_httpserver_root():
|
||||
"""
|
||||
Get seafile http server address and port from settings.py,
|
||||
and cut out last '/'
|
||||
and cut out last '/'.
|
||||
|
||||
"""
|
||||
if settings.HTTP_SERVER_ROOT[-1] == '/':
|
||||
@ -52,7 +47,7 @@ def get_httpserver_root():
|
||||
def get_ccnetapplet_root():
|
||||
"""
|
||||
Get ccnet applet address and port from settings.py,
|
||||
and cut out last '/'
|
||||
and cut out last '/'.
|
||||
|
||||
"""
|
||||
if settings.CCNET_APPLET_ROOT[-1] == '/':
|
||||
@ -63,17 +58,17 @@ def get_ccnetapplet_root():
|
||||
|
||||
def gen_token():
|
||||
"""
|
||||
Generate short token used for owner to access repo file
|
||||
Generate short token used for owner to access repo file.
|
||||
|
||||
"""
|
||||
|
||||
token = sha_constructor(settings.SECRET_KEY + unicode(time.time())).hexdigest()[::8]
|
||||
token = sha_constructor(settings.SECRET_KEY + unicode(time.time())).hexdigest()[:5]
|
||||
return token
|
||||
|
||||
def validate_group_name(group_name):
|
||||
"""
|
||||
Check whether group name is valid.
|
||||
A valid group name only contains alphanumeric character
|
||||
A valid group name only contains alphanumeric character.
|
||||
|
||||
"""
|
||||
return re.match('^\w+$', group_name, re.U)
|
||||
|
218
views.py
218
views.py
@ -2,13 +2,16 @@
|
||||
import settings
|
||||
import stat
|
||||
import simplejson as json
|
||||
import sys
|
||||
from urllib import quote
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.core.mail import send_mail
|
||||
from django.contrib import messages
|
||||
from django.contrib.sites.models import Site, RequestSite
|
||||
from django.db import IntegrityError
|
||||
from django.http import HttpResponse, HttpResponseRedirect, Http404
|
||||
from django.shortcuts import render_to_response, redirect
|
||||
from django.template import RequestContext
|
||||
from django.template import Context, loader, RequestContext
|
||||
from django.views.decorators.csrf import csrf_protect
|
||||
|
||||
from auth.decorators import login_required
|
||||
@ -713,7 +716,7 @@ def mypeers(request):
|
||||
cid = get_user_cid(request.user)
|
||||
|
||||
@login_required
|
||||
def seafadmin(request):
|
||||
def sys_seafadmin(request):
|
||||
if not request.user.is_staff:
|
||||
raise Http404
|
||||
|
||||
@ -728,6 +731,7 @@ def seafadmin(request):
|
||||
repos_all = seafserv_threaded_rpc.get_repo_list(per_page *
|
||||
(current_page -1),
|
||||
per_page + 1)
|
||||
|
||||
repos = repos_all[:per_page]
|
||||
|
||||
if len(repos_all) == per_page + 1:
|
||||
@ -742,7 +746,7 @@ def seafadmin(request):
|
||||
repo.owner = None
|
||||
|
||||
return render_to_response(
|
||||
'repos.html', {
|
||||
'sys_seafadmin.html', {
|
||||
'repos': repos,
|
||||
'current_page': current_page,
|
||||
'prev_page': current_page-1,
|
||||
@ -753,17 +757,80 @@ def seafadmin(request):
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
@login_required
|
||||
def useradmin(request):
|
||||
def org_seafadmin(request):
|
||||
if not request.user.org:
|
||||
raise Http404
|
||||
|
||||
# Make sure page request is an int. If not, deliver first page.
|
||||
try:
|
||||
current_page = int(request.GET.get('page', '1'))
|
||||
per_page= int(request.GET.get('per_page', '25'))
|
||||
except ValueError:
|
||||
current_page = 1
|
||||
per_page = 25
|
||||
|
||||
repos_all = seafserv_threaded_rpc.get_org_repo_list(request.user.org.org_id,
|
||||
per_page * (current_page -1),
|
||||
per_page + 1)
|
||||
|
||||
repos = repos_all[:per_page]
|
||||
|
||||
if len(repos_all) == per_page + 1:
|
||||
page_next = True
|
||||
else:
|
||||
page_next = False
|
||||
|
||||
for repo in repos:
|
||||
try:
|
||||
repo.owner = seafserv_threaded_rpc.get_repo_owner(repo.props.id)
|
||||
except:
|
||||
repo.owner = None
|
||||
|
||||
return render_to_response(
|
||||
'org_seafadmin.html', {
|
||||
'repos': repos,
|
||||
'current_page': current_page,
|
||||
'prev_page': current_page-1,
|
||||
'next_page': current_page+1,
|
||||
'per_page': per_page,
|
||||
'page_next': page_next,
|
||||
},
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
@login_required
|
||||
def sys_useradmin(request):
|
||||
if not request.user.is_staff:
|
||||
raise Http404
|
||||
|
||||
users = ccnet_rpc.get_emailusers(-1,-1)
|
||||
|
||||
for user in users:
|
||||
if user.props.id == request.user.id:
|
||||
user.is_self = True
|
||||
# TODO: may add new is_org_user rpc
|
||||
user.is_org_user = True if ccnet_rpc.get_org_by_user(user.email) else False
|
||||
|
||||
return render_to_response(
|
||||
'useradmin.html', {
|
||||
'sys_useradmin.html', {
|
||||
'users': users,
|
||||
},
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
@login_required
|
||||
def org_useradmin(request):
|
||||
if not request.user.org.is_staff:
|
||||
raise Http404
|
||||
|
||||
users = ccnet_rpc.get_org_emailusers(request.user.org.url_prefix,
|
||||
0, sys.maxint)
|
||||
|
||||
for user in users:
|
||||
if user.props.id == request.user.id:
|
||||
user.is_self = True
|
||||
user.is_org_user = True
|
||||
|
||||
return render_to_response(
|
||||
'org_useradmin.html', {
|
||||
'users': users,
|
||||
},
|
||||
context_instance=RequestContext(request))
|
||||
@ -834,13 +901,18 @@ def user_info(request, email):
|
||||
def user_remove(request, user_id):
|
||||
"""The user id is emailuser id."""
|
||||
|
||||
if not request.user.is_staff:
|
||||
if not request.user.is_staff and not request.user.org.is_staff:
|
||||
raise Http404
|
||||
|
||||
ccnetuser = get_ccnetuser(userid=int(user_id))
|
||||
if ccnetuser.org:
|
||||
ccnet_rpc.remove_org_user(ccnetuser.org.org_id, ccnetuser.username)
|
||||
ccnetuser.delete()
|
||||
|
||||
return HttpResponseRedirect(reverse('useradmin'))
|
||||
|
||||
if request.user.is_staff:
|
||||
return HttpResponseRedirect(reverse('sys_useradmin'))
|
||||
else:
|
||||
return HttpResponseRedirect(reverse('org_useradmin'))
|
||||
|
||||
@login_required
|
||||
def activate_user(request, user_id):
|
||||
@ -855,13 +927,37 @@ def activate_user(request, user_id):
|
||||
|
||||
return HttpResponseRedirect(reverse('useradmin'))
|
||||
|
||||
def send_user_add_mail(request, email, password):
|
||||
""" Send email when add new user """
|
||||
|
||||
use_https = request.is_secure()
|
||||
domain = RequestSite(request).domain
|
||||
|
||||
t = loader.get_template('user_add_email.html')
|
||||
c = {
|
||||
'user': request.user.username,
|
||||
'org': request.user.org,
|
||||
'email': email,
|
||||
'password': password,
|
||||
'domain': domain,
|
||||
'protocol': use_https and 'https' or 'http',
|
||||
}
|
||||
try:
|
||||
send_mail(u'SeaCloud注册信息', t.render(Context(c)),
|
||||
None, [email], fail_silently=False)
|
||||
messages.add_message(request, messages.INFO, email)
|
||||
except:
|
||||
messages.add_message(request, messages.ERROR, email)
|
||||
|
||||
@login_required
|
||||
def user_add(request):
|
||||
"""Add a user"""
|
||||
|
||||
if not request.user.is_staff:
|
||||
if not request.user.is_staff and not request.user.org.is_staff:
|
||||
raise Http404
|
||||
|
||||
base_template = 'org_admin_base.html' if request.user.org else 'admin_base.html'
|
||||
|
||||
if request.method == 'POST':
|
||||
form = AddUserForm(request.POST)
|
||||
if form.is_valid():
|
||||
@ -872,12 +968,24 @@ def user_add(request):
|
||||
ccnetuser.is_active = True
|
||||
ccnetuser.save()
|
||||
|
||||
return HttpResponseRedirect(reverse('useradmin', args=[]))
|
||||
if request.user.org:
|
||||
org_id = request.user.org.org_id
|
||||
ccnet_rpc.add_org_user(org_id, email, 0)
|
||||
if hasattr(settings, 'EMAIL_HOST'):
|
||||
send_user_add_mail(request, email, password)
|
||||
|
||||
return HttpResponseRedirect(reverse('org_useradmin'))
|
||||
else:
|
||||
if hasattr(settings, 'EMAIL_HOST'):
|
||||
send_user_add_mail(request, email, password)
|
||||
|
||||
return HttpResponseRedirect(reverse('sys_useradmin', args=[]))
|
||||
else:
|
||||
form = AddUserForm()
|
||||
|
||||
return render_to_response("add_user_form.html", {
|
||||
'form': form,
|
||||
'form': form,
|
||||
'base_template': base_template,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
def back_local(request):
|
||||
@ -887,7 +995,7 @@ def back_local(request):
|
||||
|
||||
return HttpResponseRedirect(redirect_url)
|
||||
|
||||
def group_admin(request):
|
||||
def sys_group_admin(request):
|
||||
if not request.user.is_staff:
|
||||
raise Http404
|
||||
|
||||
@ -898,9 +1006,10 @@ def group_admin(request):
|
||||
except ValueError:
|
||||
current_page = 1
|
||||
per_page = 25
|
||||
|
||||
|
||||
groups_plus_one = ccnet_rpc.get_all_groups(per_page * (current_page -1),
|
||||
per_page +1)
|
||||
|
||||
groups = groups_plus_one[:per_page]
|
||||
|
||||
if len(groups_plus_one) == per_page + 1:
|
||||
@ -908,11 +1017,90 @@ def group_admin(request):
|
||||
else:
|
||||
page_next = False
|
||||
|
||||
return render_to_response("group_admin.html", {
|
||||
"groups": groups,
|
||||
return render_to_response('sys_group_admin.html', {
|
||||
'groups': groups,
|
||||
'current_page': current_page,
|
||||
'prev_page': current_page-1,
|
||||
'next_page': current_page+1,
|
||||
'per_page': per_page,
|
||||
'page_next': page_next,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
def sys_org_admin(request):
|
||||
if not request.user.is_staff:
|
||||
raise Http404
|
||||
|
||||
orgs = ccnet_rpc.get_all_orgs(0, sys.maxint)
|
||||
|
||||
return render_to_response('sys_org_admin.html', {
|
||||
'orgs': orgs,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
def org_group_admin(request):
|
||||
if not request.user.is_staff and not request.user.org.is_staff:
|
||||
raise Http404
|
||||
|
||||
# Make sure page request is an int. If not, deliver first page.
|
||||
try:
|
||||
current_page = int(request.GET.get('page', '1'))
|
||||
per_page= int(request.GET.get('per_page', '25'))
|
||||
except ValueError:
|
||||
current_page = 1
|
||||
per_page = 25
|
||||
|
||||
groups_plus_one = ccnet_rpc.get_org_groups (request.user.org.org_id,
|
||||
per_page * (current_page -1),
|
||||
per_page +1)
|
||||
|
||||
groups = groups_plus_one[:per_page]
|
||||
|
||||
if len(groups_plus_one) == per_page + 1:
|
||||
page_next = True
|
||||
else:
|
||||
page_next = False
|
||||
|
||||
return render_to_response('org_group_admin.html', {
|
||||
'groups': groups,
|
||||
'current_page': current_page,
|
||||
'prev_page': current_page-1,
|
||||
'next_page': current_page+1,
|
||||
'per_page': per_page,
|
||||
'page_next': page_next,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
def org_remove(request, org_id):
|
||||
if not request.user.is_staff:
|
||||
raise Http404
|
||||
|
||||
try:
|
||||
org_id_int = int(org_id)
|
||||
except ValueError:
|
||||
return HttpResponseRedirect(reverse('sys_org_admin'))
|
||||
|
||||
# Remove repos in that org
|
||||
seafserv_threaded_rpc.remove_org_repo_by_org_id(org_id_int)
|
||||
|
||||
# TODO: Remove repos in org's groups
|
||||
|
||||
ccnet_rpc.remove_org(org_id_int)
|
||||
|
||||
return HttpResponseRedirect(reverse('sys_org_admin'))
|
||||
|
||||
@login_required
|
||||
def org_info(request):
|
||||
if not request.user.org:
|
||||
raise Http404
|
||||
|
||||
org = request.user.org
|
||||
|
||||
org_members = ccnet_rpc.get_org_emailusers(org.url_prefix, 0, sys.maxint)
|
||||
for member in org_members:
|
||||
member.short_username = member.email.split('@')[0]
|
||||
|
||||
groups = ccnet_rpc.get_org_groups(org.org_id, 0, sys.maxint)
|
||||
|
||||
return render_to_response('org_info.html', {
|
||||
'org': org,
|
||||
'org_users': org_members,
|
||||
'groups': groups,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
Loading…
Reference in New Issue
Block a user