def clean_email(self): if user_number_over_limit(): raise forms.ValidationError(_("The number of users exceeds the limit.")) email = self.cleaned_data['email'] try: user = User.objects.get(email=email) raise forms.ValidationError(_("A user with this email already exists.")) except User.DoesNotExist: return self.cleaned_data['email']
def clean_email(self): if user_number_over_limit(): raise forms.ValidationError( _("The number of users exceeds the limit.")) email = self.cleaned_data['email'] try: user = User.objects.get(email=email) raise forms.ValidationError( _("A user with this email already exists.")) except User.DoesNotExist: return self.cleaned_data['email']
def clean_email(self): if user_number_over_limit(): raise forms.ValidationError(_("The number of users exceeds the limit.")) email = self.cleaned_data['email'] if not self.allow_register(email): raise forms.ValidationError(_("Enter a valid email address.")) emailuser = ccnet_threaded_rpc.get_emailuser(email) if not emailuser: return self.cleaned_data['email'] else: raise forms.ValidationError(_("User %s already exists.") % email)
def test_user_number_over_limit(mock_is_pro_version, mock_parse_license): # max user is 1 license_dict = {'Expiration': '2017-7-20', 'Hash': 'hash value', 'LicenceKEY': '1474598078', 'Licencetype': 'User', 'MaxUsers': '1', 'Mode': 'subscription', 'Name': 'Test', 'ProductID': 'Seafile server'} mock_is_pro_version.return_value = True mock_parse_license.return_value = license_dict assert user_number_over_limit()
def test_user_number_over_limit(mock_is_pro_version, mock_parse_license): # max user is 1 license_dict = { 'Expiration': '2017-7-20', 'Hash': 'hash value', 'LicenceKEY': '1474598078', 'Licencetype': 'User', 'MaxUsers': '1', 'Mode': 'subscription', 'Name': 'Test', 'ProductID': 'Seafile server' } mock_is_pro_version.return_value = True mock_parse_license.return_value = license_dict assert user_number_over_limit()
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) # [email protected] a a default 1024 # [email protected] 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 = str(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 vid = get_virtual_id_by_email(email) try: User.objects.get(email=vid) result['failed'].append({ 'email': email, 'error_msg': 'user %s exists.' % email }) continue except User.DoesNotExist: pass user = User.objects.create_user(email, password, is_staff=False, is_active=True) virtual_id = get_virtual_id_by_email(email) if config.FORCE_PASSWORD_CHANGE: UserOptions.objects.set_force_passwd_change(virtual_id) # update the user's optional info # update nikename nickname = email.split('@')[0] try: if record[2]: input_nickname = str(record[2]).strip() if len(input_nickname) <= 64 and '/' not in input_nickname: nickname = input_nickname Profile.objects.add_or_update(virtual_id, 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(virtual_id, 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(virtual_id, space_quota) except Exception as e: logger.error(e) try: 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, }) except Exception as e: logger.error(e) user_info = get_user_info(virtual_id) result['success'].append(user_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)
def test_user_number_over_limit_if_not_pro(mock_is_pro_version): mock_is_pro_version.return_value = False assert not user_number_over_limit()
def post(self, request): if not request.user.admin_permissions.can_manage_user(): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') if user_number_over_limit(): error_msg = _("The number of users exceeds the limit.") return api_error(status.HTTP_400_BAD_REQUEST, error_msg) email = request.data.get('email', None) if not email or not is_valid_email(email): error_msg = 'email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # basic user info check is_staff = request.data.get("is_staff", 'False') try: is_staff = to_python_boolean(is_staff) except ValueError: error_msg = 'is_staff invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) is_active = request.data.get("is_active", 'True') try: is_active = to_python_boolean(is_active) except ValueError: error_msg = 'is_active invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # additional user info check role = '' if is_pro_version(): role = request.data.get("role", None) if role: available_roles = get_available_roles() if role not in available_roles: error_msg = 'role must be in %s.' % str(available_roles) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) name = request.data.get("name", None) if name: if len(name) > 64: error_msg = 'Name is too long (maximum is 64 characters).' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if "/" in name: error_msg = "Name should not include '/'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) contact_email = request.data.get('contact_email', None) if contact_email and not is_valid_email(contact_email): error_msg = 'contact_email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) quota_total_mb = request.data.get("quota_total", None) if quota_total_mb: try: quota_total_mb = int(quota_total_mb) except ValueError: error_msg = "Must be an integer that is greater than or equal to 0." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if quota_total_mb < 0: error_msg = "Space quota is too low (minimum value is 0)." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if is_org_context(request): org_id = request.user.org.org_id org_quota_mb = seafile_api.get_org_quota(org_id) / \ get_file_size_unit('MB') if quota_total_mb > org_quota_mb: error_msg = 'Failed to set quota: maximum quota is %d MB' % org_quota_mb return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: User.objects.get(email=email) user_exist = True except User.DoesNotExist: user_exist = False if user_exist: error_msg = "User %s already exists." % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) password = request.data.get('password', None) if not password: error_msg = 'password required.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # create user try: user_obj = User.objects.create_user(email, password, is_staff, is_active) create_user_info(request, email=user_obj.username, role=role, nickname=name, contact_email=contact_email, quota_total_mb=quota_total_mb) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) add_user_tip = _('Successfully added user %(user)s.') % {'user': email} if IS_EMAIL_CONFIGURED and SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER: c = { 'user': request.user.username, 'email': email, 'password': password } try: send_html_email( _('You are invited to join %s') % get_site_name(), 'sysadmin/user_add_email.html', c, None, [email2contact_email(email)]) add_user_tip = _( 'Successfully added user %(user)s. An email notification has been sent.' ) % { 'user': email } except Exception as e: logger.error(str(e)) add_user_tip = _( 'Successfully added user %(user)s. But email notification can not be sent, because Email service is not properly configured.' ) % { 'user': email } user_info = get_user_info(email) user_info['add_user_tip'] = add_user_tip # 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(user_info)
def post(self, request, org_id): """ Add new user to org. Permission checking: 1. only admin can perform this action. """ # argument check org_id = int(org_id) if org_id == 0: error_msg = 'org_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) org = ccnet_api.get_org_by_id(org_id) if not org: error_msg = 'Organization %d not found.' % org_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) email = request.POST.get('email', None) if not email or not is_valid_email(email): error_msg = 'email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) password = request.POST.get('password', None) if not password: error_msg = 'password invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: User.objects.get(email=email) user_exists = True except User.DoesNotExist: user_exists = False if user_exists: error_msg = 'User %s already exists.' % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # check user number limit by license if user_number_over_limit(): error_msg = 'The number of users exceeds the limit.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # check user number limit by org member quota org_members = len(ccnet_api.get_org_emailusers(org.url_prefix, -1, -1)) if ORG_MEMBER_QUOTA_ENABLED: from seahub_extra.organizations.models import OrgMemberQuota org_members_quota = OrgMemberQuota.objects.get_quota(org_id) if org_members_quota is not None and org_members >= org_members_quota: error_msg = 'Failed. You can only invite %d members.' % org_members_quota return api_error(status.HTTP_403_FORBIDDEN, error_msg) # create user try: user = User.objects.create_user(email, password, is_staff=False, is_active=True) except User.DoesNotExist as e: logger.error(e) error_msg = 'Fail to add user %s.' % email return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) # add user to org # set `is_staff` parameter as `0` try: ccnet_api.add_org_user(org_id, email, 0) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) name = request.POST.get('name', None) if name: Profile.objects.add_or_update(email, name) if config.FORCE_PASSWORD_CHANGE: UserOptions.objects.set_force_passwd_change(email) user_info = get_org_user_info(org_id, user) return Response(user_info)
def post(self, request, org_id): """Added an organization user, check member quota before adding. """ # resource check org_id = int(org_id) if not ccnet_api.get_org_by_id(org_id): error_msg = 'Organization %s not found.' % org_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # check plan url_prefix = request.user.org.url_prefix org_members = len( ccnet_api.get_org_users_by_url_prefix(url_prefix, -1, -1)) if ORG_MEMBER_QUOTA_ENABLED: from seahub_extra.organizations.models import OrgMemberQuota org_members_quota = OrgMemberQuota.objects.get_quota( request.user.org.org_id) if org_members_quota is not None and org_members >= org_members_quota: err_msg = 'Failed. You can only invite %d members.' % org_members_quota return api_error(status.HTTP_403_FORBIDDEN, err_msg) if user_number_over_limit(): return api_error(status.HTTP_403_FORBIDDEN, 'The number of users exceeds the limit') email = request.data.get('email', '') name = request.data.get('name', '') password = request.data.get('password', '') if not email or not is_valid_email(email): return api_error(status.HTTP_400_BAD_REQUEST, 'Email invalid.') if not password: return api_error(status.HTTP_400_BAD_REQUEST, 'Password invalid.') name = name.strip() if not name: return api_error(status.HTTP_400_BAD_REQUEST, 'Name invalid.') if len(name) > 64: error_msg = 'Name is too long (maximum is 64 characters).' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if "/" in name: error_msg = "Name should not include '/'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: user = User.objects.get(email=email) error_msg = 'User %s already exists.' % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) except User.DoesNotExist: pass try: user = User.objects.create_user(email, password, is_staff=False, is_active=True) except User.DoesNotExist as e: logger.error(e) error_msg = 'Fail to add user %s.' % email return api_error(status.HTTP_403_FORBIDDEN, error_msg) if user and name: Profile.objects.add_or_update(username=user.username, nickname=name) set_org_user(org_id, user.username) if IS_EMAIL_CONFIGURED: if SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER: try: send_user_add_mail(request, email, password) except Exception, e: logger.error(str(e))
def post(self, request, org_id): """ Add new user to org. Permission checking: 1. only admin can perform this action. """ # argument check org_id = int(org_id) if org_id == 0: error_msg = 'org_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) org = ccnet_api.get_org_by_id(org_id) if not org: error_msg = 'Organization %d not found.' % org_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) email = request.POST.get('email', None) if not email or not is_valid_email(email): error_msg = 'email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) password = request.POST.get('password', None) if not password: error_msg = 'password invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) active = request.POST.get('active', 'true') active = active.lower() if active not in ('true', 'false'): error_msg = 'active invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) is_active = active == 'true' try: User.objects.get(email=email) user_exists = True except User.DoesNotExist: user_exists = False if user_exists: error_msg = 'User %s already exists.' % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # check user number limit by license if user_number_over_limit(): error_msg = 'The number of users exceeds the limit.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # check user number limit by org member quota org_members = len(ccnet_api.get_org_emailusers(org.url_prefix, -1, -1)) if ORG_MEMBER_QUOTA_ENABLED: from seahub_extra.organizations.models import OrgMemberQuota org_members_quota = OrgMemberQuota.objects.get_quota(org_id) if org_members_quota is not None and org_members >= org_members_quota: error_msg = 'Failed. You can only invite %d members.' % org_members_quota return api_error(status.HTTP_403_FORBIDDEN, error_msg) # create user try: User.objects.create_user(email, password, is_staff=False, is_active=is_active) except User.DoesNotExist as e: logger.error(e) error_msg = 'Fail to add user %s.' % email return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) # add user to org # set `is_staff` parameter as `0` try: ccnet_api.add_org_user(org_id, email, 0) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) name = request.POST.get('name', None) if name: Profile.objects.add_or_update(email, name) if config.FORCE_PASSWORD_CHANGE: UserOptions.objects.set_force_passwd_change(email) user_info = get_org_user_info(org_id, email) user_info['active'] = is_active return Response(user_info)
def post(self, request): if user_number_over_limit(): error_msg = _("The number of users exceeds the limit.") return api_error(status.HTTP_400_BAD_REQUEST, error_msg) email = request.data.get('email', None) if not email or not is_valid_username(email): error_msg = 'email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # basic user info check is_staff = request.data.get("is_staff", None) if is_staff: try: is_staff = to_python_boolean(is_staff) except ValueError: error_msg = 'is_staff invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) is_active = request.data.get("is_active", None) if is_active: try: is_active = to_python_boolean(is_active) except ValueError: error_msg = 'is_active invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # additional user info check role = request.data.get("role", None) if role: available_roles = get_available_roles() if role.lower() not in available_roles: error_msg = 'role must be in %s.' % str(available_roles) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) name = request.data.get("name", None) if name: if len(name) > 64: error_msg = 'Name is too long (maximum is 64 characters).' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if "/" in name: error_msg = "Name should not include '/'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) department = request.data.get("department", None) if department: if len(department) > 512: error_msg = "Department is too long (maximum is 512 characters)." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) quota_total_mb = request.data.get("quota_total", None) if quota_total_mb: try: quota_total_mb = int(quota_total_mb) except ValueError: error_msg = "Must be an integer that is greater than or equal to 0." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if quota_total_mb < 0: error_msg = "Space quota is too low (minimum value is 0)." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if is_org_context(request): org_id = request.user.org.org_id org_quota_mb = seafile_api.get_org_quota(org_id) / \ get_file_size_unit('MB') if quota_total_mb > org_quota_mb: error_msg = 'Failed to set quota: maximum quota is %d MB' % org_quota_mb return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: User.objects.get(email=email) user_exist = True except User.DoesNotExist: user_exist = False if user_exist: error_msg = "User %s already exists." % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) password = request.data.get('password', None) if not password: error_msg = 'password required.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # create user try: user_obj = User.objects.create_user(email) update_user_info(request, user_obj) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if IS_EMAIL_CONFIGURED and SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER: c = { 'user': request.user.username, 'email': email, 'password': password } try: send_html_email( _('You are invited to join %s') % get_site_name(), 'sysadmin/user_add_email.html', c, None, [email]) except Exception as e: logger.error(str(e)) user_info = get_user_info(email) return Response(user_info)