def post(self, request): license_file = request.FILES.get('license', None) if not license_file: error_msg = 'license can not be found.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) file_type, ext = get_file_type_and_ext(license_file.name) if ext != 'txt': error_msg = file_type_error_msg(ext, 'txt') return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if license_file.size > 1024 * 1024 * 5: # 5mb error_msg = file_size_error_msg(license_file.size, 5 * 1024 * 1024) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) license_dir = os.path.dirname(LICENSE_PATH) try: if not os.path.exists(license_dir): error_msg = 'path %s invalid.' % LICENSE_PATH return api_error(status.HTTP_400_BAD_REQUEST, error_msg) with open(LICENSE_PATH, 'w') as fd: fd.write(license_file.read()) ccnet_api.reload_license() except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) return Response({'success': True}, status=status.HTTP_200_OK)
def post(self, request): license_file = request.FILES.get('license', None) if not license_file: error_msg = 'license can not be found.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) file_type, ext = get_file_type_and_ext(license_file.name) if ext != 'txt': error_msg = file_type_error_msg(ext, 'txt') return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if license_file.size > 1024 * 1024 * 5: # 5mb error_msg = file_size_error_msg(license_file.size, 5*1024*1024) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) license_dir = os.path.dirname(LICENSE_PATH) try: if not os.path.exists(license_dir): error_msg = 'path %s invalid.' % LICENSE_PATH return api_error(status.HTTP_400_BAD_REQUEST, error_msg) with open(LICENSE_PATH, 'w') as fd: fd.write(license_file.read()) ccnet_api.reload_license() except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) return Response({'success': True}, status=status.HTTP_200_OK)
def post(self, request): if not request.user.admin_permissions.can_config_system(): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') license_file = request.FILES.get('license', None) if not license_file: error_msg = 'license can not be found.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) file_type, ext = get_file_type_and_ext(license_file.name) if ext != 'txt': error_msg = file_type_error_msg(ext, 'txt') return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if license_file.size > 1024 * 1024 * 5: # 5mb error_msg = file_size_error_msg(license_file.size, 5 * 1024 * 1024) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) license_dir = os.path.dirname(LICENSE_PATH) try: if not os.path.exists(license_dir): error_msg = 'path %s invalid.' % LICENSE_PATH return api_error(status.HTTP_400_BAD_REQUEST, error_msg) with open(LICENSE_PATH, 'wb') as fd: fd.write(license_file.read()) ccnet_api.reload_license() except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) # get license info is_pro = is_pro_version() if is_pro: license_dict = parse_license() else: license_dict = {} if license_dict: try: max_users = int(license_dict.get('MaxUsers', 3)) except ValueError as e: logger.error(e) max_users = 0 else: max_users = 0 license_info = { 'license_expiration': license_dict.get('Expiration', ''), 'license_mode': license_dict.get('Mode', ''), 'license_maxusers': max_users, 'license_to': license_dict.get('Name', ''), } return Response(license_info, status=status.HTTP_200_OK)
def clean_avatar(self): data = self.cleaned_data['avatar'] if AVATAR_ALLOWED_FILE_EXTS: (root, ext) = os.path.splitext(data.name.lower()) if ext not in AVATAR_ALLOWED_FILE_EXTS: error_msg = file_type_error_msg(ext, AVATAR_ALLOWED_FILE_EXTS) raise forms.ValidationError(error_msg) if data.size > AVATAR_MAX_SIZE: error_msg = file_size_error_msg(data.size, AVATAR_MAX_SIZE) raise forms.ValidationError(error_msg)
def clean_avatar(self): data = self.cleaned_data['avatar'] if AVATAR_ALLOWED_FILE_EXTS: (root, ext) = os.path.splitext(data.name.lower()) if ext not in AVATAR_ALLOWED_FILE_EXTS: error_msg = file_type_error_msg(ext, AVATAR_ALLOWED_FILE_EXTS) raise forms.ValidationError(error_msg) if data.size > AVATAR_MAX_SIZE: error_msg = file_size_error_msg(data.size, AVATAR_MAX_SIZE) raise forms.ValidationError(error_msg)
def post(self, request): if not request.user.admin_permissions.can_config_system(): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') favicon_file = request.FILES.get('favicon', None) if not favicon_file: error_msg = 'Favicon can not be found.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) file_type, ext = get_file_type_and_ext(favicon_file.name) if file_type != IMAGE: error_msg = file_type_error_msg(ext, PREVIEW_FILEEXT.get(IMAGE)) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if favicon_file.size > 1024 * 1024 * 20: # 20mb error_msg = file_size_error_msg(favicon_file.size, 20 * 1024 * 1024) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not os.path.exists(SEAHUB_DATA_ROOT): os.makedirs(SEAHUB_DATA_ROOT) custom_dir = os.path.join(SEAHUB_DATA_ROOT, os.path.dirname(CUSTOM_FAVICON_PATH)) if not os.path.exists(custom_dir): os.makedirs(custom_dir) try: custom_favicon_file = os.path.join(SEAHUB_DATA_ROOT, CUSTOM_FAVICON_PATH) # save favicon file to custom dir with open(custom_favicon_file, 'wb') as fd: fd.write(favicon_file.read()) custom_symlink = os.path.join(MEDIA_ROOT, os.path.dirname(CUSTOM_FAVICON_PATH)) # create symlink for custom dir if not os.path.exists(custom_symlink): os.symlink(custom_dir, custom_symlink) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) return Response({ 'favicon_path': get_service_url() + MEDIA_URL + CUSTOM_FAVICON_PATH })
def test_update_license_with_invalid_type(self, mock_ccnet_api): mock_ccnet_api.return_val = {} url = reverse('api-v2.1-admin-license') url = urljoin(BASE_URL, url) with open('temp.notxt', 'w') as f: f.write('1') with open(os.path.join(os.getcwd(), 'temp.notxt')) as f: resp = self.client.post(url, {'license': f}) json_resp = json.loads(resp.content) assert 400 == resp.status_code assert file_type_error_msg('notxt', 'txt') == json_resp['error_msg']
def test_update_favicon_with_invalid_filetype(self): with open('test.noico', 'w') as f: f.write('hello') logo_url = reverse('api-v2.1-admin-favicon') logo_url = urljoin(BASE_URL, logo_url) logo_file = os.path.join(os.getcwd(), 'test.noico') with open(logo_file) as f: resp = self.client.post(logo_url, {'favicon': f}) json_resp = json.loads(resp.content) assert resp.status_code == 400 assert json_resp['error_msg'] == file_type_error_msg('noico', PREVIEW_FILEEXT.get(IMAGE))
def test_update_favicon_with_invalid_filetype(self): with open('test.noico', 'w') as f: f.write('hello') logo_url = reverse('api-v2.1-admin-favicon') logo_url = urljoin(BASE_URL, logo_url) logo_file = os.path.join(os.getcwd(), 'test.noico') with open(logo_file, 'rb') as f: resp = self.client.post(logo_url, {'favicon': f}) json_resp = json.loads(resp.content) assert resp.status_code == 400 assert json_resp['error_msg'] == file_type_error_msg('noico', PREVIEW_FILEEXT.get(IMAGE))
def test_update_logo_with_invalid_file_type(self): with open('test.noimage', 'w') as f: f.write('hello') image_url = reverse('api-v2.1-admin-login-background-image') image_url = urljoin(BASE_URL, image_url) image_file = os.path.join(os.getcwd(), 'test.noimage') with open(image_file, 'rb') as f: resp = self.client.post(image_url, {'login_bg_image': f}) json_resp = json.loads(resp.content) os.remove(image_file) assert 400 == resp.status_code assert json_resp['error_msg'] == file_type_error_msg("noimage", PREVIEW_FILEEXT.get('Image'))
def test_update_logo_with_invalid_file_type(self): with open('test.noimage', 'w') as f: f.write('1') logo_url = reverse('api-v2.1-admin-logo') logo_url = urljoin(BASE_URL, logo_url) logo_file = os.path.join(os.getcwd(), 'test.noimage') with open(logo_file, 'rb') as f: resp = self.client.post(logo_url, {'logo': f}) json_resp = json.loads(resp.content) os.remove(logo_file) assert 400 == resp.status_code assert json_resp['error_msg'] == file_type_error_msg( 'noimage', PREVIEW_FILEEXT.get(IMAGE))
def post(self, request): favicon_file = request.FILES.get('favicon', None) if not favicon_file: error_msg = 'Favicon can not be found.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) file_type, ext = get_file_type_and_ext(favicon_file.name) if file_type != IMAGE: error_msg = file_type_error_msg(ext, PREVIEW_FILEEXT.get(IMAGE)) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if favicon_file.size > 1024 * 1024 * 20: # 20mb error_msg = file_size_error_msg(favicon_file.size, 20*1024*1024) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not os.path.exists(SEAHUB_DATA_ROOT): os.makedirs(SEAHUB_DATA_ROOT) custom_dir = os.path.join(SEAHUB_DATA_ROOT, os.path.dirname(CUSTOM_FAVICON_PATH)) if not os.path.exists(custom_dir): os.makedirs(custom_dir) try: custom_favicon_file = os.path.join(SEAHUB_DATA_ROOT, CUSTOM_FAVICON_PATH) # save favicon file to custom dir with open(custom_favicon_file, 'w') as fd: fd.write(favicon_file.read()) custom_symlink = os.path.join(MEDIA_ROOT, os.path.dirname(CUSTOM_FAVICON_PATH)) # create symlink for custom dir if not os.path.exists(custom_symlink): os.symlink(custom_dir, custom_symlink) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) return Response({'success': True})
def post(self, request): if not request.user.admin_permissions.can_config_system(): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') logo_file = request.FILES.get('logo', None) if not logo_file: error_msg = 'Logo can not be found.' logger.error(error_msg) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) file_type, ext = get_file_type_and_ext(logo_file.name) if file_type != IMAGE: error_msg = file_type_error_msg(ext, PREVIEW_FILEEXT.get(IMAGE)) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if logo_file.size > 1024 * 1024 * 20: # 20mb error_msg = file_size_error_msg(logo_file.size, 20 * 1024 * 1024) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not os.path.exists(SEAHUB_DATA_ROOT): os.makedirs(SEAHUB_DATA_ROOT) custom_dir = os.path.join(SEAHUB_DATA_ROOT, os.path.dirname(CUSTOM_LOGO_PATH)) if not os.path.exists(custom_dir): os.makedirs(custom_dir) try: # save logo file to custom dir custom_logo_file = os.path.join(SEAHUB_DATA_ROOT, CUSTOM_LOGO_PATH) image = Image.open(logo_file) image.save(custom_logo_file) # create symlink for custom dir custom_symlink = os.path.join(MEDIA_ROOT, os.path.dirname(CUSTOM_LOGO_PATH)) if not os.path.exists(custom_symlink): os.symlink(custom_dir, custom_symlink) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) return Response( {'logo_path': get_service_url() + MEDIA_URL + CUSTOM_LOGO_PATH})
def clean_avatar(self): data = self.cleaned_data['avatar'] if AVATAR_ALLOWED_FILE_EXTS: (root, ext) = os.path.splitext(data.name.lower()) if ext not in AVATAR_ALLOWED_FILE_EXTS: error_msg = file_type_error_msg(ext, AVATAR_ALLOWED_FILE_EXTS) raise forms.ValidationError(error_msg) if data.size > AVATAR_MAX_SIZE: error_msg = file_size_error_msg(data.size, AVATAR_MAX_SIZE) raise forms.ValidationError(error_msg) count = Avatar.objects.filter(emailuser=self.emailuser).count() if AVATAR_MAX_AVATARS_PER_USER > 1 and \ count >= AVATAR_MAX_AVATARS_PER_USER: raise forms.ValidationError( _(u"You already have %(nb_avatars)d avatars, and the maximum allowed is %(nb_max_avatars)d.") % { 'nb_avatars' : count, 'nb_max_avatars' : AVATAR_MAX_AVATARS_PER_USER}) return
def post(self, request): image_file = request.FILES.get('login_bg_image', None) if not image_file: error_msg = 'Image can not be found.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not os.path.exists(SEAHUB_DATA_ROOT): os.makedirs(SEAHUB_DATA_ROOT) file_type, ext = get_file_type_and_ext(image_file.name) if file_type != IMAGE: error_msg = file_type_error_msg(ext, PREVIEW_FILEEXT.get('Image')) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if image_file.size > 1024 * 1024 * 20: # 20mb error_msg = file_size_error_msg(image_file.size, 20 * 1024 * 1024) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) custom_login_bg_image_path = get_custom_login_bg_image_path() custom_dir = os.path.join(SEAHUB_DATA_ROOT, os.path.dirname(custom_login_bg_image_path)) if not os.path.exists(custom_dir): os.makedirs(custom_dir) try: custom_login_bg_image_file = os.path.join( SEAHUB_DATA_ROOT, custom_login_bg_image_path) # save login background image file to custom dir with open(custom_login_bg_image_file, 'wb') as fd: fd.write(image_file.read()) custom_symlink = os.path.join( MEDIA_ROOT, os.path.dirname(custom_login_bg_image_path)) # create symlink for custom dir if not os.path.exists(custom_symlink): os.symlink(custom_dir, custom_symlink) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) return Response({ 'login_bg_image_path': get_service_url() + MEDIA_URL + CUSTOM_LOGIN_BG_PATH })
def post(self, request): image_file = request.FILES.get('login_bg_image', None) if not image_file: error_msg = 'Image can not be found.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not os.path.exists(SEAHUB_DATA_ROOT): os.makedirs(SEAHUB_DATA_ROOT) file_type, ext = get_file_type_and_ext(image_file.name) if file_type != IMAGE: error_msg = file_type_error_msg(ext, PREVIEW_FILEEXT.get('Image')) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if image_file.size > 1024 * 1024 * 20: # 20mb error_msg = file_size_error_msg(image_file.size, 20*1024*1024) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) custom_login_bg_image_path = get_custom_login_bg_image_path() custom_dir = os.path.join(SEAHUB_DATA_ROOT, os.path.dirname(custom_login_bg_image_path)) if not os.path.exists(custom_dir): os.makedirs(custom_dir) try: custom_login_bg_image_file = os.path.join(SEAHUB_DATA_ROOT, custom_login_bg_image_path) # save login background image file to custom dir with open(custom_login_bg_image_file, 'w') as fd: fd.write(image_file.read()) custom_symlink = os.path.join(MEDIA_ROOT, os.path.dirname(custom_login_bg_image_path)) # create symlink for custom dir if not os.path.exists(custom_symlink): os.symlink(custom_dir, custom_symlink) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) return Response({'success': True})
def clean_avatar(self): data = self.cleaned_data['avatar'] if AVATAR_ALLOWED_FILE_EXTS: (root, ext) = os.path.splitext(data.name.lower()) if ext not in AVATAR_ALLOWED_FILE_EXTS: error_msg = file_type_error_msg(ext, AVATAR_ALLOWED_FILE_EXTS) raise forms.ValidationError(error_msg) if data.size > AVATAR_MAX_SIZE: error_msg = file_size_error_msg(data.size, AVATAR_MAX_SIZE) raise forms.ValidationError(error_msg) count = Avatar.objects.filter(emailuser=self.emailuser).count() if AVATAR_MAX_AVATARS_PER_USER > 1 and \ count >= AVATAR_MAX_AVATARS_PER_USER: raise forms.ValidationError( _("You already have %(nb_avatars)d avatars, and the maximum allowed is %(nb_max_avatars)d." ) % { 'nb_avatars': count, 'nb_max_avatars': AVATAR_MAX_AVATARS_PER_USER }) return
def post(self, request): logo_file = request.FILES.get('logo', None) if not logo_file: error_msg = 'Logo can not be found.' logger.error(error_msg) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) file_type, ext = get_file_type_and_ext(logo_file.name) if file_type != IMAGE: error_msg = file_type_error_msg(ext, PREVIEW_FILEEXT.get(IMAGE)) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if logo_file.size > 1024 * 1024 * 20: # 20mb error_msg = file_size_error_msg(logo_file.size, 20*1024*1024) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not os.path.exists(SEAHUB_DATA_ROOT): os.makedirs(SEAHUB_DATA_ROOT) custom_dir = os.path.join(SEAHUB_DATA_ROOT, os.path.dirname(CUSTOM_LOGO_PATH)) if not os.path.exists(custom_dir): os.makedirs(custom_dir) try: # save logo file to custom dir custom_logo_file = os.path.join(SEAHUB_DATA_ROOT, CUSTOM_LOGO_PATH) image = Image.open(logo_file) image.save(custom_logo_file) # create symlink for custom dir custom_symlink = os.path.join(MEDIA_ROOT, os.path.dirname(CUSTOM_LOGO_PATH)) if not os.path.exists(custom_symlink): os.symlink(custom_dir, custom_symlink) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) return Response({'success': True})
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 post(self, request, group_id): """ Import members from xlsx file Permission checking: 1. group admin or owner. """ 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) # recourse check group_id = int(group_id) group = ccnet_api.get_group(group_id) if not group: error_msg = _('Group does not exist') return api_error(status.HTTP_404_NOT_FOUND, error_msg) # check permission # only group owner/admin can add group members username = request.user.username if not is_group_admin_or_owner(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, 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 # [email protected] # [email protected] 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]) emails_list = [] for record in records: if record[0]: email = record[0].strip().lower() emails_list.append(email) result = {} result['failed'] = [] result['success'] = [] emails_need_add = [] org_id = None if is_org_context(request): org_id = request.user.org.org_id for email in emails_list: email_name = email2nickname(email) try: User.objects.get(email=email) except User.DoesNotExist: result['failed'].append({ 'email': email, 'email_name': email_name, 'error_msg': 'User %s not found.' % email_name }) continue if is_group_member(group_id, email, in_structure=False): result['failed'].append({ 'email': email, 'email_name': email_name, 'error_msg': _('User %s is already a group member.') % email_name }) continue # Can only invite organization users to group if org_id and not ccnet_api.org_user_exists(org_id, email): result['failed'].append({ 'email': email, 'email_name': email_name, 'error_msg': _('User %s not found in organization.') % email_name }) continue if not org_id and is_org_user(email): result['failed'].append({ 'email': email, 'email_name': email_name, 'error_msg': _('User %s is an organization user.') % email_name }) continue emails_need_add.append(email) # Add user to group. for email in emails_need_add: try: ccnet_api.group_add_member(group_id, username, email) member_info = get_group_member_info(request, group_id, email) result['success'].append(member_info) except SearpcError as e: logger.error(e) result['failed'].append({ 'email': email, 'error_msg': 'Internal Server Error' }) add_user_to_group.send(sender=None, group_staff=username, group_id=group_id, added_user=email) return Response(result)