2016-07-26 10:47:45 +08:00
# Copyright (c) 2012-2016 Seafile Ltd.
2013-05-17 13:41:37 +08:00
# encoding: utf-8
2013-05-25 11:40:40 +08:00
import os
2013-05-17 13:41:37 +08:00
from types import FunctionType
import logging
2014-07-09 14:00:39 +02:00
import json
2014-02-26 18:24:34 +08:00
import re
import datetime
2014-05-09 17:12:25 +08:00
import csv , chardet , StringIO
2015-10-24 15:53:02 +08:00
import time
2015-09-21 11:48:07 +08:00
from constance import config
2013-05-17 13:41:37 +08:00
2016-07-13 11:22:36 +08:00
from django . db . models import Q
2016-05-26 15:55:57 +08:00
from django . conf import settings as dj_settings
2013-05-17 13:41:37 +08:00
from django . core . urlresolvers import reverse
from django . contrib import messages
2015-05-04 13:57:10 +08:00
from django . http import HttpResponse , Http404 , HttpResponseRedirect , HttpResponseNotAllowed
2013-07-30 11:35:02 +08:00
from django . shortcuts import render_to_response
2014-02-28 17:09:01 +08:00
from django . template import RequestContext
2015-09-15 17:32:09 +08:00
from django . utils import timezone
2013-05-17 13:41:37 +08:00
from django . utils . translation import ugettext as _
2015-10-24 17:18:07 +08:00
import seaserv
from seaserv import ccnet_threaded_rpc , seafserv_threaded_rpc , \
2016-06-24 11:10:26 +08:00
seafile_api , get_group , get_group_members , ccnet_api
2013-05-17 13:41:37 +08:00
from pysearpc import SearpcError
from seahub . base . accounts import User
2013-11-21 15:05:08 +08:00
from seahub . base . models import UserLastLogin
2015-09-02 11:14:54 +08:00
from seahub . base . decorators import sys_staff_required , require_POST
2015-05-04 13:57:10 +08:00
from seahub . base . sudo_mode import update_sudo_mode_ts
2016-05-03 13:44:43 +08:00
from seahub . base . templatetags . seahub_tags import tsstr_sec , email2nickname
2015-05-04 13:57:10 +08:00
from seahub . auth import authenticate
2014-07-01 15:21:49 +08:00
from seahub . auth . decorators import login_required , login_required_ajax
2014-07-14 17:48:05 +08:00
from seahub . constants import GUEST_USER , DEFAULT_USER
2016-03-13 09:42:40 +08:00
from seahub . institutions . models import Institution , InstitutionAdmin
2016-05-13 15:34:49 +08:00
from seahub . invitations . models import Invitation
2016-05-20 15:14:06 +08:00
from seahub . role_permissions . utils import get_available_roles
2014-12-25 14:48:02 +08:00
from seahub . utils import IS_EMAIL_CONFIGURED , string2list , is_valid_username , \
2015-09-21 11:48:07 +08:00
is_pro_version , send_html_email , get_user_traffic_list , get_server_id , \
2016-07-20 15:30:39 +08:00
clear_token , handle_virus_record , get_virus_record_by_id , \
get_virus_record , FILE_AUDIT_ENABLED , get_max_upload_file_size
2016-02-23 17:20:02 +08:00
from seahub . utils . file_size import get_file_size_unit
2015-09-21 11:48:07 +08:00
from seahub . utils . rpc import mute_seafile_api
2016-11-05 12:09:58 +08:00
from seahub . utils . licenseparse import parse_license , user_number_over_limit
2015-09-21 11:48:07 +08:00
from seahub . utils . sysinfo import get_platform_name
2015-11-26 17:24:50 +08:00
from seahub . utils . mail import send_html_email_with_dj_template
2015-11-17 15:54:37 +08:00
from seahub . utils . ms_excel import write_xls
2016-05-20 15:14:06 +08:00
from seahub . utils . user_permissions import ( get_basic_user_roles ,
get_user_role )
2016-07-28 15:54:56 +08:00
from seahub . views import get_system_default_repo_id
2015-09-25 16:03:51 +08:00
from seahub . views . ajax import ( get_related_users_by_org_repo ,
get_related_users_by_repo )
2016-07-18 13:04:05 +08:00
from seahub . forms import SetUserQuotaForm , AddUserForm , BatchAddUserForm , \
TermsAndConditionsForm
2016-12-21 11:41:32 +08:00
from seahub . profile . forms import ProfileForm , DetailedProfileForm
2015-11-23 17:55:42 +08:00
from seahub . options . models import UserOptions
2013-12-18 13:56:20 +08:00
from seahub . profile . models import Profile , DetailedProfile
2015-09-25 16:03:51 +08:00
from seahub . signals import repo_deleted
2014-04-29 11:05:36 +08:00
from seahub . share . models import FileShare , UploadLinkShare
2013-05-17 13:41:37 +08:00
import seahub . settings as settings
2015-11-17 15:54:37 +08:00
from seahub . settings import INIT_PASSWD , SITE_NAME , SITE_ROOT , \
2015-10-20 16:35:54 +08:00
SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER , SEND_EMAIL_ON_RESETTING_USER_PASSWD , \
2016-07-20 15:30:39 +08:00
ENABLE_SYS_ADMIN_VIEW_REPO , ENABLE_GUEST_INVITATION
2015-01-08 16:23:18 +08:00
try :
2015-01-16 10:48:47 +08:00
from seahub . settings import ENABLE_TRIAL_ACCOUNT
2015-01-08 16:23:18 +08:00
except :
2015-01-16 10:48:47 +08:00
ENABLE_TRIAL_ACCOUNT = False
if ENABLE_TRIAL_ACCOUNT :
from seahub_extra . trialaccount . models import TrialAccount
2015-05-08 15:21:54 +08:00
try :
from seahub . settings import MULTI_TENANCY
except ImportError :
MULTI_TENANCY = False
2016-04-15 09:08:22 +08:00
from seahub . utils . two_factor_auth import HAS_TWO_FACTOR_AUTH
2016-07-18 13:04:05 +08:00
from termsandconditions . models import TermsAndConditions
2014-12-04 10:47:22 +08:00
2013-05-17 13:41:37 +08:00
logger = logging . getLogger ( __name__ )
2016-03-16 13:30:00 +08:00
@login_required
@sys_staff_required
def sysadmin ( request ) :
max_upload_file_size = get_max_upload_file_size ( )
folder_perm_enabled = True if is_pro_version ( ) and settings . ENABLE_FOLDER_PERM else False
return render_to_response ( ' sysadmin/sysadmin_backbone.html ' , {
2016-05-25 10:45:22 +08:00
' enable_sys_admin_view_repo ' : ENABLE_SYS_ADMIN_VIEW_REPO ,
2016-03-16 13:30:00 +08:00
' enable_upload_folder ' : settings . ENABLE_UPLOAD_FOLDER ,
' enable_resumable_fileupload ' : settings . ENABLE_RESUMABLE_FILEUPLOAD ,
2016-09-14 17:35:42 +08:00
' max_number_of_files_for_fileupload ' : settings . MAX_NUMBER_OF_FILES_FOR_FILEUPLOAD ,
2016-03-16 13:30:00 +08:00
' enable_thumbnail ' : settings . ENABLE_THUMBNAIL ,
' thumbnail_default_size ' : settings . THUMBNAIL_DEFAULT_SIZE ,
' thumbnail_size_for_grid ' : settings . THUMBNAIL_SIZE_FOR_GRID ,
' enable_encrypted_library ' : config . ENABLE_ENCRYPTED_LIBRARY ,
' enable_repo_history_setting ' : config . ENABLE_REPO_HISTORY_SETTING ,
' max_upload_file_size ' : max_upload_file_size ,
' folder_perm_enabled ' : folder_perm_enabled ,
' is_pro ' : True if is_pro_version ( ) else False ,
' file_audit_enabled ' : FILE_AUDIT_ENABLED
} , context_instance = RequestContext ( request ) )
2016-02-29 17:20:32 +08:00
def can_view_sys_admin_repo ( repo ) :
default_repo_id = get_system_default_repo_id ( )
is_default_repo = True if repo . id == default_repo_id else False
if is_default_repo :
return True
elif repo . encrypted :
return False
elif is_pro_version ( ) and ENABLE_SYS_ADMIN_VIEW_REPO :
return True
else :
return False
2016-08-08 18:19:00 +08:00
def populate_user_info ( user ) :
2016-08-09 11:17:38 +08:00
""" Populate contact email and name to user.
2016-08-08 18:19:00 +08:00
"""
user_profile = Profile . objects . get_profile_by_user ( user . email )
if user_profile :
user . contact_email = user_profile . contact_email
user . name = user_profile . nickname
else :
user . contact_email = ' '
user . name = ' '
2014-12-24 17:35:15 +08:00
def _populate_user_quota_usage ( user ) :
""" Populate space/share quota to user.
Arguments :
- ` user ` :
"""
orgs = ccnet_threaded_rpc . get_orgs_by_user ( user . email )
try :
if orgs :
user . org = orgs [ 0 ]
org_id = user . org . org_id
user . space_usage = seafserv_threaded_rpc . get_org_user_quota_usage ( org_id , user . email )
user . space_quota = seafserv_threaded_rpc . get_org_user_quota ( org_id , user . email )
else :
user . space_usage = seafile_api . get_user_self_usage ( user . email )
user . space_quota = seafile_api . get_user_quota ( user . email )
except SearpcError as e :
logger . error ( e )
2016-02-24 14:20:28 +08:00
user . space_usage = - 1
user . space_quota = - 1
2014-12-24 17:35:15 +08:00
2013-05-17 13:41:37 +08:00
@login_required
@sys_staff_required
def sys_user_admin ( request ) :
2013-11-21 11:47:53 +08:00
""" List all users from database.
"""
2015-09-16 18:40:14 +08:00
try :
from seahub_extra . plan . models import UserPlan
enable_user_plan = True
except ImportError :
enable_user_plan = False
if enable_user_plan and request . GET . get ( ' filter ' , ' ' ) == ' paid ' :
# show paid users
users = [ ]
ups = UserPlan . objects . all ( )
for up in ups :
2015-09-21 12:05:06 +08:00
try :
u = User . objects . get ( up . username )
except User . DoesNotExist :
continue
2015-09-16 18:40:14 +08:00
_populate_user_quota_usage ( u )
users . append ( u )
last_logins = UserLastLogin . objects . filter ( username__in = [ x . username for x in users ] )
for u in users :
for e in last_logins :
if e . username == u . username :
u . last_login = e . last_login
return render_to_response ( ' sysadmin/sys_useradmin_paid.html ' , {
' users ' : users ,
' enable_user_plan ' : enable_user_plan ,
} , context_instance = RequestContext ( request ) )
### List all users
2013-05-17 13:41:37 +08:00
# Make sure page request is an int. If not, deliver first page.
try :
current_page = int ( request . GET . get ( ' page ' , ' 1 ' ) )
2013-07-30 11:35:02 +08:00
per_page = int ( request . GET . get ( ' per_page ' , ' 25 ' ) )
2013-05-17 13:41:37 +08:00
except ValueError :
current_page = 1
per_page = 25
2015-10-24 17:18:07 +08:00
users_plus_one = seaserv . get_emailusers ( ' DB ' , per_page * ( current_page - 1 ) ,
per_page + 1 )
2013-05-17 13:41:37 +08:00
if len ( users_plus_one ) == per_page + 1 :
page_next = True
else :
page_next = False
users = users_plus_one [ : per_page ]
2013-11-21 15:05:08 +08:00
last_logins = UserLastLogin . objects . filter ( username__in = [ x . email for x in users ] )
2015-01-16 10:48:47 +08:00
if ENABLE_TRIAL_ACCOUNT :
2015-01-10 12:07:33 +08:00
trial_users = TrialAccount . objects . filter ( user_or_org__in = [ x . email for x in users ] )
2015-01-08 16:23:18 +08:00
else :
trial_users = [ ]
2016-11-01 11:45:32 +08:00
2013-05-17 13:41:37 +08:00
for user in users :
2015-06-26 14:05:39 +08:00
if user . email == request . user . email :
2013-05-17 13:41:37 +08:00
user . is_self = True
2014-10-10 18:42:06 +08:00
2016-08-08 18:19:00 +08:00
populate_user_info ( user )
2014-12-24 17:35:15 +08:00
_populate_user_quota_usage ( user )
2014-10-10 18:42:06 +08:00
2014-07-14 17:48:05 +08:00
# check user's role
2016-05-20 15:14:06 +08:00
user . is_guest = True if get_user_role ( user ) == GUEST_USER else False
user . is_default = True if get_user_role ( user ) == DEFAULT_USER else False
2015-01-08 16:23:18 +08:00
2013-11-21 15:05:08 +08:00
# populate user last login time
user . last_login = None
for last_login in last_logins :
if last_login . username == user . email :
user . last_login = last_login . last_login
2013-11-21 11:47:53 +08:00
2015-01-08 16:23:18 +08:00
user . trial_info = None
for trial_user in trial_users :
2015-01-10 12:07:33 +08:00
if trial_user . user_or_org == user . email :
2015-01-08 16:23:18 +08:00
user . trial_info = { ' expire_date ' : trial_user . expire_date }
2015-10-24 17:18:07 +08:00
have_ldap = True if len ( seaserv . get_emailusers ( ' LDAP ' , 0 , 1 ) ) > 0 else False
2013-11-21 11:47:53 +08:00
2014-04-17 18:33:12 +08:00
platform = get_platform_name ( )
2014-04-18 12:13:43 +08:00
server_id = get_server_id ( )
2014-12-25 14:48:02 +08:00
pro_server = 1 if is_pro_version ( ) else 0
2016-05-20 15:14:06 +08:00
extra_user_roles = [ x for x in get_available_roles ( )
if x not in get_basic_user_roles ( ) ]
2014-04-17 18:33:12 +08:00
2013-05-17 13:41:37 +08:00
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 ,
2013-11-21 11:47:53 +08:00
' have_ldap ' : have_ldap ,
2014-04-17 18:33:12 +08:00
' platform ' : platform ,
2014-04-18 14:19:58 +08:00
' server_id ' : server_id [ : 8 ] ,
2014-07-14 17:48:05 +08:00
' default_user ' : DEFAULT_USER ,
' guest_user ' : GUEST_USER ,
2015-06-24 15:08:04 +08:00
' is_pro ' : is_pro_version ( ) ,
2014-12-25 14:48:02 +08:00
' pro_server ' : pro_server ,
2015-09-16 18:40:14 +08:00
' enable_user_plan ' : enable_user_plan ,
2016-05-20 15:14:06 +08:00
' extra_user_roles ' : extra_user_roles ,
2014-07-14 17:48:05 +08:00
} , context_instance = RequestContext ( request ) )
2013-11-21 11:47:53 +08:00
2015-11-17 15:54:37 +08:00
@login_required
@sys_staff_required
def sys_useradmin_export_excel ( request ) :
""" Export all users from database to excel
"""
next = request . META . get ( ' HTTP_REFERER ' , None )
if not next :
next = SITE_ROOT
try :
2016-08-09 11:17:38 +08:00
users = ccnet_api . get_emailusers ( ' DB ' , - 1 , - 1 ) + \
ccnet_api . get_emailusers ( ' LDAPImport ' , - 1 , - 1 )
2015-11-17 15:54:37 +08:00
except Exception as e :
logger . error ( e )
2015-12-03 17:56:28 +08:00
messages . error ( request , _ ( u ' Failed to export Excel ' ) )
2015-11-17 15:54:37 +08:00
return HttpResponseRedirect ( next )
if is_pro_version ( ) :
is_pro = True
else :
is_pro = False
if is_pro :
2016-12-16 12:15:53 +08:00
head = [ _ ( " Email " ) , _ ( " Name " ) , _ ( " Contact Email " ) , _ ( " Status " ) , _ ( " Role " ) ,
_ ( " Space Usage " ) + " (MB) " , _ ( " Space Quota " ) + " (MB) " ,
_ ( " Create At " ) , _ ( " Last Login " ) , _ ( " Admin " ) , _ ( " LDAP(imported) " ) , ]
2015-11-17 15:54:37 +08:00
else :
2016-08-09 11:17:38 +08:00
head = [ _ ( " Email " ) , _ ( " Name " ) , _ ( " Contact Email " ) , _ ( " Status " ) ,
2016-12-16 12:15:53 +08:00
_ ( " Space Usage " ) + " (MB) " , _ ( " Space Quota " ) + " (MB) " ,
2016-08-09 11:17:38 +08:00
_ ( " Create At " ) , _ ( " Last Login " ) , _ ( " Admin " ) , _ ( " LDAP(imported) " ) , ]
2015-11-17 15:54:37 +08:00
data_list = [ ]
last_logins = UserLastLogin . objects . filter ( username__in = [ x . email for x in users ] )
for user in users :
2016-08-09 11:17:38 +08:00
# populate name and contact email
populate_user_info ( user )
2016-12-16 12:15:53 +08:00
# populate space usage and quota
MB = get_file_size_unit ( ' MB ' )
_populate_user_quota_usage ( user )
if user . space_usage > 0 :
try :
space_usage_MB = round ( float ( user . space_usage ) / MB , 2 )
except Exception as e :
logger . error ( e )
space_usage_MB = ' -- '
else :
2016-12-19 11:05:37 +08:00
space_usage_MB = ' '
2016-12-16 12:15:53 +08:00
if user . space_quota > 0 :
try :
space_quota_MB = round ( float ( user . space_quota ) / MB , 2 )
except Exception as e :
logger . error ( e )
space_quota_MB = ' -- '
else :
2016-12-19 11:05:37 +08:00
space_quota_MB = ' '
2016-12-16 12:15:53 +08:00
2015-11-17 15:54:37 +08:00
# populate user last login time
user . last_login = None
for last_login in last_logins :
if last_login . username == user . email :
user . last_login = last_login . last_login
if user . is_active :
status = _ ( ' Active ' )
else :
status = _ ( ' Inactive ' )
2015-11-24 13:19:58 +08:00
create_at = tsstr_sec ( user . ctime ) if user . ctime else ' '
last_login = user . last_login . strftime ( " % Y- % m- %d % H: % M: % S " ) if \
2015-11-17 15:54:37 +08:00
user . last_login else ' '
is_admin = _ ( ' Yes ' ) if user . is_staff else ' '
ldap_import = _ ( ' Yes ' ) if user . source == ' LDAPImport ' else ' '
if is_pro :
if user . role == GUEST_USER :
role = _ ( ' Guest ' )
else :
role = _ ( ' Default ' )
2016-12-16 12:15:53 +08:00
row = [ user . email , user . name , user . contact_email , status , role ,
space_usage_MB , space_quota_MB , create_at ,
last_login , is_admin , ldap_import ]
2015-11-17 15:54:37 +08:00
else :
2016-08-09 11:17:38 +08:00
row = [ user . email , user . name , user . contact_email , status ,
2016-12-16 12:15:53 +08:00
space_usage_MB , space_quota_MB , create_at ,
last_login , is_admin , ldap_import ]
2015-11-17 15:54:37 +08:00
data_list . append ( row )
2015-12-03 17:56:28 +08:00
wb = write_xls ( ' users ' , head , data_list )
2015-11-17 15:54:37 +08:00
if not wb :
2015-12-03 17:56:28 +08:00
messages . error ( request , _ ( u ' Failed to export Excel ' ) )
2015-11-17 15:54:37 +08:00
return HttpResponseRedirect ( next )
2015-12-07 10:52:56 +08:00
response = HttpResponse ( content_type = ' application/ms-excel ' )
2015-11-24 13:19:58 +08:00
response [ ' Content-Disposition ' ] = ' attachment; filename=users.xlsx '
2015-11-17 15:54:37 +08:00
wb . save ( response )
return response
2015-06-26 14:05:39 +08:00
@login_required
@sys_staff_required
def sys_user_admin_ldap_imported ( request ) :
""" List all users from LDAP imported.
"""
# 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
2015-10-24 17:18:07 +08:00
users_plus_one = seaserv . get_emailusers ( ' LDAPImport ' ,
per_page * ( current_page - 1 ) ,
per_page + 1 )
2015-06-26 14:05:39 +08:00
if len ( users_plus_one ) == per_page + 1 :
page_next = True
else :
page_next = False
users = users_plus_one [ : per_page ]
last_logins = UserLastLogin . objects . filter ( username__in = [ x . email for x in users ] )
for user in users :
if user . email == request . user . email :
user . is_self = True
2016-10-18 10:17:41 +08:00
populate_user_info ( user )
2015-06-26 14:05:39 +08:00
_populate_user_quota_usage ( user )
# populate user last login time
user . last_login = None
for last_login in last_logins :
if last_login . username == user . email :
user . last_login = last_login . last_login
return render_to_response (
' sysadmin/sys_user_admin_ldap_imported.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 ,
' is_pro ' : is_pro_version ( ) ,
} , context_instance = RequestContext ( request ) )
2013-11-21 11:47:53 +08:00
@login_required
@sys_staff_required
2014-04-16 17:39:23 +08:00
def sys_user_admin_ldap ( request ) :
2013-11-21 11:47:53 +08:00
""" List all users from LDAP.
"""
# 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
2015-10-24 17:18:07 +08:00
users_plus_one = seaserv . get_emailusers ( ' LDAP ' ,
per_page * ( current_page - 1 ) ,
per_page + 1 )
2013-11-21 11:47:53 +08:00
if len ( users_plus_one ) == per_page + 1 :
page_next = True
else :
page_next = False
users = users_plus_one [ : per_page ]
2013-11-21 15:05:08 +08:00
last_logins = UserLastLogin . objects . filter ( username__in = [ x . email for x in users ] )
2013-11-21 11:47:53 +08:00
for user in users :
2015-06-26 14:05:39 +08:00
if user . email == request . user . email :
2013-11-21 11:47:53 +08:00
user . is_self = True
2014-12-24 17:35:15 +08:00
_populate_user_quota_usage ( user )
2013-11-21 15:05:08 +08:00
# populate user last login time
user . last_login = None
for last_login in last_logins :
if last_login . username == user . email :
user . last_login = last_login . last_login
2014-12-25 17:17:29 +08:00
2013-11-21 11:47:53 +08:00
return render_to_response (
2014-04-16 17:39:23 +08:00
' sysadmin/sys_useradmin_ldap.html ' , {
2013-11-21 11:47:53 +08:00
' users ' : users ,
' current_page ' : current_page ,
' prev_page ' : current_page - 1 ,
' next_page ' : current_page + 1 ,
' per_page ' : per_page ,
' page_next ' : page_next ,
2015-06-24 15:08:04 +08:00
' is_pro ' : is_pro_version ( ) ,
2013-05-17 13:41:37 +08:00
} ,
context_instance = RequestContext ( request ) )
2014-04-16 17:39:23 +08:00
@login_required
@sys_staff_required
def sys_user_admin_admins ( request ) :
2015-06-26 14:05:39 +08:00
""" List all admins from database and ldap imported
2014-04-16 17:39:23 +08:00
"""
2015-10-24 17:18:07 +08:00
db_users = seaserv . get_emailusers ( ' DB ' , - 1 , - 1 )
ldpa_imported_users = seaserv . get_emailusers ( ' LDAPImport ' , - 1 , - 1 )
2014-04-16 17:39:23 +08:00
admin_users = [ ]
not_admin_users = [ ]
2015-06-26 14:05:39 +08:00
for user in db_users + ldpa_imported_users :
2014-04-16 17:39:23 +08:00
if user . is_staff is True :
admin_users . append ( user )
else :
not_admin_users . append ( user )
last_logins = UserLastLogin . objects . filter ( username__in = [ x . email for x in admin_users ] )
for user in admin_users :
2015-06-26 14:05:39 +08:00
if user . email == request . user . email :
2014-04-16 17:39:23 +08:00
user . is_self = True
2014-12-24 17:35:15 +08:00
_populate_user_quota_usage ( user )
2015-06-26 14:05:39 +08:00
# check db user's role
if user . source == " DB " :
if user . role == GUEST_USER :
user . is_guest = True
else :
user . is_guest = False
2014-04-16 17:39:23 +08:00
# populate user last login time
user . last_login = None
for last_login in last_logins :
if last_login . username == user . email :
user . last_login = last_login . last_login
2015-10-24 17:18:07 +08:00
have_ldap = True if len ( seaserv . get_emailusers ( ' LDAP ' , 0 , 1 ) ) > 0 else False
2014-04-16 17:39:23 +08:00
return render_to_response (
' sysadmin/sys_useradmin_admins.html ' , {
2015-06-26 14:05:39 +08:00
' users ' : admin_users ,
2014-04-16 17:39:23 +08:00
' not_admin_users ' : not_admin_users ,
' have_ldap ' : have_ldap ,
2014-07-14 17:48:05 +08:00
' default_user ' : DEFAULT_USER ,
' guest_user ' : GUEST_USER ,
2015-06-24 15:08:04 +08:00
' is_pro ' : is_pro_version ( ) ,
2014-12-24 17:35:15 +08:00
} , context_instance = RequestContext ( request ) )
2014-04-16 17:39:23 +08:00
2013-05-17 13:41:37 +08:00
@login_required
@sys_staff_required
def user_info ( request , email ) :
2015-04-08 17:55:01 +08:00
org_name = None
space_quota = space_usage = 0
2013-05-17 13:41:37 +08:00
2014-10-10 18:42:06 +08:00
org = ccnet_threaded_rpc . get_orgs_by_user ( email )
if not org :
2016-01-19 16:35:12 +08:00
owned_repos = mute_seafile_api . get_owned_repo_list ( email ,
ret_corrupted = True )
2015-09-15 17:56:26 +08:00
in_repos = mute_seafile_api . get_share_in_repo_list ( email , - 1 , - 1 )
2015-04-08 17:55:01 +08:00
space_usage = mute_seafile_api . get_user_self_usage ( email )
space_quota = mute_seafile_api . get_user_quota ( email )
2014-10-10 18:42:06 +08:00
else :
org_id = org [ 0 ] . org_id
2014-10-22 10:10:58 +08:00
org_name = org [ 0 ] . org_name
2014-12-24 17:35:15 +08:00
space_usage = seafserv_threaded_rpc . get_org_user_quota_usage ( org_id ,
email )
space_quota = seafserv_threaded_rpc . get_org_user_quota ( org_id , email )
2016-01-19 16:35:12 +08:00
owned_repos = seafile_api . get_org_owned_repo_list ( org_id , email ,
ret_corrupted = True )
2015-09-15 17:56:26 +08:00
in_repos = seafile_api . get_org_share_in_repo_list ( org_id , email , - 1 , - 1 )
2013-05-17 13:41:37 +08:00
2016-09-22 11:32:21 +08:00
owned_repos = filter ( lambda r : not r . is_virtual , owned_repos )
2013-12-18 13:56:20 +08:00
# get user profile
profile = Profile . objects . get_profile_by_user ( email )
d_profile = DetailedProfile . objects . get_detailed_profile_by_user ( email )
2014-04-29 11:05:36 +08:00
user_shared_links = [ ]
# download links
2014-08-20 15:05:20 +08:00
p_fileshares = [ ]
2014-05-09 15:08:56 +08:00
fileshares = list ( FileShare . objects . filter ( username = email ) )
2014-04-29 11:05:36 +08:00
for fs in fileshares :
2015-04-08 17:55:01 +08:00
try :
r = seafile_api . get_repo ( fs . repo_id )
if not r :
2014-04-29 11:05:36 +08:00
fs . delete ( )
continue
2015-04-08 17:55:01 +08:00
if fs . is_file_share_link ( ) :
if seafile_api . get_file_id_by_path ( r . id , fs . path ) is None :
fs . delete ( )
continue
fs . filename = os . path . basename ( fs . path )
path = fs . path . rstrip ( ' / ' ) # Normalize file path
obj_id = seafile_api . get_file_id_by_path ( r . id , path )
fs . file_size = seafile_api . get_file_size ( r . store_id ,
r . version , obj_id )
else :
if seafile_api . get_dir_id_by_path ( r . id , fs . path ) is None :
fs . delete ( )
continue
2015-08-24 09:53:00 +08:00
if fs . path == ' / ' :
fs . filename = ' / '
else :
fs . filename = os . path . basename ( fs . path . rstrip ( ' / ' ) )
2015-04-08 17:55:01 +08:00
path = fs . path
if path [ - 1 ] != ' / ' : # Normalize dir path
path + = ' / '
# get dir size
2016-01-27 15:52:33 +08:00
dir_id = seafile_api . get_dir_id_by_commit_and_path ( r . id , r . head_cmmt_id , path )
fs . dir_size = seafile_api . get_dir_size ( r . store_id , r . version , dir_id )
2015-04-08 17:55:01 +08:00
fs . is_download = True
p_fileshares . append ( fs )
except SearpcError as e :
logger . error ( e )
continue
2014-08-20 15:05:20 +08:00
p_fileshares . sort ( key = lambda x : x . view_cnt , reverse = True )
user_shared_links + = p_fileshares
2014-04-29 11:05:36 +08:00
# upload links
2014-05-09 15:08:56 +08:00
uploadlinks = list ( UploadLinkShare . objects . filter ( username = email ) )
2014-08-20 15:05:20 +08:00
p_uploadlinks = [ ]
2014-04-29 11:05:36 +08:00
for link in uploadlinks :
2015-04-08 17:55:01 +08:00
try :
r = seafile_api . get_repo ( link . repo_id )
if not r :
link . delete ( )
continue
if seafile_api . get_dir_id_by_path ( r . id , link . path ) is None :
link . delete ( )
continue
2015-08-24 09:53:00 +08:00
if link . path == ' / ' :
link . dir_name = ' / '
else :
link . dir_name = os . path . basename ( link . path . rstrip ( ' / ' ) )
2015-04-08 17:55:01 +08:00
link . is_upload = True
p_uploadlinks . append ( link )
except SearpcError as e :
logger . error ( e )
2014-04-29 11:05:36 +08:00
continue
2014-08-20 15:05:20 +08:00
p_uploadlinks . sort ( key = lambda x : x . view_cnt , reverse = True )
user_shared_links + = p_uploadlinks
2014-04-29 11:05:36 +08:00
2015-11-24 19:02:30 +08:00
try :
personal_groups = seaserv . get_personal_groups_by_user ( email )
except SearpcError as e :
logger . error ( e )
personal_groups = [ ]
for g in personal_groups :
try :
is_group_staff = seaserv . check_group_staff ( g . id , email )
except SearpcError as e :
logger . error ( e )
is_group_staff = False
if email == g . creator_name :
g . role = _ ( ' Owner ' )
elif is_group_staff :
g . role = _ ( ' Admin ' )
else :
g . role = _ ( ' Member ' )
2013-05-17 13:41:37 +08:00
return render_to_response (
' sysadmin/userinfo.html ' , {
' owned_repos ' : owned_repos ,
2014-12-24 17:35:15 +08:00
' space_quota ' : space_quota ,
' space_usage ' : space_usage ,
2013-05-17 13:41:37 +08:00
' in_repos ' : in_repos ,
' email ' : email ,
2013-12-18 13:56:20 +08:00
' profile ' : profile ,
' d_profile ' : d_profile ,
2014-10-22 10:10:58 +08:00
' org_name ' : org_name ,
2014-12-25 17:17:29 +08:00
' user_shared_links ' : user_shared_links ,
2015-10-20 16:35:54 +08:00
' enable_sys_admin_view_repo ' : ENABLE_SYS_ADMIN_VIEW_REPO ,
2015-11-24 19:02:30 +08:00
' personal_groups ' : personal_groups ,
2014-12-24 17:35:15 +08:00
} , context_instance = RequestContext ( request ) )
2013-05-17 13:41:37 +08:00
2014-07-01 15:21:49 +08:00
@login_required_ajax
2013-11-21 11:23:43 +08:00
@sys_staff_required
def user_set_quota ( request , email ) :
2014-07-01 15:21:49 +08:00
if request . method != ' POST ' :
2013-11-21 11:23:43 +08:00
raise Http404
content_type = ' application/json; charset=utf-8 '
result = { }
f = SetUserQuotaForm ( request . POST )
if f . is_valid ( ) :
2014-12-25 17:17:29 +08:00
space_quota_mb = f . cleaned_data [ ' space_quota ' ]
2016-02-23 17:20:02 +08:00
space_quota = space_quota_mb * get_file_size_unit ( ' MB ' )
2013-11-21 11:23:43 +08:00
2014-10-10 18:42:06 +08:00
org = ccnet_threaded_rpc . get_orgs_by_user ( email )
2013-11-21 11:23:43 +08:00
try :
2014-10-10 18:42:06 +08:00
if not org :
2014-12-25 17:17:29 +08:00
seafile_api . set_user_quota ( email , space_quota )
2014-10-10 18:42:06 +08:00
else :
org_id = org [ 0 ] . org_id
2016-02-23 17:20:02 +08:00
org_quota_mb = seafserv_threaded_rpc . get_org_quota ( org_id ) / get_file_size_unit ( ' MB ' )
2014-12-25 17:17:29 +08:00
if space_quota_mb > org_quota_mb :
2014-10-22 10:10:58 +08:00
result [ ' error ' ] = _ ( u ' Failed to set quota: maximum quota is %d MB ' % \
org_quota_mb )
return HttpResponse ( json . dumps ( result ) , status = 400 , content_type = content_type )
else :
2014-12-25 17:17:29 +08:00
seafserv_threaded_rpc . set_org_user_quota ( org_id , email , space_quota )
2013-11-21 11:23:43 +08:00
except :
2014-07-01 15:21:49 +08:00
result [ ' error ' ] = _ ( u ' Failed to set quota: internal server error ' )
2013-11-21 11:23:43 +08:00
return HttpResponse ( json . dumps ( result ) , status = 500 , 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 ) , status = 400 , content_type = content_type )
2014-09-26 14:02:19 +08:00
@login_required_ajax
@sys_staff_required
def sys_org_set_quota ( request , org_id ) :
if request . method != ' POST ' :
raise Http404
content_type = ' application/json; charset=utf-8 '
result = { }
org_id = int ( org_id )
quota_mb = int ( request . POST . get ( ' quota ' , 0 ) )
2016-02-23 17:20:02 +08:00
quota = quota_mb * get_file_size_unit ( ' MB ' )
2014-09-26 14:02:19 +08:00
try :
seafserv_threaded_rpc . set_org_quota ( org_id , quota )
except SearpcError as e :
logger . error ( e )
result [ ' error ' ] = _ ( u ' Failed to set quota: internal server error ' )
return HttpResponse ( json . dumps ( result ) , status = 500 , content_type = content_type )
result [ ' success ' ] = True
return HttpResponse ( json . dumps ( result ) , content_type = content_type )
2013-05-17 13:41:37 +08:00
@login_required
@sys_staff_required
2015-09-02 11:14:54 +08:00
@require_POST
2015-06-26 14:05:39 +08:00
def user_remove ( request , email ) :
2014-10-17 10:35:58 +08:00
""" Remove user """
referer = request . META . get ( ' HTTP_REFERER ' , None )
next = reverse ( ' sys_useradmin ' ) if referer is None else referer
2013-05-17 13:41:37 +08:00
try :
2015-06-26 14:05:39 +08:00
user = User . objects . get ( email = email )
2014-10-10 18:42:06 +08:00
org = ccnet_threaded_rpc . get_orgs_by_user ( user . email )
if org :
2014-10-17 10:35:58 +08:00
if org [ 0 ] . creator == user . email :
messages . error ( request , _ ( u ' Failed to delete: the user is an organization creator ' ) )
return HttpResponseRedirect ( next )
2013-05-17 13:41:37 +08:00
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 ' ) )
2013-12-21 14:11:07 +08:00
return HttpResponseRedirect ( next )
2013-05-17 13:41:37 +08:00
2015-01-08 16:23:18 +08:00
@login_required
@sys_staff_required
2015-10-21 18:22:52 +08:00
@require_POST
2015-01-10 12:07:33 +08:00
def remove_trial ( request , user_or_org ) :
""" Remove trial account.
2015-05-04 13:57:10 +08:00
2015-01-08 16:23:18 +08:00
Arguments :
- ` request ` :
"""
2015-01-16 10:48:47 +08:00
if not ENABLE_TRIAL_ACCOUNT :
raise Http404
2015-01-08 16:23:18 +08:00
referer = request . META . get ( ' HTTP_REFERER ' , None )
next = reverse ( ' sys_useradmin ' ) if referer is None else referer
2015-01-10 12:07:33 +08:00
TrialAccount . objects . filter ( user_or_org = user_or_org ) . delete ( )
2015-01-08 16:23:18 +08:00
2015-01-10 12:07:33 +08:00
messages . success ( request , _ ( ' Successfully remove trial for: %s ' ) % user_or_org )
2015-01-08 16:23:18 +08:00
return HttpResponseRedirect ( next )
2015-06-27 14:12:46 +08:00
# @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'))
# referer = request.META.get('HTTP_REFERER', None)
# next = reverse('sys_useradmin') if referer is None else referer
# return HttpResponseRedirect(next)
2013-05-17 13:41:37 +08:00
@login_required
@sys_staff_required
2015-09-02 11:14:54 +08:00
@require_POST
2015-06-26 14:05:39 +08:00
def user_remove_admin ( request , email ) :
2013-05-17 13:41:37 +08:00
""" Unset user admin. """
try :
2015-06-26 14:05:39 +08:00
user = User . objects . get ( email = email )
2013-05-17 13:41:37 +08:00
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 ' ) )
2013-12-21 14:11:07 +08:00
referer = request . META . get ( ' HTTP_REFERER ' , None )
next = reverse ( ' sys_useradmin ' ) if referer is None else referer
2014-12-25 17:17:29 +08:00
2013-12-21 14:11:07 +08:00
return HttpResponseRedirect ( next )
2013-05-17 13:41:37 +08:00
2015-06-27 14:12:46 +08:00
# @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()
# messages.success(request, _(u'Successfully activated "%s".') % user.email)
# except User.DoesNotExist:
# messages.success(request, _(u'Failed to activate: user does not exist.'))
# next = request.META.get('HTTP_REFERER', None)
# if not next:
# next = reverse('sys_useradmin')
# return HttpResponseRedirect(next)
# @login_required
# @sys_staff_required
# def user_deactivate(request, user_id):
# try:
# user = User.objects.get(id=int(user_id))
# user.is_active = False
# user.save()
# messages.success(request, _(u'Successfully deactivated "%s".') % user.email)
# except User.DoesNotExist:
# messages.success(request, _(u'Failed to deactivate: user does not exist.'))
# next = request.META.get('HTTP_REFERER', None)
# if not next:
# next = reverse('sys_useradmin')
# return HttpResponseRedirect(next)
2013-10-15 17:41:02 +08:00
2013-10-17 18:20:44 +08:00
def email_user_on_activation ( user ) :
""" Send an email to user when admin activate his/her account.
"""
2014-02-18 20:16:39 +08:00
c = {
' username ' : user . email ,
}
2014-02-19 20:03:55 +08:00
send_html_email ( _ ( u ' Your account on %s is activated ' ) % SITE_NAME ,
' sysadmin/user_activation_email.html ' , c , None , [ user . email ] )
2014-07-18 11:52:59 +08:00
2014-07-01 15:21:49 +08:00
@login_required_ajax
2013-10-15 17:41:02 +08:00
@sys_staff_required
2015-10-21 18:22:52 +08:00
@require_POST
2014-07-18 11:52:59 +08:00
def user_toggle_status ( request , email ) :
2013-10-15 17:41:02 +08:00
content_type = ' application/json; charset=utf-8 '
2014-07-18 11:52:59 +08:00
if not is_valid_username ( email ) :
return HttpResponse ( json . dumps ( { ' success ' : False } ) , status = 400 ,
content_type = content_type )
2013-10-15 17:41:02 +08:00
try :
2015-10-21 18:22:52 +08:00
user_status = int ( request . POST . get ( ' s ' , 0 ) )
2013-10-15 17:41:02 +08:00
except ValueError :
user_status = 0
try :
2014-07-18 11:52:59 +08:00
user = User . objects . get ( email )
2013-10-15 17:41:02 +08:00
user . is_active = bool ( user_status )
2015-09-09 10:47:36 +08:00
result_code = user . save ( )
if result_code == - 1 :
return HttpResponse ( json . dumps ( { ' success ' : False } ) , status = 403 ,
content_type = content_type )
2013-10-17 18:20:44 +08:00
if user . is_active is True :
try :
email_user_on_activation ( user )
email_sent = True
except Exception as e :
logger . error ( e )
email_sent = False
return HttpResponse ( json . dumps ( { ' success ' : True ,
' email_sent ' : email_sent ,
} ) , content_type = content_type )
2015-03-09 17:34:28 +08:00
else :
clear_token ( user . email )
2013-10-15 17:41:02 +08:00
return HttpResponse ( json . dumps ( { ' success ' : True } ) ,
2013-10-17 18:20:44 +08:00
content_type = content_type )
2013-10-15 17:41:02 +08:00
except User . DoesNotExist :
return HttpResponse ( json . dumps ( { ' success ' : False } ) , status = 500 ,
content_type = content_type )
2014-07-07 16:05:14 +08:00
@login_required_ajax
@sys_staff_required
2015-10-21 18:22:52 +08:00
@require_POST
2014-07-14 17:48:05 +08:00
def user_toggle_role ( request , email ) :
2014-07-07 16:05:14 +08:00
content_type = ' application/json; charset=utf-8 '
2014-07-14 17:48:05 +08:00
if not is_valid_username ( email ) :
return HttpResponse ( json . dumps ( { ' success ' : False } ) , status = 400 ,
content_type = content_type )
2015-06-24 15:08:04 +08:00
if not is_pro_version ( ) :
2014-07-14 17:48:05 +08:00
return HttpResponse ( json . dumps ( { ' success ' : False } ) , status = 403 ,
content_type = content_type )
2014-07-07 16:05:14 +08:00
try :
2015-10-21 18:22:52 +08:00
user_role = request . POST . get ( ' r ' , DEFAULT_USER )
2014-07-07 16:05:14 +08:00
except ValueError :
user_role = DEFAULT_USER
try :
2014-07-14 17:48:05 +08:00
user = User . objects . get ( email )
2014-07-07 16:05:14 +08:00
User . objects . update_role ( user . email , user_role )
return HttpResponse ( json . dumps ( { ' success ' : True } ) ,
content_type = content_type )
except User . DoesNotExist :
return HttpResponse ( json . dumps ( { ' success ' : False } ) , status = 500 ,
content_type = content_type )
2013-05-17 13:41:37 +08:00
def send_user_reset_email ( request , email , password ) :
"""
Send email when reset user password .
"""
2014-02-17 19:43:16 +08:00
2013-05-17 13:41:37 +08:00
c = {
' email ' : email ,
' password ' : password ,
}
2014-02-19 20:03:55 +08:00
send_html_email ( _ ( u ' Password has been reset on %s ' ) % SITE_NAME ,
' sysadmin/user_reset_email.html ' , c , None , [ email ] )
2014-12-25 17:17:29 +08:00
2013-05-17 13:41:37 +08:00
@login_required
@sys_staff_required
2015-09-02 11:14:54 +08:00
@require_POST
2015-06-26 14:05:39 +08:00
def user_reset ( request , email ) :
2013-05-17 13:41:37 +08:00
""" Reset password for user. """
try :
2015-06-26 14:05:39 +08:00
user = User . objects . get ( email = email )
2013-05-17 13:41:37 +08:00
if isinstance ( INIT_PASSWD , FunctionType ) :
new_password = INIT_PASSWD ( )
else :
new_password = INIT_PASSWD
user . set_password ( new_password )
user . save ( )
2015-11-23 17:55:42 +08:00
2015-04-29 10:24:29 +08:00
clear_token ( user . username )
2016-03-29 17:03:50 +08:00
if config . FORCE_PASSWORD_CHANGE :
UserOptions . objects . set_force_passwd_change ( user . username )
2013-05-17 13:41:37 +08:00
if IS_EMAIL_CONFIGURED :
if SEND_EMAIL_ON_RESETTING_USER_PASSWD :
try :
2017-01-16 15:46:00 +08:00
contact_email = Profile . objects . get_contact_email_by_user ( user . email )
send_user_reset_email ( request , contact_email , new_password )
2013-05-17 13:41:37 +08:00
msg = _ ( ' Successfully reset password to %(passwd)s , an email has been sent to %(user)s . ' ) % \
2017-01-17 16:08:03 +08:00
{ ' passwd ' : new_password , ' user ' : contact_email }
2013-05-17 13:41:37 +08:00
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 )
2014-03-01 13:49:22 +08:00
referer = request . META . get ( ' HTTP_REFERER ' , None )
next = reverse ( ' sys_useradmin ' ) if referer is None else referer
2014-12-25 17:17:29 +08:00
2014-03-01 13:49:22 +08:00
return HttpResponseRedirect ( next )
2014-12-25 17:17:29 +08:00
2013-05-17 13:41:37 +08:00
def send_user_add_mail ( request , email , password ) :
""" Send email when add new user. """
c = {
' user ' : request . user . username ,
' org ' : request . user . org ,
' email ' : email ,
' password ' : password ,
}
2014-02-19 20:03:55 +08:00
send_html_email ( _ ( u ' You are invited to join %s ' ) % SITE_NAME ,
' sysadmin/user_add_email.html ' , c , None , [ email ] )
2013-05-17 13:41:37 +08:00
2014-07-01 15:21:49 +08:00
@login_required_ajax
2013-05-17 13:41:37 +08:00
def user_add ( request ) :
""" Add a user """
2014-07-01 15:21:49 +08:00
if not request . user . is_staff or request . method != ' POST ' :
2013-05-17 13:41:37 +08:00
raise Http404
content_type = ' application/json; charset=utf-8 '
2014-07-01 15:21:49 +08:00
post_values = request . POST . copy ( )
post_email = request . POST . get ( ' email ' , ' ' )
2014-07-23 15:57:25 +08:00
post_role = request . POST . get ( ' role ' , DEFAULT_USER )
2014-07-07 16:05:14 +08:00
post_values . update ( {
' email ' : post_email . lower ( ) ,
' role ' : post_role ,
} )
2014-07-01 15:21:49 +08:00
form = AddUserForm ( post_values )
if form . is_valid ( ) :
email = form . cleaned_data [ ' email ' ]
2016-12-21 11:41:32 +08:00
name = form . cleaned_data [ ' name ' ]
department = form . cleaned_data [ ' department ' ]
2014-07-07 16:05:14 +08:00
role = form . cleaned_data [ ' role ' ]
2014-07-01 15:21:49 +08:00
password = form . cleaned_data [ ' password1 ' ]
2015-05-07 11:38:29 +08:00
try :
user = User . objects . create_user ( email , password , is_staff = False ,
is_active = True )
except User . DoesNotExist as e :
logger . error ( e )
err_msg = _ ( u ' Fail to add user %s . ' ) % email
return HttpResponse ( json . dumps ( { ' error ' : err_msg } ) , status = 403 , content_type = content_type )
2014-07-07 16:05:14 +08:00
if user :
User . objects . update_role ( email , role )
2016-03-29 17:03:50 +08:00
if config . FORCE_PASSWORD_CHANGE :
UserOptions . objects . set_force_passwd_change ( email )
2016-12-21 11:41:32 +08:00
if name :
Profile . objects . add_or_update ( email , name , ' ' )
if department :
DetailedProfile . objects . add_or_update ( email , department , ' ' )
2014-07-07 16:05:14 +08:00
2014-07-01 15:21:49 +08:00
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 IS_EMAIL_CONFIGURED :
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 )
return HttpResponse ( json . dumps ( { ' success ' : True } ) , content_type = content_type )
else :
if IS_EMAIL_CONFIGURED :
if SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER :
2014-03-05 14:10:05 +08:00
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 )
2013-05-17 13:41:37 +08:00
else :
2014-07-01 15:21:49 +08:00
messages . success ( request , _ ( u ' Successfully added user %s . But email notification can not be sent, because Email service is not properly configured. ' ) % email )
2013-05-17 13:41:37 +08:00
2014-07-01 15:21:49 +08:00
return HttpResponse ( json . dumps ( { ' success ' : True } ) , content_type = content_type )
else :
2014-07-09 17:51:07 +08:00
return HttpResponse ( json . dumps ( { ' error ' : str ( form . errors . values ( ) [ 0 ] ) } ) , status = 400 , content_type = content_type )
2013-05-17 13:41:37 +08:00
2015-11-17 15:54:37 +08:00
@login_required
@sys_staff_required
def sys_group_admin_export_excel ( request ) :
""" Export all groups to excel
"""
next = request . META . get ( ' HTTP_REFERER ' , None )
if not next :
next = SITE_ROOT
try :
groups = ccnet_threaded_rpc . get_all_groups ( - 1 , - 1 )
except Exception as e :
logger . error ( e )
2015-12-03 18:05:20 +08:00
messages . error ( request , _ ( u ' Failed to export Excel ' ) )
2015-11-17 15:54:37 +08:00
return HttpResponseRedirect ( next )
head = [ _ ( " Name " ) , _ ( " Creator " ) , _ ( " Create At " ) ]
data_list = [ ]
for grp in groups :
2015-11-24 13:19:58 +08:00
create_at = tsstr_sec ( grp . timestamp ) if grp . timestamp else ' '
row = [ grp . group_name , grp . creator_name , create_at ]
2015-11-17 15:54:37 +08:00
data_list . append ( row )
2015-12-03 17:56:28 +08:00
wb = write_xls ( ' groups ' , head , data_list )
2015-11-17 15:54:37 +08:00
if not wb :
2015-12-03 18:05:20 +08:00
messages . error ( request , _ ( u ' Failed to export Excel ' ) )
2015-11-17 15:54:37 +08:00
return HttpResponseRedirect ( next )
2015-12-07 10:52:56 +08:00
response = HttpResponse ( content_type = ' application/ms-excel ' )
2015-11-24 13:19:58 +08:00
response [ ' Content-Disposition ' ] = ' attachment; filename=groups.xlsx '
2015-11-17 15:54:37 +08:00
wb . save ( response )
return response
2015-04-25 10:57:14 +08:00
@login_required
@sys_staff_required
def sys_admin_group_info ( request , group_id ) :
group_id = int ( group_id )
group = get_group ( group_id )
2015-07-25 19:08:12 +08:00
org_id = request . GET . get ( ' org_id ' , None )
if org_id :
repos = seafile_api . get_org_group_repos ( org_id , group_id )
else :
repos = seafile_api . get_repos_by_group ( group_id )
2015-04-25 10:57:14 +08:00
members = get_group_members ( group_id )
return render_to_response ( ' sysadmin/sys_admin_group_info.html ' , {
' group ' : group ,
' repos ' : repos ,
' members ' : members ,
2015-10-20 16:35:54 +08:00
' enable_sys_admin_view_repo ' : ENABLE_SYS_ADMIN_VIEW_REPO ,
2015-04-25 10:57:14 +08:00
} , context_instance = RequestContext ( request ) )
2014-03-05 14:10:05 +08:00
@login_required
@sys_staff_required
def sys_org_admin ( request ) :
2014-08-27 17:14:35 +08:00
# 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
2015-09-16 18:40:14 +08:00
try :
from seahub_extra . plan . models import OrgPlan
enable_org_plan = True
except ImportError :
enable_org_plan = False
if enable_org_plan and request . GET . get ( ' filter ' , ' ' ) == ' paid ' :
orgs = [ ]
ops = OrgPlan . objects . all ( )
for e in ops :
o = ccnet_threaded_rpc . get_org_by_id ( e . org_id )
2015-09-21 12:05:06 +08:00
if not o :
continue
2015-09-16 18:40:14 +08:00
o . quota_usage = seafserv_threaded_rpc . get_org_quota_usage ( o . org_id )
o . total_quota = seafserv_threaded_rpc . get_org_quota ( o . org_id )
o . expiration = e . expire_date
o . is_expired = True if e . expire_date < timezone . now ( ) else False
orgs . append ( o )
return render_to_response ( ' sysadmin/sys_org_admin.html ' , {
' orgs ' : orgs ,
' enable_org_plan ' : enable_org_plan ,
' hide_paginator ' : True ,
' paid_page ' : True ,
} , context_instance = RequestContext ( request ) )
2014-08-27 17:14:35 +08:00
orgs_plus_one = ccnet_threaded_rpc . get_all_orgs ( per_page * ( current_page - 1 ) ,
per_page + 1 )
2015-09-16 18:40:14 +08:00
if len ( orgs_plus_one ) == per_page + 1 :
page_next = True
else :
page_next = False
2014-08-27 17:14:35 +08:00
orgs = orgs_plus_one [ : per_page ]
2015-01-10 12:07:33 +08:00
2015-01-16 10:48:47 +08:00
if ENABLE_TRIAL_ACCOUNT :
2015-01-10 12:07:33 +08:00
trial_orgs = TrialAccount . objects . filter ( user_or_org__in = [ x . org_id for x in orgs ] )
else :
trial_orgs = [ ]
2015-09-16 18:40:14 +08:00
2014-09-26 14:02:19 +08:00
for org in orgs :
org . quota_usage = seafserv_threaded_rpc . get_org_quota_usage ( org . org_id )
org . total_quota = seafserv_threaded_rpc . get_org_quota ( org . org_id )
2014-08-27 17:14:35 +08:00
2015-09-15 17:32:09 +08:00
from seahub_extra . organizations . settings import ORG_TRIAL_DAYS
if ORG_TRIAL_DAYS > 0 :
from datetime import timedelta
org . expiration = datetime . datetime . fromtimestamp ( org . ctime / 1e6 ) + timedelta ( days = ORG_TRIAL_DAYS )
2015-01-10 12:07:33 +08:00
org . trial_info = None
for trial_org in trial_orgs :
if trial_org . user_or_org == str ( org . org_id ) :
org . trial_info = { ' expire_date ' : trial_org . expire_date }
2015-09-15 17:32:09 +08:00
if trial_org . expire_date :
org . expiration = trial_org . expire_date
2015-01-10 12:07:33 +08:00
2015-09-15 17:32:09 +08:00
if org . expiration :
org . is_expired = True if org . expiration < timezone . now ( ) else False
else :
org . is_expired = False
2014-03-05 14:10:05 +08:00
return render_to_response ( ' sysadmin/sys_org_admin.html ' , {
' orgs ' : orgs ,
2014-08-27 17:14:35 +08:00
' current_page ' : current_page ,
' prev_page ' : current_page - 1 ,
' next_page ' : current_page + 1 ,
' per_page ' : per_page ,
' page_next ' : page_next ,
2015-09-16 18:40:14 +08:00
' enable_org_plan ' : enable_org_plan ,
' all_page ' : True ,
2014-03-05 14:10:05 +08:00
} , context_instance = RequestContext ( request ) )
@login_required
@sys_staff_required
2015-09-15 17:32:09 +08:00
def sys_org_search ( request ) :
org_name = request . GET . get ( ' name ' , ' ' ) . lower ( )
creator = request . GET . get ( ' creator ' , ' ' ) . lower ( )
if not org_name and not creator :
return HttpResponseRedirect ( reverse ( ' sys_org_admin ' ) )
orgs = [ ]
orgs_all = ccnet_threaded_rpc . get_all_orgs ( - 1 , - 1 )
if org_name and creator :
for o in orgs_all :
if org_name in o . org_name . lower ( ) and creator in o . creator . lower ( ) :
orgs . append ( o )
else :
if org_name :
for o in orgs_all :
if org_name in o . org_name . lower ( ) :
orgs . append ( o )
if creator :
for o in orgs_all :
if creator in o . creator . lower ( ) :
orgs . append ( o )
return render_to_response (
' sysadmin/sys_org_search.html ' , {
' orgs ' : orgs ,
' name ' : org_name ,
' creator ' : creator ,
} , context_instance = RequestContext ( request ) )
2014-03-05 14:10:05 +08:00
@login_required
@sys_staff_required
2014-10-22 10:10:58 +08:00
def sys_org_rename ( request , org_id ) :
if request . method != ' POST ' :
raise Http404
referer = request . META . get ( ' HTTP_REFERER ' , None )
next = reverse ( ' sys_org_admin ' ) if referer is None else referer
new_name = request . POST . get ( ' new_name ' , None )
if new_name :
try :
ccnet_threaded_rpc . set_org_name ( int ( org_id ) , new_name )
messages . success ( request , _ ( u ' Success ' ) )
except Exception as e :
logger . error ( e )
messages . error ( request , _ ( u ' Failed to rename organization ' ) )
return HttpResponseRedirect ( next )
2015-09-17 16:14:09 +08:00
@login_required
@require_POST
@sys_staff_required
def sys_org_remove ( request , org_id ) :
""" Remove an org and all members/repos/groups.
Arguments :
- ` request ` :
- ` org_id ` :
"""
org_id = int ( org_id )
org = ccnet_threaded_rpc . get_org_by_id ( org_id )
users = ccnet_threaded_rpc . get_org_emailusers ( org . url_prefix , - 1 , - 1 )
for u in users :
ccnet_threaded_rpc . remove_org_user ( org_id , u . email )
groups = ccnet_threaded_rpc . get_org_groups ( org . org_id , - 1 , - 1 )
for g in groups :
ccnet_threaded_rpc . remove_org_group ( org_id , g . gid )
# remove org repos
seafserv_threaded_rpc . remove_org_repo_by_org_id ( org_id )
# remove org
ccnet_threaded_rpc . remove_org ( org_id )
messages . success ( request , _ ( u ' Successfully deleted. ' ) )
2015-09-21 12:05:06 +08:00
referer = request . META . get ( ' HTTP_REFERER ' , None )
next = reverse ( ' sys_org_admin ' ) if referer is None else referer
return HttpResponseRedirect ( next )
2015-09-17 16:14:09 +08:00
2014-12-03 18:39:02 +08:00
@login_required_ajax
@sys_staff_required
def sys_org_set_member_quota ( request , org_id ) :
if request . method != ' POST ' :
raise Http404
content_type = ' application/json; charset=utf-8 '
try :
member_quota = int ( request . POST . get ( ' member_quota ' , ' 0 ' ) )
except ValueError :
return HttpResponse ( json . dumps ( { ' error ' : _ ( ' Input should be a number ' ) } ) ,
status = 400 , content_type = content_type )
2014-12-04 10:47:22 +08:00
if member_quota > 0 :
from seahub_extra . organizations . models import OrgMemberQuota
OrgMemberQuota . objects . set_quota ( org_id , member_quota )
messages . success ( request , _ ( u ' Success ' ) )
return HttpResponse ( json . dumps ( { ' success ' : True } ) , status = 200 ,
content_type = content_type )
else :
return HttpResponse ( json . dumps ( { ' error ' : _ ( ' Input number should be greater than 0 ' ) } ) ,
status = 400 , content_type = content_type )
2014-10-22 10:10:58 +08:00
def sys_get_org_base_info ( org_id ) :
2014-10-10 18:42:06 +08:00
2014-03-05 14:10:05 +08:00
org = ccnet_threaded_rpc . get_org_by_id ( org_id )
2014-10-22 10:10:58 +08:00
# users
2014-03-26 15:17:15 +08:00
users = ccnet_threaded_rpc . get_org_emailusers ( org . url_prefix , - 1 , - 1 )
users_count = len ( users )
2014-03-05 14:10:05 +08:00
2014-10-22 10:10:58 +08:00
# groups
groups = ccnet_threaded_rpc . get_org_groups ( org_id , - 1 , - 1 )
groups_count = len ( groups )
2014-03-05 14:10:05 +08:00
# quota
total_quota = seafserv_threaded_rpc . get_org_quota ( org_id )
quota_usage = seafserv_threaded_rpc . get_org_quota_usage ( org_id )
2014-10-10 18:42:06 +08:00
2014-10-22 10:10:58 +08:00
return {
" org " : org ,
" users " : users ,
" users_count " : users_count ,
" groups " : groups ,
" groups_count " : groups_count ,
" total_quota " : total_quota ,
" quota_usage " : quota_usage ,
}
@login_required
@sys_staff_required
def sys_org_info_user ( request , org_id ) :
org_id = int ( org_id )
org_basic_info = sys_get_org_base_info ( org_id )
users = org_basic_info [ " users " ]
2014-10-10 18:42:06 +08:00
last_logins = UserLastLogin . objects . filter ( username__in = [ x . email for x in users ] )
for user in users :
2015-06-26 14:05:39 +08:00
if user . email == request . user . email :
2014-10-10 18:42:06 +08:00
user . is_self = True
try :
user . self_usage = seafserv_threaded_rpc . \
get_org_user_quota_usage ( org_id , user . email )
user . quota = seafserv_threaded_rpc . \
get_org_user_quota ( org_id , user . email )
except SearpcError as e :
logger . error ( e )
user . self_usage = - 1
user . quota = - 1
# populate user last login time
user . last_login = None
for last_login in last_logins :
if last_login . username == user . email :
user . last_login = last_login . last_login
2014-10-22 10:10:58 +08:00
return render_to_response ( ' sysadmin/sys_org_info_user.html ' ,
org_basic_info , context_instance = RequestContext ( request ) )
2014-10-10 18:42:06 +08:00
2014-03-05 14:10:05 +08:00
2014-10-22 10:10:58 +08:00
@login_required
@sys_staff_required
def sys_org_info_group ( request , org_id ) :
org_id = int ( org_id )
org_basic_info = sys_get_org_base_info ( org_id )
return render_to_response ( ' sysadmin/sys_org_info_group.html ' ,
org_basic_info , context_instance = RequestContext ( request ) )
@login_required
@sys_staff_required
def sys_org_info_library ( request , org_id ) :
org_id = int ( org_id )
org_basic_info = sys_get_org_base_info ( org_id )
# library
org_repos = seafserv_threaded_rpc . get_org_repo_list ( org_id , - 1 , - 1 )
for repo in org_repos :
try :
repo . owner = seafserv_threaded_rpc . get_org_repo_owner ( repo . id )
except :
repo . owner = None
org_basic_info [ " org_repos " ] = org_repos
return render_to_response ( ' sysadmin/sys_org_info_library.html ' ,
org_basic_info , context_instance = RequestContext ( request ) )
@login_required
@sys_staff_required
def sys_org_info_setting ( request , org_id ) :
org_id = int ( org_id )
org_basic_info = sys_get_org_base_info ( org_id )
2014-12-04 10:47:22 +08:00
if getattr ( settings , ' ORG_MEMBER_QUOTA_ENABLED ' , False ) :
from seahub_extra . organizations . models import OrgMemberQuota
org_basic_info [ ' org_member_quota ' ] = OrgMemberQuota . objects . get_quota ( org_id )
else :
org_basic_info [ ' org_member_quota ' ] = None
2014-10-22 10:10:58 +08:00
return render_to_response ( ' sysadmin/sys_org_info_setting.html ' ,
2014-12-04 10:47:22 +08:00
org_basic_info ,
context_instance = RequestContext ( request ) )
2013-05-25 11:40:40 +08:00
@login_required
@sys_staff_required
def sys_publink_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 ' , ' 100 ' ) )
except ValueError :
current_page = 1
per_page = 100
2013-08-14 11:45:41 +08:00
offset = per_page * ( current_page - 1 )
limit = per_page + 1
2016-05-03 13:44:43 +08:00
sort_by = request . GET . get ( ' sort_by ' , ' time_up ' )
if sort_by == ' time_down ' :
publinks = FileShare . objects . all ( ) . order_by ( ' ctime ' ) [ offset : offset + limit ]
elif sort_by == ' count_up ' :
publinks = FileShare . objects . all ( ) . order_by ( ' -view_cnt ' ) [ offset : offset + limit ]
elif sort_by == ' count_down ' :
publinks = FileShare . objects . all ( ) . order_by ( ' view_cnt ' ) [ offset : offset + limit ]
else :
publinks = FileShare . objects . all ( ) . order_by ( ' -ctime ' ) [ offset : offset + limit ]
2013-08-14 11:45:41 +08:00
2013-08-09 17:35:08 +08:00
if len ( publinks ) == per_page + 1 :
page_next = True
else :
page_next = False
2013-05-25 11:40:40 +08:00
for l in publinks :
2014-03-05 14:10:05 +08:00
if l . is_file_share_link ( ) :
2013-05-25 11:40:40 +08:00
l . name = os . path . basename ( l . path )
else :
l . name = os . path . dirname ( l . path )
return render_to_response (
' sysadmin/sys_publink_admin.html ' , {
' publinks ' : publinks ,
' current_page ' : current_page ,
' prev_page ' : current_page - 1 ,
' next_page ' : current_page + 1 ,
' per_page ' : per_page ,
2013-08-09 17:35:08 +08:00
' page_next ' : page_next ,
2016-05-03 13:44:43 +08:00
' per_page ' : per_page ,
' sort_by ' : sort_by ,
2013-05-25 11:40:40 +08:00
} ,
context_instance = RequestContext ( request ) )
2013-09-07 11:44:21 +08:00
2015-10-21 18:22:52 +08:00
@login_required_ajax
2015-10-14 17:01:28 +08:00
@sys_staff_required
2015-10-21 18:22:52 +08:00
@require_POST
2015-10-14 17:01:28 +08:00
def sys_publink_remove ( request ) :
""" Remove share links.
"""
2015-10-21 18:22:52 +08:00
content_type = ' application/json; charset=utf-8 '
result = { }
2015-10-14 17:01:28 +08:00
2015-10-21 18:22:52 +08:00
token = request . POST . get ( ' t ' )
if not token :
result = { ' error ' : _ ( u " Argument missing " ) }
return HttpResponse ( json . dumps ( result ) , status = 400 , content_type = content_type )
2015-10-14 17:01:28 +08:00
2015-10-21 18:22:52 +08:00
FileShare . objects . filter ( token = token ) . delete ( )
result = { ' success ' : True }
return HttpResponse ( json . dumps ( result ) , content_type = content_type )
2015-10-14 17:01:28 +08:00
2015-10-21 18:22:52 +08:00
@login_required_ajax
2015-10-14 17:01:28 +08:00
@sys_staff_required
2015-10-21 18:22:52 +08:00
@require_POST
2015-10-14 17:01:28 +08:00
def sys_upload_link_remove ( request ) :
""" Remove shared upload links.
"""
2015-10-21 18:22:52 +08:00
content_type = ' application/json; charset=utf-8 '
result = { }
2015-10-14 17:01:28 +08:00
2015-10-21 18:22:52 +08:00
token = request . POST . get ( ' t ' )
if not token :
result = { ' error ' : _ ( u " Argument missing " ) }
return HttpResponse ( json . dumps ( result ) , status = 400 , content_type = content_type )
2015-10-14 17:01:28 +08:00
2015-10-21 18:22:52 +08:00
UploadLinkShare . objects . filter ( token = token ) . delete ( )
result = { ' success ' : True }
return HttpResponse ( json . dumps ( result ) , content_type = content_type )
2015-10-14 17:01:28 +08:00
2013-09-07 11:44:21 +08:00
@login_required
@sys_staff_required
def user_search ( request ) :
""" Search a user.
"""
email = request . GET . get ( ' email ' , ' ' )
2014-10-10 15:35:47 +08:00
2016-08-20 14:23:28 +08:00
user_emails = [ ]
2016-07-13 11:22:36 +08:00
# search user from ccnet db
2016-08-20 14:23:28 +08:00
users_from_ccnet = ccnet_api . search_emailusers ( ' DB ' , email , - 1 , - 1 )
for user in users_from_ccnet :
user_emails . append ( user . email )
2016-07-13 11:22:36 +08:00
# search user from ccnet ldap
2016-08-20 14:23:28 +08:00
users_from_ldap = ccnet_api . search_emailusers ( ' LDAP ' , email , - 1 , - 1 )
for user in users_from_ldap :
user_emails . append ( user . email )
2015-06-16 10:39:49 +08:00
2016-07-13 11:22:36 +08:00
# search user from profile
users_from_profile = Profile . objects . filter ( ( Q ( nickname__icontains = email ) ) |
Q ( contact_email__icontains = email ) )
for user in users_from_profile :
2016-08-20 14:23:28 +08:00
user_emails . append ( user . user )
# remove duplicate emails
user_emails = { } . fromkeys ( user_emails ) . keys ( )
users = [ ]
for user_email in user_emails :
2016-07-13 11:22:36 +08:00
try :
2016-08-20 14:23:28 +08:00
user_obj = User . objects . get ( email = user_email )
2016-07-13 11:22:36 +08:00
except User . DoesNotExist :
continue
2016-08-20 14:23:28 +08:00
2016-07-13 11:22:36 +08:00
users . append ( user_obj )
2013-11-21 15:05:08 +08:00
last_logins = UserLastLogin . objects . filter ( username__in = [ x . email for x in users ] )
2015-01-16 10:48:47 +08:00
if ENABLE_TRIAL_ACCOUNT :
2015-01-10 12:07:33 +08:00
trial_users = TrialAccount . objects . filter ( user_or_org__in = [ x . email for x in users ] )
2015-01-08 16:23:18 +08:00
else :
trial_users = [ ]
2016-11-01 11:45:32 +08:00
2013-11-21 15:05:08 +08:00
for user in users :
2016-08-08 18:19:00 +08:00
populate_user_info ( user )
2014-12-24 17:35:15 +08:00
_populate_user_quota_usage ( user )
2014-07-23 15:57:25 +08:00
# check user's role
2016-08-22 11:20:08 +08:00
user . is_guest = True if get_user_role ( user ) == GUEST_USER else False
user . is_default = True if get_user_role ( user ) == DEFAULT_USER else False
2013-11-21 15:05:08 +08:00
# populate user last login time
user . last_login = None
for last_login in last_logins :
if last_login . username == user . email :
user . last_login = last_login . last_login
2013-09-07 11:44:21 +08:00
2015-01-08 16:23:18 +08:00
user . trial_info = None
for trial_user in trial_users :
2015-01-10 12:07:33 +08:00
if trial_user . user_or_org == user . email :
2015-01-08 16:23:18 +08:00
user . trial_info = { ' expire_date ' : trial_user . expire_date }
2016-11-01 11:45:32 +08:00
extra_user_roles = [ x for x in get_available_roles ( )
if x not in get_basic_user_roles ( ) ]
2013-09-07 11:44:21 +08:00
return render_to_response ( ' sysadmin/user_search.html ' , {
' users ' : users ,
' email ' : email ,
2014-07-23 15:57:25 +08:00
' default_user ' : DEFAULT_USER ,
' guest_user ' : GUEST_USER ,
2015-06-24 15:08:04 +08:00
' is_pro ' : is_pro_version ( ) ,
2016-08-22 11:20:08 +08:00
' extra_user_roles ' : extra_user_roles ,
2013-09-07 11:44:21 +08:00
} , context_instance = RequestContext ( request ) )
2014-12-24 17:35:15 +08:00
2013-09-23 16:58:33 +08:00
@login_required
@sys_staff_required
2015-09-02 11:14:54 +08:00
@require_POST
2013-09-23 16:58:33 +08:00
def sys_repo_transfer ( request ) :
""" Transfer a repo to others.
"""
repo_id = request . POST . get ( ' repo_id ' , None )
new_owner = request . POST . get ( ' email ' , None )
2013-10-17 11:11:08 +08:00
next = request . META . get ( ' HTTP_REFERER ' , None )
if not next :
2016-07-28 15:54:56 +08:00
next = reverse ( ' sys_repo_admin ' )
2015-02-03 16:39:38 +08:00
if not ( repo_id and new_owner ) :
messages . error ( request , _ ( u ' Failed to transfer, invalid arguments. ' ) )
return HttpResponseRedirect ( next )
repo = seafile_api . get_repo ( repo_id )
if not repo :
messages . error ( request , _ ( u ' Library does not exist ' ) )
return HttpResponseRedirect ( next )
try :
User . objects . get ( email = new_owner )
except User . DoesNotExist :
messages . error ( request , _ ( u ' Failed to transfer, user %s not found ' ) % new_owner )
return HttpResponseRedirect ( next )
2016-08-20 11:12:15 +08:00
if MULTI_TENANCY :
try :
if seafserv_threaded_rpc . get_org_id_by_repo_id ( repo_id ) > 0 :
messages . error ( request , _ ( u ' Can not transfer organization library ' ) )
return HttpResponseRedirect ( next )
2015-02-03 16:39:38 +08:00
2016-08-20 11:12:15 +08:00
if ccnet_api . get_orgs_by_user ( new_owner ) :
messages . error ( request , _ ( u ' Can not transfer library to organization user %s ' ) % new_owner )
return HttpResponseRedirect ( next )
except Exception as e :
logger . error ( e )
messages . error ( request , ' Internal Server Error ' )
2015-02-03 16:39:38 +08:00
return HttpResponseRedirect ( next )
2016-06-24 11:10:26 +08:00
repo_owner = seafile_api . get_repo_owner ( repo_id )
2016-06-29 15:17:48 +08:00
# get repo shared to user/group list
2016-06-24 11:10:26 +08:00
shared_users = seafile_api . list_repo_shared_to (
repo_owner , repo_id )
shared_groups = seafile_api . list_repo_shared_group_by_user (
repo_owner , repo_id )
2016-06-29 15:17:48 +08:00
# get all pub repos
2016-08-18 17:49:12 +08:00
pub_repos = [ ]
if not request . cloud_mode :
pub_repos = seafile_api . list_inner_pub_repos_by_owner ( repo_owner )
2016-06-24 11:10:26 +08:00
# transfer repo
2015-02-03 16:39:38 +08:00
seafile_api . set_repo_owner ( repo_id , new_owner )
2015-09-25 16:03:51 +08:00
2016-06-29 15:17:48 +08:00
# reshare repo to user
2016-06-24 11:10:26 +08:00
for shared_user in shared_users :
shared_username = shared_user . user
if new_owner == shared_username :
continue
seafile_api . share_repo ( repo_id , new_owner ,
shared_username , shared_user . perm )
2016-06-29 15:17:48 +08:00
# reshare repo to group
2016-06-24 11:10:26 +08:00
for shared_group in shared_groups :
shared_group_id = shared_group . group_id
if not ccnet_api . is_group_user ( shared_group_id , new_owner ) :
continue
seafile_api . set_group_repo ( repo_id , shared_group_id ,
new_owner , shared_group . perm )
2016-06-29 15:17:48 +08:00
# check if current repo is pub-repo
# if YES, reshare current repo to public
2016-06-24 11:10:26 +08:00
for pub_repo in pub_repos :
if repo_id != pub_repo . id :
continue
2016-08-20 11:12:15 +08:00
seafile_api . add_inner_pub_repo ( repo_id , pub_repo . permission )
2016-06-24 11:10:26 +08:00
break
2015-02-03 16:39:38 +08:00
messages . success ( request , _ ( u ' Successfully transfered. ' ) )
2013-10-17 11:11:08 +08:00
return HttpResponseRedirect ( next )
2014-12-25 17:17:29 +08:00
2015-09-25 16:03:51 +08:00
@login_required
@sys_staff_required
@require_POST
def sys_repo_delete ( request , repo_id ) :
""" Delete a repo.
"""
next = request . META . get ( ' HTTP_REFERER ' , None )
if not next :
2016-07-28 15:54:56 +08:00
next = reverse ( ' sys_repo_admin ' )
2015-09-25 16:03:51 +08:00
if get_system_default_repo_id ( ) == repo_id :
messages . error ( request , _ ( ' System library can not be deleted. ' ) )
return HttpResponseRedirect ( next )
repo = seafile_api . get_repo ( repo_id )
2015-12-04 11:15:34 +08:00
if repo : # Handle the case that repo is `None`.
repo_name = repo . name
else :
repo_name = ' '
2015-09-25 16:03:51 +08:00
2015-09-28 15:08:35 +08:00
if MULTI_TENANCY :
org_id = seafserv_threaded_rpc . get_org_id_by_repo_id ( repo_id )
2015-09-25 16:03:51 +08:00
usernames = get_related_users_by_org_repo ( org_id , repo_id )
repo_owner = seafile_api . get_org_repo_owner ( repo_id )
else :
2015-09-28 15:08:35 +08:00
org_id = - 1
2015-09-25 16:03:51 +08:00
usernames = get_related_users_by_repo ( repo_id )
repo_owner = seafile_api . get_repo_owner ( repo_id )
seafile_api . remove_repo ( repo_id )
repo_deleted . send ( sender = None , org_id = org_id , usernames = usernames ,
repo_owner = repo_owner , repo_id = repo_id ,
repo_name = repo_name )
messages . success ( request , _ ( u ' Successfully deleted. ' ) )
return HttpResponseRedirect ( next )
2014-02-26 18:24:34 +08:00
@login_required
@sys_staff_required
def sys_traffic_admin ( request ) :
""" List all users from database.
"""
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
month = request . GET . get ( ' month ' , ' ' )
if not re . match ( r ' [ \ d] {6} ' , month ) :
month = datetime . datetime . now ( ) . strftime ( ' % Y % m ' )
start = per_page * ( current_page - 1 )
limit = per_page + 1
traffic_info_list = get_user_traffic_list ( month , start , limit )
page_next = len ( traffic_info_list ) == limit
for info in traffic_info_list :
info [ ' total ' ] = info [ ' file_view ' ] + info [ ' file_download ' ] + info [ ' dir_download ' ]
return render_to_response (
' sysadmin/sys_trafficadmin.html ' , {
' traffic_info_list ' : traffic_info_list ,
' month ' : month ,
' 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 ) )
2014-04-03 15:19:09 +08:00
2015-08-17 11:20:00 +08:00
@login_required
@sys_staff_required
def sys_virus_scan_records ( request ) :
""" List virus scan records.
"""
try :
current_page = int ( request . GET . get ( ' page ' , ' 1 ' ) )
per_page = int ( request . GET . get ( ' per_page ' , ' 100 ' ) )
except ValueError :
current_page = 1
per_page = 100
records_all = get_virus_record ( start = per_page * ( current_page - 1 ) ,
limit = per_page + 1 )
if len ( records_all ) == per_page + 1 :
page_next = True
else :
page_next = False
records = [ ]
for r in records_all [ : per_page ] :
try :
2015-11-18 10:18:34 +08:00
repo = seafile_api . get_repo ( r . repo_id )
except SearpcError as e :
logger . error ( e )
continue
if not repo :
2015-08-17 11:20:00 +08:00
continue
2015-11-18 10:18:34 +08:00
r . repo = repo
2015-08-17 11:20:00 +08:00
r . repo . owner = seafile_api . get_repo_owner ( r . repo . repo_id )
records . append ( r )
return render_to_response (
' sysadmin/sys_virus_scan_records.html ' , {
' records ' : records ,
' 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 ) )
2015-10-22 15:40:15 +08:00
@login_required
2015-08-17 11:20:00 +08:00
@sys_staff_required
2015-10-21 18:22:52 +08:00
@require_POST
2015-08-17 11:20:00 +08:00
def sys_delete_virus_scan_records ( request , vid ) :
r = get_virus_record_by_id ( vid )
parent_dir = os . path . dirname ( r . file_path )
dirent_name = os . path . basename ( r . file_path )
try :
seafile_api . del_file ( r . repo_id , parent_dir , dirent_name ,
request . user . username )
handle_virus_record ( vid )
2015-10-22 15:40:15 +08:00
messages . success ( request , _ ( ' Successfully deleted. ' ) )
2015-08-17 11:20:00 +08:00
except SearpcError as e :
logger . error ( e )
2015-10-22 15:40:15 +08:00
messages . error ( request , _ ( ' Failed to delete, please try again later. ' ) )
return HttpResponseRedirect ( reverse ( ' sys_virus_scan_records ' ) )
2015-08-17 11:20:00 +08:00
2014-07-01 15:21:49 +08:00
@login_required_ajax
2014-04-03 15:19:09 +08:00
@sys_staff_required
def batch_user_make_admin ( request ) :
2014-04-16 17:39:23 +08:00
""" Batch make users as admins.
"""
2014-07-01 15:21:49 +08:00
if request . method != ' POST ' :
2014-04-16 11:47:53 +08:00
raise Http404
2014-04-03 15:19:09 +08:00
content_type = ' application/json; charset=utf-8 '
set_admin_emails = request . POST . get ( ' set_admin_emails ' )
set_admin_emails = string2list ( set_admin_emails )
2014-04-03 17:31:43 +08:00
success = [ ]
failed = [ ]
for email in set_admin_emails :
try :
2014-04-03 15:19:09 +08:00
user = User . objects . get ( email = email )
2014-04-03 17:31:43 +08:00
except User . DoesNotExist :
failed . append ( email )
2015-01-10 18:13:47 +08:00
continue
2015-06-26 14:05:39 +08:00
user . is_staff = True
user . save ( )
2015-01-10 18:13:47 +08:00
success . append ( email )
for item in success :
2014-04-16 17:39:23 +08:00
messages . success ( request , _ ( u ' Successfully set %s as admin. ' ) % item )
2014-04-03 17:31:43 +08:00
for item in failed :
2014-04-16 17:39:23 +08:00
messages . error ( request , _ ( u ' Failed to set %s as admin: user does not exist. ' ) % item )
2014-04-03 17:31:43 +08:00
2015-01-10 18:13:47 +08:00
return HttpResponse ( json . dumps ( { ' success ' : True , } ) , content_type = content_type )
2014-05-09 17:12:25 +08:00
@login_required
@sys_staff_required
def batch_add_user ( request ) :
2014-05-16 17:43:36 +08:00
""" Batch add users. Import users from CSV file.
"""
2014-05-09 17:12:25 +08:00
if request . method != ' POST ' :
raise Http404
2016-11-05 12:09:58 +08:00
next = request . META . get ( ' HTTP_REFERER ' , reverse ( sys_user_admin ) )
2014-05-16 17:43:36 +08:00
form = BatchAddUserForm ( request . POST , request . FILES )
if form . is_valid ( ) :
content = request . FILES [ ' file ' ] . read ( )
2014-05-09 17:12:25 +08:00
encoding = chardet . detect ( content ) [ ' encoding ' ]
if encoding != ' utf-8 ' :
content = content . decode ( encoding , ' replace ' ) . encode ( ' utf-8 ' )
filestream = StringIO . StringIO ( content )
2016-11-05 12:09:58 +08:00
2014-05-16 17:43:36 +08:00
reader = csv . reader ( filestream )
2016-11-05 12:09:58 +08:00
new_users_count = len ( list ( reader ) )
if user_number_over_limit ( new_users = new_users_count ) :
messages . error ( request , _ ( u ' The number of users exceeds the limit. ' ) )
return HttpResponseRedirect ( next )
2014-05-09 17:12:25 +08:00
2016-11-05 12:09:58 +08:00
# return to the top of the file
filestream . seek ( 0 )
reader = csv . reader ( filestream )
2014-05-16 17:43:36 +08:00
for row in reader :
if not row :
continue
2014-05-09 17:12:25 +08:00
2014-05-16 17:43:36 +08:00
username = row [ 0 ] . strip ( )
password = row [ 1 ] . strip ( )
2014-05-09 17:12:25 +08:00
2016-12-21 11:41:32 +08:00
# nickname & department are optional
try :
nickname = row [ 2 ] . strip ( )
except IndexError :
nickname = ' '
try :
department = row [ 3 ] . strip ( )
except IndexError :
department = ' '
2014-05-16 17:43:36 +08:00
if not is_valid_username ( username ) :
continue
2014-05-09 17:12:25 +08:00
2014-05-16 17:43:36 +08:00
if password == ' ' :
continue
2014-05-09 17:12:25 +08:00
2016-12-21 11:41:32 +08:00
if nickname :
if len ( nickname ) > 64 or ' / ' in nickname :
continue
if department :
if len ( department ) > 512 :
continue
2014-05-16 17:43:36 +08:00
try :
User . objects . get ( email = username )
continue
except User . DoesNotExist :
User . objects . create_user ( username , password , is_staff = False ,
is_active = True )
2015-11-26 17:24:50 +08:00
2016-12-21 11:41:32 +08:00
if nickname :
Profile . objects . add_or_update ( username , nickname , ' ' )
if department :
DetailedProfile . objects . add_or_update ( username , department , ' ' )
2015-11-26 17:24:50 +08:00
send_html_email_with_dj_template (
username , dj_template = ' sysadmin/user_batch_add_email.html ' ,
subject = _ ( u ' You are invited to join %s ' ) % SITE_NAME ,
context = {
' user ' : email2nickname ( request . user . username ) ,
' email ' : username ,
' password ' : password ,
} )
2014-06-17 17:08:43 +08:00
messages . success ( request , _ ( ' Import succeeded ' ) )
2014-05-09 17:12:25 +08:00
else :
messages . error ( request , _ ( u ' Please select a csv file first. ' ) )
return HttpResponseRedirect ( next )
2015-05-04 13:57:10 +08:00
@login_required
def sys_sudo_mode ( request ) :
if request . method not in ( ' GET ' , ' POST ' ) :
return HttpResponseNotAllowed
# here we can't use @sys_staff_required
if not request . user . is_staff :
2015-10-19 18:01:55 +08:00
raise Http404
2015-05-04 13:57:10 +08:00
password_error = False
if request . method == ' POST ' :
password = request . POST . get ( ' password ' )
if password :
user = authenticate ( username = request . user . username , password = password )
2015-05-05 13:34:03 +08:00
if user :
update_sudo_mode_ts ( request )
return HttpResponseRedirect (
request . GET . get ( ' next ' , reverse ( ' sys_useradmin ' ) ) )
2015-05-04 13:57:10 +08:00
password_error = True
2015-05-05 13:34:03 +08:00
enable_shib_login = getattr ( settings , ' ENABLE_SHIB_LOGIN ' , False )
2015-05-04 13:57:10 +08:00
return render_to_response (
' sysadmin/sudo_mode.html ' , {
2015-05-05 13:34:03 +08:00
' password_error ' : password_error ,
' enable_shib_login ' : enable_shib_login ,
2015-05-04 13:57:10 +08:00
} ,
context_instance = RequestContext ( request ) )
2015-08-07 16:08:45 +08:00
@login_required
@sys_staff_required
def sys_settings ( request ) :
""" List and change seahub settings in admin panel.
"""
2016-05-27 10:32:36 +08:00
if not dj_settings . ENABLE_SETTINGS_VIA_WEB :
2016-05-26 15:55:57 +08:00
raise Http404
2015-08-07 16:08:45 +08:00
2016-04-15 09:08:22 +08:00
DIGIT_WEB_SETTINGS = [
2016-01-21 13:55:52 +08:00
' DISABLE_SYNC_WITH_ANY_FOLDER ' , ' ENABLE_SIGNUP ' ,
2015-09-21 11:48:07 +08:00
' ACTIVATE_AFTER_REGISTRATION ' , ' REGISTRATION_SEND_MAIL ' ,
' LOGIN_REMEMBER_DAYS ' , ' REPO_PASSWORD_MIN_LENGTH ' ,
' ENABLE_REPO_HISTORY_SETTING ' , ' USER_STRONG_PASSWORD_REQUIRED ' ,
2015-10-09 15:40:54 +08:00
' ENABLE_ENCRYPTED_LIBRARY ' , ' USER_PASSWORD_MIN_LENGTH ' ,
2016-01-21 13:55:52 +08:00
' USER_PASSWORD_STRENGTH_LEVEL ' , ' SHARE_LINK_PASSWORD_MIN_LENGTH ' ,
2016-04-19 15:33:48 +08:00
' ENABLE_USER_CREATE_ORG_REPO ' , ' FORCE_PASSWORD_CHANGE ' ,
' LOGIN_ATTEMPT_LIMIT ' , ' FREEZE_USER_ON_LOGIN_FAILED ' ,
2016-04-15 09:08:22 +08:00
]
if HAS_TWO_FACTOR_AUTH :
DIGIT_WEB_SETTINGS . append ( ' ENABLE_TWO_FACTOR_AUTH ' )
2015-09-21 11:48:07 +08:00
STRING_WEB_SETTINGS = ( ' SERVICE_URL ' , ' FILE_SERVER_ROOT ' , )
if request . is_ajax ( ) and request . method == " POST " :
content_type = ' application/json; charset=utf-8 '
result = { }
2015-08-07 16:08:45 +08:00
2015-09-21 11:48:07 +08:00
key = request . POST . get ( ' key ' , None )
value = request . POST . get ( ' value ' , None )
if key not in dir ( config ) or value is None :
result [ ' error ' ] = _ ( u ' Invalid setting ' )
return HttpResponse ( json . dumps ( result ) , status = 400 , content_type = content_type )
if value . isdigit ( ) :
if key in DIGIT_WEB_SETTINGS :
value = int ( value )
else :
result [ ' error ' ] = _ ( u ' Invalid value ' )
return HttpResponse ( json . dumps ( result ) , status = 400 , content_type = content_type )
2015-10-09 10:33:29 +08:00
if key == ' USER_PASSWORD_STRENGTH_LEVEL ' and value not in ( 1 , 2 , 3 , 4 ) :
result [ ' error ' ] = _ ( u ' Invalid value ' )
return HttpResponse ( json . dumps ( result ) , status = 400 , content_type = content_type )
2015-09-21 11:48:07 +08:00
else :
if key not in STRING_WEB_SETTINGS :
result [ ' error ' ] = _ ( u ' Invalid value ' )
return HttpResponse ( json . dumps ( result ) , status = 400 , content_type = content_type )
try :
setattr ( config , key , value )
result [ ' success ' ] = True
return HttpResponse ( json . dumps ( result ) , content_type = content_type )
except AttributeError as e :
logger . error ( e )
result [ ' error ' ] = _ ( u ' Internal server error ' )
return HttpResponse ( json . dumps ( result ) , status = 500 , content_type = content_type )
2015-08-07 16:08:45 +08:00
config_dict = { }
2015-09-21 11:48:07 +08:00
for key in dir ( config ) :
value = getattr ( config , key )
config_dict [ key ] = value
2015-08-07 16:08:45 +08:00
return render_to_response ( ' sysadmin/settings.html ' , {
' config_dict ' : config_dict ,
2016-04-15 09:08:22 +08:00
' has_two_factor_auth ' : HAS_TWO_FACTOR_AUTH ,
2015-08-07 16:08:45 +08:00
} , context_instance = RequestContext ( request ) )
2015-10-24 15:53:02 +08:00
@login_required_ajax
@sys_staff_required
def sys_check_license ( request ) :
""" Check seafile license expiration.
"""
if not is_pro_version ( ) :
raise Http404
content_type = ' application/json; charset=utf-8 '
result = { }
2016-11-05 12:09:58 +08:00
license_dict = parse_license ( )
2015-10-24 15:53:02 +08:00
if license_dict :
try :
expiration = license_dict [ ' Expiration ' ]
except KeyError as e :
logger . error ( e )
result [ ' error ' ] = str ( e )
return HttpResponse ( json . dumps ( result ) , status = 500 , content_type = content_type )
struct_time = datetime . datetime . strptime ( expiration , " % Y- % m- %d " )
expiration_timestamp = time . mktime ( struct_time . timetuple ( ) )
if time . time ( ) > expiration_timestamp :
# already expired
result [ ' already_expired ' ] = True
elif time . time ( ) + 30 * 24 * 60 * 60 > expiration_timestamp :
# will be expired in 30 days
result [ ' to_be_expired ' ] = True
2015-10-24 18:14:58 +08:00
result [ ' expiration_date ' ] = expiration
2015-10-24 15:53:02 +08:00
return HttpResponse ( json . dumps ( result ) , content_type = content_type )
2016-03-13 09:42:40 +08:00
@login_required
@sys_staff_required
def sys_inst_admin ( request ) :
""" List institutions.
"""
if request . method == " POST " :
inst_name = request . POST . get ( ' name ' ) . strip ( )
if not inst_name :
messages . error ( request , ' Name is required. ' )
return HttpResponseRedirect ( reverse ( ' sys_inst_admin ' ) )
Institution . objects . create ( name = inst_name )
messages . success ( request , _ ( ' Success ' ) )
return HttpResponseRedirect ( reverse ( ' sys_inst_admin ' ) )
# 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 ' , ' 100 ' ) )
except ValueError :
current_page = 1
per_page = 100
offset = per_page * ( current_page - 1 )
2016-04-09 11:34:35 +08:00
insts = Institution . objects . all ( ) [ offset : offset + per_page + 1 ]
2016-03-13 09:42:40 +08:00
if len ( insts ) == per_page + 1 :
page_next = True
else :
page_next = False
return render_to_response (
' sysadmin/sys_inst_admin.html ' , {
2016-04-09 11:34:35 +08:00
' insts ' : insts [ : per_page ] ,
2016-03-13 09:42:40 +08:00
' 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
@require_POST
def sys_inst_remove ( request , inst_id ) :
""" Delete an institution.
"""
try :
inst = Institution . objects . get ( pk = inst_id )
except Institution . DoesNotExist :
raise Http404
inst . delete ( )
messages . success ( request , _ ( ' Success ' ) )
return HttpResponseRedirect ( reverse ( ' sys_inst_admin ' ) )
@login_required
@sys_staff_required
def sys_inst_info_user ( request , inst_id ) :
2016-06-08 15:39:12 +08:00
""" List institution members including admins.
2016-03-13 09:42:40 +08:00
"""
try :
inst = Institution . objects . get ( pk = inst_id )
except Institution . DoesNotExist :
raise Http404
2016-04-09 11:34:35 +08:00
# Make sure page request is an int. If not, deliver first page.
try :
current_page = int ( request . GET . get ( ' page ' , ' 1 ' ) )
2016-04-09 11:44:39 +08:00
per_page = int ( request . GET . get ( ' per_page ' , ' 100 ' ) )
2016-04-09 11:34:35 +08:00
except ValueError :
current_page = 1
2016-04-09 11:44:39 +08:00
per_page = 100
2016-04-09 11:34:35 +08:00
offset = per_page * ( current_page - 1 )
2016-03-13 09:42:40 +08:00
inst_admins = [ x . user for x in InstitutionAdmin . objects . filter ( institution = inst ) ]
2016-04-09 11:34:35 +08:00
usernames = [ x . user for x in Profile . objects . filter ( institution = inst . name ) [ offset : offset + per_page + 1 ] ]
if len ( usernames ) == per_page + 1 :
page_next = True
else :
page_next = False
users = [ User . objects . get ( x ) for x in usernames [ : per_page ] ]
2016-03-13 09:42:40 +08:00
last_logins = UserLastLogin . objects . filter ( username__in = [ x . email for x in users ] )
for u in users :
_populate_user_quota_usage ( u )
if u . username in inst_admins :
u . inst_admin = True
else :
u . inst_admin = False
# populate user last login time
u . last_login = None
for last_login in last_logins :
if last_login . username == u . email :
u . last_login = last_login . last_login
2016-06-08 15:39:12 +08:00
users_count = Profile . objects . filter ( institution = inst . name ) . count ( )
2016-03-13 09:42:40 +08:00
return render_to_response ( ' sysadmin/sys_inst_info_user.html ' , {
' inst ' : inst ,
' users ' : users ,
' users_count ' : users_count ,
2016-04-09 11:34:35 +08:00
' current_page ' : current_page ,
' prev_page ' : current_page - 1 ,
' next_page ' : current_page + 1 ,
' per_page ' : per_page ,
' page_next ' : page_next ,
2016-03-13 09:42:40 +08:00
} , context_instance = RequestContext ( request ) )
2016-06-08 15:39:12 +08:00
@login_required
@sys_staff_required
def sys_inst_search_user ( request , inst_id ) :
""" Search institution members.
"""
try :
inst = Institution . objects . get ( pk = inst_id )
except Institution . DoesNotExist :
raise Http404
q = request . GET . get ( ' q ' , ' ' ) . lower ( )
if not q :
return HttpResponseRedirect ( reverse ( ' sys_inst_info_users ' , args = [ inst_id ] ) )
profiles = Profile . objects . filter ( institution = inst . name )
usernames = [ x . user for x in profiles if q in x . user ]
users = [ User . objects . get ( x ) for x in usernames ]
inst_admins = [ x . user for x in InstitutionAdmin . objects . filter ( institution = inst ) ]
last_logins = UserLastLogin . objects . filter ( username__in = [ x for x in users ] )
for u in users :
_populate_user_quota_usage ( u )
if u . username in inst_admins :
u . inst_admin = True
else :
u . inst_admin = False
# populate user last login time
u . last_login = None
for last_login in last_logins :
if last_login . username == u . email :
u . last_login = last_login . last_login
users_count = Profile . objects . filter ( institution = inst . name ) . count ( )
return render_to_response ( ' sysadmin/sys_inst_search_user.html ' , {
' q ' : q ,
' inst ' : inst ,
' users ' : users ,
' users_count ' : users_count ,
} , context_instance = RequestContext ( request ) )
@login_required
@sys_staff_required
def sys_inst_info_admins ( request , inst_id ) :
""" List institution admins.
"""
try :
inst = Institution . objects . get ( pk = inst_id )
except Institution . DoesNotExist :
raise Http404
inst_admins = [ x . user for x in InstitutionAdmin . objects . filter ( institution = inst ) ]
admins = [ User . objects . get ( x ) for x in inst_admins ]
last_logins = UserLastLogin . objects . filter ( username__in = [ x . email for x in admins ] )
for u in admins :
_populate_user_quota_usage ( u )
# populate user last login time
u . last_login = None
for last_login in last_logins :
if last_login . username == u . email :
u . last_login = last_login . last_login
users_count = Profile . objects . filter ( institution = inst . name ) . count ( )
return render_to_response ( ' sysadmin/sys_inst_info_admins.html ' , {
' inst ' : inst ,
' admins ' : admins ,
' users_count ' : users_count ,
} , context_instance = RequestContext ( request ) )
2016-03-13 09:42:40 +08:00
@login_required
@sys_staff_required
@require_POST
def sys_inst_toggle_admin ( request , inst_id , email ) :
""" Set or revoke an institution admin.
"""
try :
inst = Institution . objects . get ( pk = inst_id )
except Institution . DoesNotExist :
raise Http404
2016-06-08 15:39:12 +08:00
next = request . META . get ( ' HTTP_REFERER ' , None )
if not next :
next = reverse ( ' sys_inst_info_users ' , args = [ inst . pk ] )
2016-03-13 09:42:40 +08:00
try :
u = User . objects . get ( email = email )
except User . DoesNotExist :
assert False , ' TODO '
if u . is_staff :
2016-06-08 15:39:12 +08:00
messages . error (
request , ' Can not assign institutional administration roles to global administrators ' )
return HttpResponseRedirect ( next )
2016-03-13 09:42:40 +08:00
res = InstitutionAdmin . objects . filter ( institution = inst , user = email )
if len ( res ) == 0 :
InstitutionAdmin . objects . create ( institution = inst , user = email )
elif len ( res ) == 1 :
res [ 0 ] . delete ( )
# todo: expire user's session
else :
assert False
messages . success ( request , _ ( ' Success ' ) )
2016-06-08 15:39:12 +08:00
return HttpResponseRedirect ( next )
2016-05-13 15:34:49 +08:00
@login_required
@sys_staff_required
def sys_invitation_admin ( request ) :
""" List all invitations .
"""
2016-07-20 15:30:39 +08:00
if not ENABLE_GUEST_INVITATION :
raise Http404
2016-05-13 15:34:49 +08:00
# 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 ' , ' 100 ' ) )
except ValueError :
current_page = 1
per_page = 100
offset = per_page * ( current_page - 1 )
limit = per_page + 1
2016-07-20 15:30:39 +08:00
invitations = Invitation . objects . all ( ) . order_by ( ' -invite_time ' ) [ offset : offset + limit ]
2016-05-13 15:34:49 +08:00
if len ( invitations ) == per_page + 1 :
page_next = True
else :
page_next = False
return render_to_response (
' sysadmin/sys_invitations_admin.html ' , {
' invitations ' : invitations ,
' 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 ) )
2016-07-18 13:04:05 +08:00
@login_required
@sys_staff_required
def sys_terms_admin ( request ) :
""" List Terms and Conditions """
if request . method == " POST " :
content_type = ' application/json; charset=utf-8 '
form = TermsAndConditionsForm ( request . POST )
if form . is_valid ( ) :
name = form . cleaned_data [ ' name ' ]
version_number = form . cleaned_data [ ' version_number ' ]
text = form . cleaned_data [ ' text ' ]
enabled = True if request . POST . get ( ' status ' , ' 0 ' ) == ' 1 ' else False
if enabled :
date_active = timezone . now ( )
else :
date_active = None
pk = request . POST . get ( ' pk ' , None )
if not pk : # create
t_c = TermsAndConditions . objects . create (
name = name , version_number = version_number , text = text ,
date_active = date_active )
else : # update
t_c = TermsAndConditions . objects . get ( pk = pk )
t_c . text = text
t_c . version_number = version_number
t_c . name = name
t_c . date_active = date_active
t_c . save ( )
return HttpResponse ( json . dumps ( { ' success ' : True } ) ,
content_type = content_type )
else :
return HttpResponse ( json . dumps ( {
' error ' : str ( form . errors . values ( ) [ 0 ] )
} ) , status = 400 , content_type = content_type )
tc_list = TermsAndConditions . objects . all ( ) . order_by ( ' -date_created ' )
return render_to_response ( ' sysadmin/sys_terms_admin.html ' , {
' object_list ' : tc_list ,
} , context_instance = RequestContext ( request ) )
@login_required
@sys_staff_required
@require_POST
def sys_delete_terms ( request , pk ) :
TermsAndConditions . objects . filter ( pk = pk ) . delete ( )
2016-07-26 15:03:15 +08:00
messages . success ( request , _ ( ' Successfully deleted 1 item ' ) )
2016-07-18 13:04:05 +08:00
return HttpResponseRedirect ( reverse ( ' sys_terms_admin ' ) )