mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-21 19:37:28 +00:00
Move system admin functions to sysadmin.py
This commit is contained in:
@@ -38,9 +38,9 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
<td>
|
<td>
|
||||||
{% if CALC_SHARE_USAGE %}
|
{% if CALC_SHARE_USAGE %}
|
||||||
{{ user.self_usage|filesizeformat }} + {{ user.share_usage|filesizeformat }} / {{ user.quota|filesizeformat }}
|
{{ user.self_usage|filesizeformat }} + {{ user.share_usage|filesizeformat }} {% if user.quota > 0 %} / {{ user.quota|filesizeformat }} {% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ user.self_usage|filesizeformat }} / {{ user.quota|filesizeformat }}
|
{{ user.self_usage|filesizeformat }} {% if user.quota > 0 %} / {{ user.quota|filesizeformat }} {% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td>{{ user.ctime|tsstr_sec }}</td>
|
<td>{{ user.ctime|tsstr_sec }}</td>
|
||||||
@@ -139,14 +139,14 @@ $('#add-user-form').submit(function() {
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
url: '{% url 'user_add' %}',
|
url: '{% url 'user_add' %}',
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
dataType: 'json',
|
datatype: 'json',
|
||||||
cache: 'false',
|
cache: 'false',
|
||||||
beforeSend: prepareCSRFToken,
|
beforeSend: prepareCSRFToken,
|
||||||
data: {
|
data: {
|
||||||
'email': email,
|
'email': email,
|
||||||
'password1': pwd1,
|
'password1': pwd1,
|
||||||
'password2': pwd2
|
'password2': pwd2
|
||||||
},
|
},
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
if (data['success']) {
|
if (data['success']) {
|
||||||
location.reload(true);
|
location.reload(true);
|
@@ -108,7 +108,7 @@ $('#set-quota-form .submit').click(function() {
|
|||||||
var self = $(this);
|
var self = $(this);
|
||||||
self.attr('disabled', 'disabled');
|
self.attr('disabled', 'disabled');
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '{% url 'views.user_info' email %}',
|
url: '{% url 'user_info' email %}',
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
cache: 'false',
|
cache: 'false',
|
@@ -12,6 +12,9 @@ from group.views import group_list
|
|||||||
from seahub.views.wiki import personal_wiki, personal_wiki_pages, \
|
from seahub.views.wiki import personal_wiki, personal_wiki_pages, \
|
||||||
personal_wiki_create, personal_wiki_page_new, personal_wiki_page_edit, \
|
personal_wiki_create, personal_wiki_page_new, personal_wiki_page_edit, \
|
||||||
personal_wiki_page_delete
|
personal_wiki_page_delete
|
||||||
|
from seahub.views.sysadmin import sys_repo_admin, sys_user_admin, sys_group_admin, \
|
||||||
|
user_info, user_add, user_remove, user_make_admin, \
|
||||||
|
user_remove_admin, user_reset, user_activate
|
||||||
|
|
||||||
# Uncomment the next two lines to enable the admin:
|
# Uncomment the next two lines to enable the admin:
|
||||||
#from django.contrib import admin
|
#from django.contrib import admin
|
||||||
@@ -88,16 +91,8 @@ urlpatterns = patterns('',
|
|||||||
(r'^download/repo/$', repo_download),
|
(r'^download/repo/$', repo_download),
|
||||||
(r'^file/move/get_subdir/$', get_subdir),
|
(r'^file/move/get_subdir/$', get_subdir),
|
||||||
(r'^file/move/$', file_move),
|
(r'^file/move/$', file_move),
|
||||||
(r'^seafile_access_check/$', seafile_access_check),
|
(r'^seafile_access_check/$', seafile_access_check),
|
||||||
url(r'^org/remove/(?P<org_id>[\d]+)/$', org_remove, name="org_remove"),
|
|
||||||
|
|
||||||
url(r'^useradmin/add/$', user_add, name="user_add"),
|
|
||||||
(r'^useradmin/remove/(?P<user_id>[^/]+)/$', user_remove),
|
|
||||||
url(r'^useradmin/makeadmin/(?P<user_id>[^/]+)/$', user_make_admin, name='user_make_admin'),
|
|
||||||
url(r'^useradmin/removeadmin/(?P<user_id>[^/]+)/$', user_remove_admin, name='user_remove_admin'),
|
|
||||||
(r'^useradmin/info/(?P<email>[^/]+)/$', user_info),
|
|
||||||
(r'^useradmin/activate/(?P<user_id>[^/]+)/$', activate_user),
|
|
||||||
url(r'^useradmin/password/reset/(?P<user_id>[^/]+)/$', user_reset, name='user_reset'),
|
|
||||||
|
|
||||||
### Apps ###
|
### Apps ###
|
||||||
(r'^api2/', include('seahub.api2.urls')),
|
(r'^api2/', include('seahub.api2.urls')),
|
||||||
@@ -110,11 +105,18 @@ urlpatterns = patterns('',
|
|||||||
(r'^share/', include('seahub.share.urls')),
|
(r'^share/', include('seahub.share.urls')),
|
||||||
|
|
||||||
### system admin ###
|
### system admin ###
|
||||||
(r'^sys/seafadmin/$', sys_seafadmin),
|
(r'^sys/seafadmin/$', sys_repo_admin),
|
||||||
url(r'^sys/useradmin/$', sys_useradmin, name='sys_useradmin'),
|
url(r'^sys/useradmin/$', sys_user_admin, name='sys_useradmin'),
|
||||||
url(r'^sys/orgadmin/$', sys_org_admin, name='sys_org_admin'),
|
|
||||||
url(r'^sys/notificationadmin/', notification_list, name='notification_list'),
|
|
||||||
url(r'^sys/groupadmin/$', sys_group_admin, name='sys_group_admin'),
|
url(r'^sys/groupadmin/$', sys_group_admin, name='sys_group_admin'),
|
||||||
|
url(r'^sys/notificationadmin/', notification_list, name='notification_list'),
|
||||||
|
url(r'^useradmin/add/$', user_add, name="user_add"),
|
||||||
|
(r'^useradmin/remove/(?P<user_id>[^/]+)/$', user_remove),
|
||||||
|
url(r'^useradmin/makeadmin/(?P<user_id>[^/]+)/$', user_make_admin, name='user_make_admin'),
|
||||||
|
url(r'^useradmin/removeadmin/(?P<user_id>[^/]+)/$', user_remove_admin, name='user_remove_admin'),
|
||||||
|
url(r'^useradmin/info/(?P<email>[^/]+)/$', user_info, name='user_info'),
|
||||||
|
(r'^useradmin/activate/(?P<user_id>[^/]+)/$', user_activate),
|
||||||
|
url(r'^useradmin/password/reset/(?P<user_id>[^/]+)/$', user_reset, name='user_reset'),
|
||||||
|
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -1295,382 +1295,6 @@ def seafile_access_check(request):
|
|||||||
},
|
},
|
||||||
context_instance=RequestContext(request))
|
context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
|
||||||
@sys_staff_required
|
|
||||||
def sys_seafadmin(request):
|
|
||||||
# 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_repo_list(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:
|
|
||||||
if is_org_repo(repo.id):
|
|
||||||
repo.owner = get_org_repo_owner(repo.id)
|
|
||||||
else:
|
|
||||||
repo.owner = get_repo_owner(repo.id)
|
|
||||||
|
|
||||||
return render_to_response(
|
|
||||||
'sys_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
|
|
||||||
@sys_staff_required
|
|
||||||
def sys_useradmin(request):
|
|
||||||
# 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
|
|
||||||
users_plus_one = get_emailusers(per_page * (current_page - 1), per_page + 1)
|
|
||||||
if len(users_plus_one) == per_page + 1:
|
|
||||||
page_next = True
|
|
||||||
else:
|
|
||||||
page_next = False
|
|
||||||
|
|
||||||
users = users_plus_one[:per_page]
|
|
||||||
for user in users:
|
|
||||||
if user.props.id == request.user.id:
|
|
||||||
user.is_self = True
|
|
||||||
try:
|
|
||||||
user.self_usage = seafile_api.get_user_self_usage(user.email)
|
|
||||||
user.share_usage = seafile_api.get_user_share_usage(user.email)
|
|
||||||
user.quota = seafile_api.get_user_quota(user.email)
|
|
||||||
except:
|
|
||||||
user.self_usage = -1
|
|
||||||
user.share_usage = -1
|
|
||||||
user.quota = -1
|
|
||||||
|
|
||||||
return render_to_response(
|
|
||||||
'sys_useradmin.html', {
|
|
||||||
'users': users,
|
|
||||||
'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
|
|
||||||
@sys_staff_required
|
|
||||||
def user_info(request, email):
|
|
||||||
if request.method == 'POST':
|
|
||||||
result = {}
|
|
||||||
content_type = 'application/json; charset=utf-8'
|
|
||||||
|
|
||||||
f = SetUserQuotaForm(request.POST)
|
|
||||||
if f.is_valid():
|
|
||||||
email = f.cleaned_data['email']
|
|
||||||
quota_mb = f.cleaned_data['quota']
|
|
||||||
quota = quota_mb * (1 << 20)
|
|
||||||
|
|
||||||
try:
|
|
||||||
seafserv_threaded_rpc.set_user_quota(email, quota)
|
|
||||||
except:
|
|
||||||
result['error'] = _(u'Failed to set quota: internal error')
|
|
||||||
return HttpResponse(json.dumps(result), content_type=content_type)
|
|
||||||
|
|
||||||
result['success'] = True
|
|
||||||
return HttpResponse(json.dumps(result), content_type=content_type)
|
|
||||||
else:
|
|
||||||
result['error'] = str(f.errors.values()[0])
|
|
||||||
return HttpResponse(json.dumps(result), content_type=content_type)
|
|
||||||
|
|
||||||
owned_repos = []
|
|
||||||
|
|
||||||
owned_repos = seafserv_threaded_rpc.list_owned_repos(email)
|
|
||||||
|
|
||||||
quota = seafserv_threaded_rpc.get_user_quota(email)
|
|
||||||
quota_usage = 0
|
|
||||||
share_usage = 0
|
|
||||||
my_usage = 0
|
|
||||||
my_usage = seafserv_threaded_rpc.get_user_quota_usage(email)
|
|
||||||
if CALC_SHARE_USAGE:
|
|
||||||
try:
|
|
||||||
share_usage = seafserv_threaded_rpc.get_user_share_usage(email)
|
|
||||||
except SearpcError, e:
|
|
||||||
share_usage = 0
|
|
||||||
quota_usage = my_usage + share_usage
|
|
||||||
else:
|
|
||||||
quota_usage = my_usage
|
|
||||||
|
|
||||||
# Repos that are share to user
|
|
||||||
in_repos = seafserv_threaded_rpc.list_share_repos(email, 'to_email',
|
|
||||||
-1, -1)
|
|
||||||
|
|
||||||
# get nickname
|
|
||||||
if not Profile.objects.filter(user=email):
|
|
||||||
nickname = ''
|
|
||||||
else:
|
|
||||||
profile = Profile.objects.filter(user=email)[0]
|
|
||||||
nickname = profile.nickname
|
|
||||||
|
|
||||||
return render_to_response(
|
|
||||||
'userinfo.html', {
|
|
||||||
'owned_repos': owned_repos,
|
|
||||||
'quota': quota,
|
|
||||||
'quota_usage': quota_usage,
|
|
||||||
'CALC_SHARE_USAGE': CALC_SHARE_USAGE,
|
|
||||||
'share_usage': share_usage,
|
|
||||||
'my_usage': my_usage,
|
|
||||||
'in_repos': in_repos,
|
|
||||||
'email': email,
|
|
||||||
'nickname': nickname,
|
|
||||||
}, context_instance=RequestContext(request))
|
|
||||||
|
|
||||||
@login_required
|
|
||||||
@sys_staff_required
|
|
||||||
def user_remove(request, user_id):
|
|
||||||
"""Remove user, also remove group relationship."""
|
|
||||||
try:
|
|
||||||
user = User.objects.get(id=int(user_id))
|
|
||||||
user.delete()
|
|
||||||
messages.success(request, _(u'Successfully deleted %s') % user.username)
|
|
||||||
except User.DoesNotExist:
|
|
||||||
messages.error(request, _(u'Failed to delete: the user does not exist'))
|
|
||||||
|
|
||||||
return HttpResponseRedirect(request.META["HTTP_REFERER"])
|
|
||||||
|
|
||||||
@login_required
|
|
||||||
@sys_staff_required
|
|
||||||
def user_make_admin(request, user_id):
|
|
||||||
"""Set user as system admin."""
|
|
||||||
try:
|
|
||||||
user = User.objects.get(id=int(user_id))
|
|
||||||
user.is_staff = True
|
|
||||||
user.save()
|
|
||||||
messages.success(request, _(u'Successfully set %s as admin') % user.username)
|
|
||||||
except User.DoesNotExist:
|
|
||||||
messages.error(request, _(u'Failed to set admin: the user does not exist'))
|
|
||||||
|
|
||||||
return HttpResponseRedirect(request.META["HTTP_REFERER"])
|
|
||||||
|
|
||||||
@login_required
|
|
||||||
@sys_staff_required
|
|
||||||
def user_remove_admin(request, user_id):
|
|
||||||
"""Unset user admin."""
|
|
||||||
try:
|
|
||||||
user = User.objects.get(id=int(user_id))
|
|
||||||
user.is_staff = False
|
|
||||||
user.save()
|
|
||||||
messages.success(request, _(u'Successfully revoke the admin permission of %s') % user.username)
|
|
||||||
except User.DoesNotExist:
|
|
||||||
messages.error(request, _(u'Failed to revoke admin: the user does not exist'))
|
|
||||||
|
|
||||||
return HttpResponseRedirect(request.META["HTTP_REFERER"])
|
|
||||||
|
|
||||||
@login_required
|
|
||||||
@sys_staff_required
|
|
||||||
def activate_user(request, user_id):
|
|
||||||
try:
|
|
||||||
user = User.objects.get(id=int(user_id))
|
|
||||||
user.is_active = True
|
|
||||||
user.save()
|
|
||||||
except User.DoesNotExist:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return HttpResponseRedirect(reverse('sys_useradmin'))
|
|
||||||
|
|
||||||
def send_user_reset_email(request, email, password):
|
|
||||||
"""
|
|
||||||
Send email when reset user password.
|
|
||||||
"""
|
|
||||||
use_https = request.is_secure()
|
|
||||||
domain = RequestSite(request).domain
|
|
||||||
|
|
||||||
t = loader.get_template('user_reset_email.html')
|
|
||||||
c = {
|
|
||||||
'email': email,
|
|
||||||
'password': password,
|
|
||||||
'site_name': settings.SITE_NAME,
|
|
||||||
}
|
|
||||||
send_mail(_(u'Password Reset'), t.render(Context(c)),
|
|
||||||
None, [email], fail_silently=False)
|
|
||||||
|
|
||||||
@login_required
|
|
||||||
@sys_staff_required
|
|
||||||
def user_reset(request, user_id):
|
|
||||||
"""Reset password for user."""
|
|
||||||
try:
|
|
||||||
user = User.objects.get(id=int(user_id))
|
|
||||||
if isinstance(INIT_PASSWD, FunctionType):
|
|
||||||
new_password = INIT_PASSWD()
|
|
||||||
else:
|
|
||||||
new_password = INIT_PASSWD
|
|
||||||
user.set_password(new_password)
|
|
||||||
user.save()
|
|
||||||
|
|
||||||
if IS_EMAIL_CONFIGURED:
|
|
||||||
if SEND_EMAIL_ON_RESETTING_USER_PASSWD:
|
|
||||||
try:
|
|
||||||
send_user_reset_email(request, user.email, new_password)
|
|
||||||
msg = _('Successfully resetted password to %(passwd)s, an email has been sent to %(user)s.') % \
|
|
||||||
{'passwd': new_password, 'user': user.email}
|
|
||||||
messages.success(request, msg)
|
|
||||||
except Exception, e:
|
|
||||||
logger.error(str(e))
|
|
||||||
msg = _('Successfully resetted password to %(passwd)s, but failed to send email to %(user)s, please check your email configuration.') % \
|
|
||||||
{'passwd':new_password, 'user': user.email}
|
|
||||||
messages.success(request, msg)
|
|
||||||
else:
|
|
||||||
messages.success(request, _(u'Successfully resetted password to %(passwd)s for user %(user)s.') % \
|
|
||||||
{'passwd':new_password,'user': user.email})
|
|
||||||
else:
|
|
||||||
messages.success(request, _(u'Successfully resetted password to %(passwd)s for user %(user)s. But email notification can not be sent, because Email service is not properly configured.') % \
|
|
||||||
{'passwd':new_password,'user': user.email})
|
|
||||||
except User.DoesNotExist:
|
|
||||||
msg = _(u'Failed to reset password: user does not exist')
|
|
||||||
messages.error(request, msg)
|
|
||||||
|
|
||||||
return HttpResponseRedirect(reverse('sys_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',
|
|
||||||
'site_name': settings.SITE_NAME,
|
|
||||||
}
|
|
||||||
send_mail(_(u'Seafile Registration Information'), t.render(Context(c)),
|
|
||||||
None, [email], fail_silently=False)
|
|
||||||
|
|
||||||
@login_required
|
|
||||||
def user_add(request):
|
|
||||||
"""Add a user"""
|
|
||||||
|
|
||||||
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'
|
|
||||||
|
|
||||||
content_type = 'application/json; charset=utf-8'
|
|
||||||
if request.method == 'POST':
|
|
||||||
form = AddUserForm(request.POST)
|
|
||||||
if form.is_valid():
|
|
||||||
email = form.cleaned_data['email']
|
|
||||||
password = form.cleaned_data['password1']
|
|
||||||
|
|
||||||
user = User.objects.create_user(email, password, is_staff=False,
|
|
||||||
is_active=True)
|
|
||||||
|
|
||||||
if request.user.org:
|
|
||||||
org_id = request.user.org['org_id']
|
|
||||||
url_prefix = request.user.org['url_prefix']
|
|
||||||
ccnet_threaded_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',
|
|
||||||
args=[url_prefix]))
|
|
||||||
else:
|
|
||||||
if IS_EMAIL_CONFIGURED:
|
|
||||||
if SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER:
|
|
||||||
try:
|
|
||||||
send_user_add_mail(request, email, password)
|
|
||||||
messages.success(request, _(u'Successfully added user %s. An email notification has been sent.') % email)
|
|
||||||
except Exception, e:
|
|
||||||
logger.error(str(e))
|
|
||||||
messages.success(request, _(u'Successfully added user %s. An error accurs when sending email notification, please check your email configuration.') % email)
|
|
||||||
else:
|
|
||||||
messages.success(request, _(u'Successfully added user %s.') % email)
|
|
||||||
else:
|
|
||||||
messages.success(request, _(u'Successfully added user %s. But email notification can not be sent, because Email service is not properly configured.') % email)
|
|
||||||
|
|
||||||
return HttpResponse(json.dumps({'success': True}), content_type=content_type)
|
|
||||||
else:
|
|
||||||
return HttpResponse(json.dumps({'err': str(form.errors)}), status=400, content_type=content_type)
|
|
||||||
|
|
||||||
@login_required
|
|
||||||
@sys_staff_required
|
|
||||||
def sys_group_admin(request):
|
|
||||||
# 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_threaded_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:
|
|
||||||
page_next = True
|
|
||||||
else:
|
|
||||||
page_next = False
|
|
||||||
|
|
||||||
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))
|
|
||||||
|
|
||||||
@login_required
|
|
||||||
@sys_staff_required
|
|
||||||
def sys_org_admin(request):
|
|
||||||
try:
|
|
||||||
orgs = ccnet_threaded_rpc.get_all_orgs(0, MAX_INT)
|
|
||||||
except:
|
|
||||||
orgs = []
|
|
||||||
|
|
||||||
return render_to_response('sys_org_admin.html', {
|
|
||||||
'orgs': orgs,
|
|
||||||
}, context_instance=RequestContext(request))
|
|
||||||
|
|
||||||
@login_required
|
|
||||||
@sys_staff_required
|
|
||||||
def org_remove(request, org_id):
|
|
||||||
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_threaded_rpc.remove_org(org_id_int)
|
|
||||||
|
|
||||||
return HttpResponseRedirect(reverse('sys_org_admin'))
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def file_upload_progress_page(request):
|
def file_upload_progress_page(request):
|
||||||
|
382
seahub/views/sysadmin.py
Normal file
382
seahub/views/sysadmin.py
Normal file
@@ -0,0 +1,382 @@
|
|||||||
|
# encoding: utf-8
|
||||||
|
|
||||||
|
from types import FunctionType
|
||||||
|
import logging
|
||||||
|
import simplejson as json
|
||||||
|
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
from django.core.mail import send_mail
|
||||||
|
from django.contrib import messages
|
||||||
|
from django.http import HttpResponse, HttpResponseBadRequest, Http404, \
|
||||||
|
HttpResponseRedirect
|
||||||
|
from django.shortcuts import render_to_response, redirect
|
||||||
|
from django.template import Context, loader, RequestContext
|
||||||
|
from django.template.loader import render_to_string
|
||||||
|
from django.utils.translation import ugettext as _
|
||||||
|
from django.contrib.sites.models import Site, RequestSite
|
||||||
|
from django.core.mail import send_mail
|
||||||
|
|
||||||
|
|
||||||
|
import seaserv
|
||||||
|
from seaserv import ccnet_rpc, ccnet_threaded_rpc, get_emailusers, \
|
||||||
|
MAX_DOWNLOAD_DIR_SIZE, CALC_SHARE_USAGE, \
|
||||||
|
send_message
|
||||||
|
from seaserv import seafile_api
|
||||||
|
from pysearpc import SearpcError
|
||||||
|
|
||||||
|
from seahub.base.accounts import User
|
||||||
|
from seahub.base.decorators import sys_staff_required
|
||||||
|
from seahub.auth.decorators import login_required
|
||||||
|
from seahub.utils import IS_EMAIL_CONFIGURED
|
||||||
|
from seahub.forms import SetUserQuotaForm, AddUserForm
|
||||||
|
from seahub.profile.models import Profile
|
||||||
|
|
||||||
|
import seahub.settings as settings
|
||||||
|
from seahub.settings import INIT_PASSWD, \
|
||||||
|
SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER, SEND_EMAIL_ON_RESETTING_USER_PASSWD
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@sys_staff_required
|
||||||
|
def sys_repo_admin(request):
|
||||||
|
# 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 = seafile_api.get_repo_list(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 = seafile_api.get_repo_owner(repo.id)
|
||||||
|
except:
|
||||||
|
repo.owner = "failed to get"
|
||||||
|
|
||||||
|
return render_to_response(
|
||||||
|
'sysadmin/sys_repo_admin.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
|
||||||
|
@sys_staff_required
|
||||||
|
def sys_user_admin(request):
|
||||||
|
# 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
|
||||||
|
users_plus_one = get_emailusers(per_page * (current_page - 1), per_page + 1)
|
||||||
|
if len(users_plus_one) == per_page + 1:
|
||||||
|
page_next = True
|
||||||
|
else:
|
||||||
|
page_next = False
|
||||||
|
|
||||||
|
users = users_plus_one[:per_page]
|
||||||
|
for user in users:
|
||||||
|
if user.props.id == request.user.id:
|
||||||
|
user.is_self = True
|
||||||
|
try:
|
||||||
|
user.self_usage = seafile_api.get_user_self_usage(user.email)
|
||||||
|
user.share_usage = seafile_api.get_user_share_usage(user.email)
|
||||||
|
user.quota = seafile_api.get_user_quota(user.email)
|
||||||
|
except:
|
||||||
|
user.self_usage = -1
|
||||||
|
user.share_usage = -1
|
||||||
|
user.quota = -1
|
||||||
|
|
||||||
|
return render_to_response(
|
||||||
|
'sysadmin/sys_useradmin.html', {
|
||||||
|
'users': users,
|
||||||
|
'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
|
||||||
|
@sys_staff_required
|
||||||
|
def user_info(request, email):
|
||||||
|
if request.method == 'POST':
|
||||||
|
result = {}
|
||||||
|
content_type = 'application/json; charset=utf-8'
|
||||||
|
|
||||||
|
f = SetUserQuotaForm(request.POST)
|
||||||
|
if f.is_valid():
|
||||||
|
email = f.cleaned_data['email']
|
||||||
|
quota_mb = f.cleaned_data['quota']
|
||||||
|
quota = quota_mb * (1 << 20)
|
||||||
|
|
||||||
|
try:
|
||||||
|
seafile_api.set_user_quota(email, quota)
|
||||||
|
except:
|
||||||
|
result['error'] = _(u'Failed to set quota: internal error')
|
||||||
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
||||||
|
|
||||||
|
result['success'] = True
|
||||||
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
||||||
|
else:
|
||||||
|
result['error'] = str(f.errors.values()[0])
|
||||||
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
||||||
|
|
||||||
|
owned_repos = []
|
||||||
|
|
||||||
|
owned_repos = seafile_api.get_owned_repo_list(email)
|
||||||
|
|
||||||
|
quota = seafile_api.get_user_quota(email)
|
||||||
|
quota_usage = 0
|
||||||
|
share_usage = 0
|
||||||
|
my_usage = 0
|
||||||
|
my_usage = seafile_api.get_user_self_usage(email)
|
||||||
|
if CALC_SHARE_USAGE:
|
||||||
|
try:
|
||||||
|
share_usage = seafile_api.get_user_share_usage(email)
|
||||||
|
except SearpcError, e:
|
||||||
|
share_usage = 0
|
||||||
|
quota_usage = my_usage + share_usage
|
||||||
|
else:
|
||||||
|
quota_usage = my_usage
|
||||||
|
|
||||||
|
# Repos that are share to user
|
||||||
|
in_repos = seafile_api.get_share_in_repo_list(email, -1, -1)
|
||||||
|
|
||||||
|
# get nickname
|
||||||
|
if not Profile.objects.filter(user=email):
|
||||||
|
nickname = ''
|
||||||
|
else:
|
||||||
|
profile = Profile.objects.filter(user=email)[0]
|
||||||
|
nickname = profile.nickname
|
||||||
|
|
||||||
|
return render_to_response(
|
||||||
|
'sysadmin/userinfo.html', {
|
||||||
|
'owned_repos': owned_repos,
|
||||||
|
'quota': quota,
|
||||||
|
'quota_usage': quota_usage,
|
||||||
|
'CALC_SHARE_USAGE': CALC_SHARE_USAGE,
|
||||||
|
'share_usage': share_usage,
|
||||||
|
'my_usage': my_usage,
|
||||||
|
'in_repos': in_repos,
|
||||||
|
'email': email,
|
||||||
|
'nickname': nickname,
|
||||||
|
}, context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@sys_staff_required
|
||||||
|
def user_remove(request, user_id):
|
||||||
|
"""Remove user, also remove group relationship."""
|
||||||
|
try:
|
||||||
|
user = User.objects.get(id=int(user_id))
|
||||||
|
user.delete()
|
||||||
|
messages.success(request, _(u'Successfully deleted %s') % user.username)
|
||||||
|
except User.DoesNotExist:
|
||||||
|
messages.error(request, _(u'Failed to delete: the user does not exist'))
|
||||||
|
|
||||||
|
return HttpResponseRedirect(request.META["HTTP_REFERER"])
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@sys_staff_required
|
||||||
|
def user_make_admin(request, user_id):
|
||||||
|
"""Set user as system admin."""
|
||||||
|
try:
|
||||||
|
user = User.objects.get(id=int(user_id))
|
||||||
|
user.is_staff = True
|
||||||
|
user.save()
|
||||||
|
messages.success(request, _(u'Successfully set %s as admin') % user.username)
|
||||||
|
except User.DoesNotExist:
|
||||||
|
messages.error(request, _(u'Failed to set admin: the user does not exist'))
|
||||||
|
|
||||||
|
return HttpResponseRedirect(request.META["HTTP_REFERER"])
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@sys_staff_required
|
||||||
|
def user_remove_admin(request, user_id):
|
||||||
|
"""Unset user admin."""
|
||||||
|
try:
|
||||||
|
user = User.objects.get(id=int(user_id))
|
||||||
|
user.is_staff = False
|
||||||
|
user.save()
|
||||||
|
messages.success(request, _(u'Successfully revoke the admin permission of %s') % user.username)
|
||||||
|
except User.DoesNotExist:
|
||||||
|
messages.error(request, _(u'Failed to revoke admin: the user does not exist'))
|
||||||
|
|
||||||
|
return HttpResponseRedirect(request.META["HTTP_REFERER"])
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@sys_staff_required
|
||||||
|
def user_activate(request, user_id):
|
||||||
|
try:
|
||||||
|
user = User.objects.get(id=int(user_id))
|
||||||
|
user.is_active = True
|
||||||
|
user.save()
|
||||||
|
except User.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return HttpResponseRedirect(reverse('sys_useradmin'))
|
||||||
|
|
||||||
|
def send_user_reset_email(request, email, password):
|
||||||
|
"""
|
||||||
|
Send email when reset user password.
|
||||||
|
"""
|
||||||
|
use_https = request.is_secure()
|
||||||
|
domain = RequestSite(request).domain
|
||||||
|
|
||||||
|
t = loader.get_template('sysadmin/user_reset_email.html')
|
||||||
|
c = {
|
||||||
|
'email': email,
|
||||||
|
'password': password,
|
||||||
|
'site_name': settings.SITE_NAME,
|
||||||
|
}
|
||||||
|
send_mail(_(u'Password Reset'), t.render(Context(c)),
|
||||||
|
None, [email], fail_silently=False)
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@sys_staff_required
|
||||||
|
def user_reset(request, user_id):
|
||||||
|
"""Reset password for user."""
|
||||||
|
try:
|
||||||
|
user = User.objects.get(id=int(user_id))
|
||||||
|
if isinstance(INIT_PASSWD, FunctionType):
|
||||||
|
new_password = INIT_PASSWD()
|
||||||
|
else:
|
||||||
|
new_password = INIT_PASSWD
|
||||||
|
user.set_password(new_password)
|
||||||
|
user.save()
|
||||||
|
|
||||||
|
if IS_EMAIL_CONFIGURED:
|
||||||
|
if SEND_EMAIL_ON_RESETTING_USER_PASSWD:
|
||||||
|
try:
|
||||||
|
send_user_reset_email(request, user.email, new_password)
|
||||||
|
msg = _('Successfully reset password to %(passwd)s, an email has been sent to %(user)s.') % \
|
||||||
|
{'passwd': new_password, 'user': user.email}
|
||||||
|
messages.success(request, msg)
|
||||||
|
except Exception, e:
|
||||||
|
logger.error(str(e))
|
||||||
|
msg = _('Successfully reset password to %(passwd)s, but failed to send email to %(user)s, please check your email configuration.') % \
|
||||||
|
{'passwd':new_password, 'user': user.email}
|
||||||
|
messages.success(request, msg)
|
||||||
|
else:
|
||||||
|
messages.success(request, _(u'Successfully reset password to %(passwd)s for user %(user)s.') % \
|
||||||
|
{'passwd':new_password,'user': user.email})
|
||||||
|
else:
|
||||||
|
messages.success(request, _(u'Successfully reset password to %(passwd)s for user %(user)s. But email notification can not be sent, because Email service is not properly configured.') % \
|
||||||
|
{'passwd':new_password,'user': user.email})
|
||||||
|
except User.DoesNotExist:
|
||||||
|
msg = _(u'Failed to reset password: user does not exist')
|
||||||
|
messages.error(request, msg)
|
||||||
|
|
||||||
|
return HttpResponseRedirect(reverse('sys_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('sysadmin/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',
|
||||||
|
'site_name': settings.SITE_NAME,
|
||||||
|
}
|
||||||
|
send_mail(_(u'Seafile Registration Information'), t.render(Context(c)),
|
||||||
|
None, [email], fail_silently=False)
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def user_add(request):
|
||||||
|
"""Add a user"""
|
||||||
|
|
||||||
|
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'
|
||||||
|
|
||||||
|
content_type = 'application/json; charset=utf-8'
|
||||||
|
if request.method == 'POST':
|
||||||
|
form = AddUserForm(request.POST)
|
||||||
|
if form.is_valid():
|
||||||
|
email = form.cleaned_data['email']
|
||||||
|
password = form.cleaned_data['password1']
|
||||||
|
|
||||||
|
user = User.objects.create_user(email, password, is_staff=False,
|
||||||
|
is_active=True)
|
||||||
|
if request.user.org:
|
||||||
|
org_id = request.user.org['org_id']
|
||||||
|
url_prefix = request.user.org['url_prefix']
|
||||||
|
ccnet_threaded_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',
|
||||||
|
args=[url_prefix]))
|
||||||
|
else:
|
||||||
|
if IS_EMAIL_CONFIGURED:
|
||||||
|
if SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER:
|
||||||
|
try:
|
||||||
|
send_user_add_mail(request, email, password)
|
||||||
|
messages.success(request, _(u'Successfully added user %s. An email notification has been sent.') % email)
|
||||||
|
except Exception, e:
|
||||||
|
logger.error(str(e))
|
||||||
|
messages.success(request, _(u'Successfully added user %s. An error accurs when sending email notification, please check your email configuration.') % email)
|
||||||
|
else:
|
||||||
|
messages.success(request, _(u'Successfully added user %s.') % email)
|
||||||
|
else:
|
||||||
|
messages.success(request, _(u'Successfully added user %s. But email notification can not be sent, because Email service is not properly configured.') % email)
|
||||||
|
|
||||||
|
return HttpResponse(json.dumps({'success': True}), content_type=content_type)
|
||||||
|
else:
|
||||||
|
return HttpResponse(json.dumps({'err': str(form.errors)}), status=400, content_type=content_type)
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@sys_staff_required
|
||||||
|
def sys_group_admin(request):
|
||||||
|
# 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_threaded_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:
|
||||||
|
page_next = True
|
||||||
|
else:
|
||||||
|
page_next = False
|
||||||
|
|
||||||
|
return render_to_response('sysadmin/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))
|
||||||
|
|
Reference in New Issue
Block a user