mirror of
https://github.com/haiwen/seahub.git
synced 2025-07-31 14:52:38 +00:00
add sysadmin import users api (#4202)
This commit is contained in:
parent
0f95a6bae3
commit
a53dd2ecb0
@ -1,6 +1,10 @@
|
||||
# Copyright (c) 2012-2016 Seafile Ltd.
|
||||
|
||||
import logging
|
||||
from io import BytesIO
|
||||
from openpyxl import load_workbook
|
||||
from constance import config
|
||||
|
||||
from rest_framework import status
|
||||
from rest_framework.authentication import SessionAuthentication
|
||||
from rest_framework.permissions import IsAdminUser
|
||||
@ -11,6 +15,7 @@ from django.utils.translation import ugettext as _
|
||||
|
||||
from seaserv import seafile_api
|
||||
|
||||
import seahub.settings as settings
|
||||
from seahub.api2.authentication import TokenAuthentication
|
||||
from seahub.api2.throttling import UserRateThrottle
|
||||
from seahub.api2.utils import api_error
|
||||
@ -19,14 +24,21 @@ from seahub.base.accounts import User
|
||||
from seahub.profile.models import Profile
|
||||
from seahub.institutions.models import Institution
|
||||
from seahub.utils.file_size import get_file_size_unit
|
||||
from seahub.utils import is_valid_username
|
||||
from seahub.admin_log.models import USER_DELETE
|
||||
from seahub.utils import is_valid_username, get_file_type_and_ext, \
|
||||
is_pro_version, get_site_name
|
||||
from seahub.utils.error_msg import file_type_error_msg
|
||||
from seahub.utils.licenseparse import user_number_over_limit
|
||||
from seahub.utils.mail import send_html_email_with_dj_template
|
||||
from seahub.admin_log.models import USER_DELETE, USER_ADD
|
||||
from seahub.admin_log.signals import admin_operation
|
||||
from seahub.utils.timeutils import timestamp_to_isoformat_timestr, datetime_to_isoformat_timestr
|
||||
from seahub.constants import DEFAULT_ADMIN
|
||||
from seahub.role_permissions.models import AdminRole
|
||||
from seahub.base.templatetags.seahub_tags import email2nickname, email2contact_email
|
||||
from seahub.base.models import UserLastLogin
|
||||
from seahub.options.models import UserOptions
|
||||
from seahub.role_permissions.utils import get_available_roles
|
||||
from seahub.utils.user_permissions import get_user_role
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -227,3 +239,161 @@ class AdminUsersBatch(APIView):
|
||||
})
|
||||
|
||||
return Response(result)
|
||||
|
||||
|
||||
class AdminImportUsers(APIView):
|
||||
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
||||
throttle_classes = (UserRateThrottle,)
|
||||
permission_classes = (IsAdminUser,)
|
||||
|
||||
def post(self, request):
|
||||
""" Import users from xlsx file
|
||||
|
||||
Permission checking:
|
||||
1. admin user.
|
||||
"""
|
||||
xlsx_file = request.FILES.get('file', None)
|
||||
if not xlsx_file:
|
||||
error_msg = 'file can not be found.'
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||
|
||||
file_type, ext = get_file_type_and_ext(xlsx_file.name)
|
||||
if ext != 'xlsx':
|
||||
error_msg = file_type_error_msg(ext, 'xlsx')
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||
|
||||
content = xlsx_file.read()
|
||||
|
||||
try:
|
||||
fs = BytesIO(content)
|
||||
wb = load_workbook(filename=fs, read_only=True)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
|
||||
# example file is like:
|
||||
# Email Password Name(Optional) Role(Optional) Space Quota(MB, Optional)
|
||||
# a@a.com a a default 1024
|
||||
# b@b.com b b default 2048
|
||||
|
||||
rows = wb.worksheets[0].rows
|
||||
records = []
|
||||
# skip first row(head field).
|
||||
next(rows)
|
||||
for row in rows:
|
||||
records.append([col.value for col in row])
|
||||
|
||||
if user_number_over_limit(new_users=len(records)):
|
||||
error_msg = 'The number of users exceeds the limit.'
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||
|
||||
result = {}
|
||||
result['failed'] = []
|
||||
result['success'] = []
|
||||
for record in records:
|
||||
if record[0]:
|
||||
email = record[0].strip()
|
||||
if not is_valid_username(email):
|
||||
result['failed'].append({
|
||||
'email': email,
|
||||
'error_msg': 'email %s invalid.' % email
|
||||
})
|
||||
continue
|
||||
else:
|
||||
result['failed'].append({
|
||||
'email': '',
|
||||
'error_msg': 'email invalid.'
|
||||
})
|
||||
continue
|
||||
|
||||
if record[1]:
|
||||
password = record[1].strip()
|
||||
if not password:
|
||||
result['failed'].append({
|
||||
'email': email,
|
||||
'error_msg': 'password invalid.'
|
||||
})
|
||||
continue
|
||||
else:
|
||||
result['failed'].append({
|
||||
'email': email,
|
||||
'error_msg': 'password invalid.'
|
||||
})
|
||||
continue
|
||||
|
||||
try:
|
||||
User.objects.get(email=email)
|
||||
result['failed'].append({
|
||||
'email': email,
|
||||
'error_msg': 'user %s exists.' % email
|
||||
})
|
||||
continue
|
||||
except User.DoesNotExist:
|
||||
pass
|
||||
|
||||
User.objects.create_user(email, password, is_staff=False, is_active=True)
|
||||
if config.FORCE_PASSWORD_CHANGE:
|
||||
UserOptions.objects.set_force_passwd_change(email)
|
||||
|
||||
# update the user's optional info
|
||||
# update nikename
|
||||
if record[2]:
|
||||
try:
|
||||
nickname = record[2].strip()
|
||||
if len(nickname) <= 64 and '/' not in nickname:
|
||||
Profile.objects.add_or_update(email, nickname, '')
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
# update role
|
||||
if record[3]:
|
||||
try:
|
||||
role = record[3].strip()
|
||||
if is_pro_version() and role in get_available_roles():
|
||||
User.objects.update_role(email, role)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
# update quota
|
||||
if record[4]:
|
||||
try:
|
||||
space_quota_mb = int(record[4])
|
||||
if space_quota_mb >= 0:
|
||||
space_quota = int(space_quota_mb) * get_file_size_unit('MB')
|
||||
seafile_api.set_user_quota(email, space_quota)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
|
||||
send_html_email_with_dj_template(
|
||||
email, dj_template='sysadmin/user_batch_add_email.html',
|
||||
subject=_('You are invited to join %s') % get_site_name(),
|
||||
context={
|
||||
'user': email2nickname(request.user.username),
|
||||
'email': email,
|
||||
'password': password,
|
||||
})
|
||||
|
||||
user = User.objects.get(email=email)
|
||||
|
||||
info = {}
|
||||
info['email'] = email
|
||||
info['name'] = email2nickname(email)
|
||||
info['contact_email'] = email2contact_email(email)
|
||||
|
||||
info['is_staff'] = user.is_staff
|
||||
info['is_active'] = user.is_active
|
||||
|
||||
info['quota_usage'] = seafile_api.get_user_self_usage(user.email)
|
||||
info['quota_total'] = seafile_api.get_user_quota(user.email)
|
||||
|
||||
info['create_time'] = timestamp_to_isoformat_timestr(user.ctime)
|
||||
|
||||
info['role'] = get_user_role(user)
|
||||
result['success'].append(info)
|
||||
|
||||
# send admin operation log signal
|
||||
admin_op_detail = {
|
||||
"email": email,
|
||||
}
|
||||
admin_operation.send(sender=None, admin_name=request.user.username,
|
||||
operation=USER_ADD, detail=admin_op_detail)
|
||||
|
||||
return Response(result)
|
||||
|
||||
|
@ -125,7 +125,8 @@ from seahub.api2.endpoints.admin.share_links import AdminShareLinks, AdminShareL
|
||||
AdminShareLinkDirents
|
||||
from seahub.api2.endpoints.admin.upload_links import AdminUploadLinks, AdminUploadLink, \
|
||||
AdminUploadLinkUpload, AdminUploadLinkCheckPassword
|
||||
from seahub.api2.endpoints.admin.users_batch import AdminUsersBatch, AdminAdminUsersBatch
|
||||
from seahub.api2.endpoints.admin.users_batch import AdminUsersBatch, AdminAdminUsersBatch, \
|
||||
AdminImportUsers
|
||||
from seahub.api2.endpoints.admin.operation_logs import AdminOperationLogs
|
||||
from seahub.api2.endpoints.admin.organizations import AdminOrganizations, AdminOrganization
|
||||
from seahub.api2.endpoints.admin.org_users import AdminOrgUsers, AdminOrgUser
|
||||
@ -527,9 +528,10 @@ urlpatterns = [
|
||||
url(r'^api/v2.1/admin/upload-links/(?P<token>[a-f0-9]+)/check-password/$',
|
||||
AdminUploadLinkCheckPassword.as_view(), name='api-v2.1-admin-upload-link-check-password'),
|
||||
|
||||
## admin::users
|
||||
## admin::users-batch
|
||||
url(r'^api/v2.1/admin/admin-users/batch/$', AdminAdminUsersBatch.as_view(), name='api-v2.1-admin-users-batch'),
|
||||
url(r'^api/v2.1/admin/users/batch/$', AdminUsersBatch.as_view(), name='api-v2.1-admin-users-batch'),
|
||||
url(r'^api/v2.1/admin/import-users/$', AdminImportUsers.as_view(), name='api-v2.1-admin-import-users'),
|
||||
|
||||
## admin::admin-role
|
||||
url(r'^api/v2.1/admin/admin-role/$', AdminAdminRole.as_view(), name='api-v2.1-admin-admin-role'),
|
||||
|
Loading…
Reference in New Issue
Block a user