def _update_account(self, request, user): password = request.DATA.get("password", None) is_staff = request.DATA.get("is_staff", None) if is_staff is not None: try: is_staff = to_python_boolean(is_staff) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, "%s is not a valid value" % is_staff) is_active = request.DATA.get("is_active", None) if is_active is not None: try: is_active = to_python_boolean(is_active) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, "%s is not a valid value" % is_active) if password is not None: user.set_password(password) if is_staff is not None: user.is_staff = is_staff if is_active is not None: user.is_active = is_active result_code = user.save() if result_code == -1: return api_error(status.HTTP_403_FORBIDDEN, "Fail to update user.") self._update_account_profile(request, user.username) try: self._update_account_quota(request, user.username) except SearpcError as e: logger.error(e) return api_error(HTTP_520_OPERATION_FAILED, "Failed to set account quota") is_trial = request.DATA.get("is_trial", None) if is_trial is not None: try: from seahub_extra.trialaccount.models import TrialAccount except ImportError: pass else: try: is_trial = to_python_boolean(is_trial) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, "%s is not a valid value" % is_trial) if is_trial is True: expire_date = timezone.now() + relativedelta(days=7) TrialAccount.object.create_or_update(user.username, expire_date) else: TrialAccount.objects.filter(user_or_org=user.username).delete() return Response("success")
def update_user_info(request): email = request.data.get("email") user = User.objects.get(email=email) # update basic user info password = request.data.get("password") if password: user.set_password(password) is_staff = request.data.get("is_staff") if is_staff: is_staff = to_python_boolean(is_staff) user.is_staff = is_staff is_active = request.data.get("is_active") if is_active: is_active = to_python_boolean(is_active) user.is_active = is_active # update user user.save() # update additional user info if is_pro_version(): role = request.data.get("role") if role: User.objects.update_role(email, role) name = request.data.get("name") if name: profile = Profile.objects.get_profile_by_user(email) if profile is None: profile = Profile(user=email) profile.nickname = name profile.save() department = request.data.get("department") if department: d_profile = DetailedProfile.objects.get_detailed_profile_by_user(email) if d_profile is None: d_profile = DetailedProfile(user=email) d_profile.department = department d_profile.save() quota_total_mb = request.data.get("quota_total") if quota_total_mb: quota_total = int(quota_total_mb) * get_file_size_unit('MB') if is_org_context(request): org_id = request.user.org.org_id seafile_api.set_org_user_quota(org_id, email, quota_total) else: seafile_api.set_user_quota(email, quota_total)
def put(self, request, pk): """ Mark an abuse report handled. Permission checking: 1. only admin can perform this action. """ if not ENABLE_SHARE_LINK_REPORT_ABUSE: error_msg = 'Feature not enabled.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # argument check handled = request.data.get('handled') if not handled: error_msg = 'handled invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if handled not in ('true', 'false'): error_msg = 'handled invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check report = AbuseReport.objects.get_abuse_report_by_id(pk) if not report: error_msg = 'abuse report %d not found.' % pk return api_error(status.HTTP_404_NOT_FOUND, error_msg) report.handled = to_python_boolean(handled) report.save() info = get_abuse_report_info(report) return Response(info)
def put(self, request, review_id, comment_id, format=None): """Update a comment, only comment author or review creator can perform this op 1.Change resolved of comment 2.Add comment_detail """ # argument check resolved = request.data.get('resolved') if resolved not in ('true', 'false', None): error_msg = 'resolved invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) detail = request.data.get('detail', '') # resource check try: r = DraftReview.objects.get(pk=review_id) except DraftReview.DoesNotExist: return api_error(status.HTTP_404_NOT_FOUND, 'Review %s not found' % review_id) try: review_comment = ReviewComment.objects.get(pk=comment_id) except ReviewComment.DoesNotExist: error_msg = 'Review comment %s not found.' % comment_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check if check_folder_permission(request, r.origin_repo_id, '/') is None: return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') if resolved is not None: comment_resolved = to_python_boolean(resolved) try: review_comment.resolved = comment_resolved review_comment.save() except Exception as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Internal error.') if detail is not None: try: review_comment.detail = detail review_comment.save() except Exception as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Internal error.') try: avatar_size = int(request.GET.get('avatar_size', AVATAR_DEFAULT_SIZE)) except ValueError: avatar_size = AVATAR_DEFAULT_SIZE username = request.user.username comment = review_comment.to_dict() comment.update(user_to_dict(username, request=request, avatar_size=avatar_size)) return Response(comment)
def get(self, request, review_id, format=None): """List all comments of a review. """ # resource check try: r = DraftReview.objects.get(pk=review_id) except DraftReview.DoesNotExist: return api_error(status.HTTP_404_NOT_FOUND, 'Review %s not found' % review_id) resolved = request.GET.get('resolved', None) if resolved not in ('true', 'false', None): error_msg = 'resolved invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # permission check if check_folder_permission(request, r.origin_repo_id, '/') is None: return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') try: avatar_size = int( request.GET.get('avatar_size', AVATAR_DEFAULT_SIZE)) page = int(request.GET.get('page', '1')) per_page = int(request.GET.get('per_page', '25')) except ValueError: avatar_size = AVATAR_DEFAULT_SIZE page = 1 per_page = 25 start = (page - 1) * per_page end = page * per_page total_count = ReviewComment.objects.filter(review_id=r).count() comments = [] if resolved is None: file_comments = ReviewComment.objects.filter(review_id=r) else: comment_resolved = to_python_boolean(resolved) file_comments = ReviewComment.objects.filter( review_id=r, resolved=comment_resolved)[start:end] for file_comment in file_comments: comment = file_comment.to_dict() comment.update( user_to_dict(file_comment.author, request=request, avatar_size=avatar_size)) comments.append(comment) result = {'comments': comments, 'total_count': total_count} resp = Response(result) base_url = reverse('api2-review-comments', args=[review_id]) links_header = generate_links_header_for_paginator( base_url, page, per_page, total_count) resp['Links'] = links_header return resp
def get(self, request, group_id): """List child groups and members in an address book group.""" group_id = int(group_id) group = ccnet_api.get_group(group_id) if not group: error_msg = 'Group %d not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: avatar_size = int( request.GET.get('avatar_size', AVATAR_DEFAULT_SIZE)) except ValueError: avatar_size = AVATAR_DEFAULT_SIZE try: return_ancestors = to_python_boolean( request.GET.get('return_ancestors', 'f')) except ValueError: return_ancestors = False ret_dict = address_book_group_to_dict(group) ret_groups = [] ret_members = [] groups = ccnet_api.get_child_groups(group_id) for group in groups: ret_groups.append(address_book_group_to_dict(group)) try: members = ccnet_api.get_group_members(group_id) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) for m in members: member_info = self._get_address_book_group_memeber_info( request, m, avatar_size) if member_info['role'] == 'Owner': continue ret_members.append(member_info) ret_dict['groups'] = ret_groups ret_dict['members'] = ret_members if return_ancestors: # get ancestor groups and remove last group which is self ancestor_groups = ccnet_api.get_ancestor_groups(group_id)[:-1] ret_dict['ancestor_groups'] = [ address_book_group_to_dict(grp) for grp in ancestor_groups ] else: ret_dict['ancestor_groups'] = [] return Response(ret_dict)
def get(self, request, repo_id, format=None): """List all comments of a file. """ path = request.GET.get('p', '/').rstrip('/') if not path: return api_error(status.HTTP_400_BAD_REQUEST, 'Wrong path.') resolved = request.GET.get('resolved', None) if resolved not in ('true', 'false', None): error_msg = 'resolved invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # permission check if check_folder_permission(request, repo_id, '/') is None: return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') try: avatar_size = int( request.GET.get('avatar_size', AVATAR_DEFAULT_SIZE)) page = int(request.GET.get('page', '1')) per_page = int(request.GET.get('per_page', '25')) except ValueError: avatar_size = AVATAR_DEFAULT_SIZE page = 1 per_page = 25 start = (page - 1) * per_page end = page * per_page total_count = FileComment.objects.get_by_file_path(repo_id, path).count() comments = [] if resolved is None: file_comments = FileComment.objects.get_by_file_path( repo_id, path)[start:end] else: comment_resolved = to_python_boolean(resolved) file_comments = FileComment.objects.get_by_file_path( repo_id, path).filter(resolved=comment_resolved)[start:end] for file_comment in file_comments: comment = file_comment.to_dict() comment.update( user_to_dict(file_comment.author, request=request, avatar_size=avatar_size)) comments.append(comment) result = {'comments': comments, 'total_count': total_count} resp = Response(result) base_url = reverse('api2-file-comments', args=[repo_id]) links_header = generate_links_header_for_paginator( base_url, page, per_page, total_count) resp['Links'] = links_header return resp
def get(self, request, group_id): """List child groups and members in an address book group.""" group_id = int(group_id) group = ccnet_api.get_group(group_id) if not group: error_msg = 'Group %d not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: avatar_size = int(request.GET.get('avatar_size', AVATAR_DEFAULT_SIZE)) except ValueError: avatar_size = AVATAR_DEFAULT_SIZE try: return_ancestors = to_python_boolean(request.GET.get( 'return_ancestors', 'f')) except ValueError: return_ancestors = False ret_dict = address_book_group_to_dict(group) ret_groups = [] ret_members = [] groups = ccnet_api.get_child_groups(group_id) for group in groups: ret_groups.append(address_book_group_to_dict(group)) try: members = ccnet_api.get_group_members(group_id) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) for m in members: member_info = self._get_address_book_group_memeber_info(request, m, avatar_size) ret_members.append(member_info) ret_dict['groups'] = ret_groups ret_dict['members'] = ret_members if return_ancestors: # get ancestor groups and remove last group which is self ancestor_groups = ccnet_api.get_ancestor_groups(group_id)[:-1] ret_dict['ancestor_groups'] = [address_book_group_to_dict(grp) for grp in ancestor_groups] else: ret_dict['ancestor_groups'] = [] return Response(ret_dict)
def put(self, request, repo_id, comment_id, format=None): """Update a comment, only comment author or repo owner can perform this op 1.Change resolved of comment 2.Add comment_detail """ # argument check resolved = request.data.get('resolved') if resolved not in ('true', 'false', None): error_msg = 'resolved invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) detail = request.data.get('detail') # resource check try: file_comment = FileComment.objects.get(pk=comment_id) except FileComment.DoesNotExist: error_msg = 'FileComment %s not found.' % comment_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check username = request.user.username if username != file_comment.author and not is_repo_owner(request, repo_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if resolved is not None: comment_resolved = to_python_boolean(resolved) try: file_comment.resolved = comment_resolved file_comment.save() except Exception as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Internal error.') if detail is not None: try: file_comment.detail = detail file_comment.save() except Exception as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Internal error.') try: avatar_size = int(request.GET.get('avatar_size', AVATAR_DEFAULT_SIZE)) except ValueError: avatar_size = AVATAR_DEFAULT_SIZE comment = file_comment.to_dict() comment.update(user_to_dict(file_comment.author, request=request, avatar_size=avatar_size)) return Response(comment)
def get(self, request, repo_id): """list all repo_tags by repo_id. """ # argument check include_file_count = request.GET.get('include_file_count', 'true') if include_file_count not in ['true', 'false']: error_msg = 'include_file_count invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) include_file_count = to_python_boolean(include_file_count) # resource check repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check if not check_folder_permission(request, repo_id, '/'): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # get files tags files_count = defaultdict(int) if include_file_count: try: files_tags = FileTags.objects.select_related( 'repo_tag').filter(repo_tag__repo_id=repo_id) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) for file_tag in files_tags: files_count[file_tag.repo_tag_id] += 1 repo_tags = [] try: repo_tag_list = RepoTags.objects.get_all_by_repo_id(repo_id) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) for repo_tag in repo_tag_list: res = repo_tag.to_dict() repo_tag_id = res["repo_tag_id"] if repo_tag_id in files_count: res["files_count"] = files_count[repo_tag_id] else: res["files_count"] = 0 repo_tags.append(res) return Response({"repo_tags": repo_tags}, status=status.HTTP_200_OK)
def get(self, request, repo_id): """list all repo_tags by repo_id. """ # argument check include_file_count = request.GET.get('include_file_count', 'true') if include_file_count not in ['true', 'false']: error_msg = 'include_file_count invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) include_file_count = to_python_boolean(include_file_count) # resource check repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check if not check_folder_permission(request, repo_id, '/'): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # get files tags files_count = defaultdict(int) if include_file_count: try: files_tags = FileTags.objects.select_related('repo_tag').filter(repo_tag__repo_id=repo_id) except Exception as e: logger.error(e) error_msg = 'Internal Server Error.' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) for file_tag in files_tags: files_count[file_tag.repo_tag_id] += 1 repo_tags = [] try: repo_tag_list = RepoTags.objects.get_all_by_repo_id(repo_id) except Exception as e: logger.error(e) error_msg = 'Internal Server Error.' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) for repo_tag in repo_tag_list: res = repo_tag.to_dict() repo_tag_id = res["repo_tag_id"] if files_count.has_key(repo_tag_id): res["files_count"] = files_count[repo_tag_id] else: res["files_count"] = 0 repo_tags.append(res) return Response({"repo_tags": repo_tags}, status=status.HTTP_200_OK)
def get(self, request, format=None): repo_id = request.repo_api_token_obj.repo_id # recourse check repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) parent_dir = request.GET.get('path', '/') dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir) if not dir_id: error_msg = 'Folder %s not found.' % parent_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check if check_folder_permission_by_repo_api(request, repo_id, parent_dir) != 'rw': return api_error( status.HTTP_403_FORBIDDEN, 'You do not have permission to access this folder.') if check_quota(repo_id) < 0: return api_error(HTTP_443_ABOVE_QUOTA, "Out of quota.") obj_data = {'parent_dir': parent_dir} if is_pro_version(): obj_data['anonymous_user'] = request.repo_api_token_obj.app_name obj_id = json.dumps(obj_data) token = seafile_api.get_fileserver_access_token(repo_id, obj_id, 'upload', '', use_onetime=False) if not token: error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) req_from = request.GET.get('from', 'api') if req_from == 'api': try: replace = to_python_boolean(request.GET.get('replace', '0')) except ValueError: replace = False url = gen_file_upload_url(token, 'upload-api', replace) elif req_from == 'web': url = gen_file_upload_url(token, 'upload-aj') else: error_msg = 'from invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) return Response(url)
def get(self, request, repo_id, format=None): """List all comments of a file. """ path = request.GET.get('p', '/').rstrip('/') if not path: return api_error(status.HTTP_400_BAD_REQUEST, 'Wrong path.') resolved = request.GET.get('resolved', None) if resolved not in ('true', 'false', None): error_msg = 'resolved invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # permission check if check_folder_permission(request, repo_id, '/') is None: return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') try: avatar_size = int(request.GET.get('avatar_size', AVATAR_DEFAULT_SIZE)) page = int(request.GET.get('page', '1')) per_page = int(request.GET.get('per_page', '25')) except ValueError: avatar_size = AVATAR_DEFAULT_SIZE page = 1 per_page = 25 start = (page - 1) * per_page end = page * per_page total_count = FileComment.objects.get_by_file_path(repo_id, path).count() comments = [] if resolved is None: file_comments = FileComment.objects.get_by_file_path(repo_id, path)[start: end] else: comment_resolved = to_python_boolean(resolved) file_comments = FileComment.objects.get_by_file_path(repo_id, path).filter(resolved=comment_resolved)[start: end] for file_comment in file_comments: comment = file_comment.to_dict() comment.update(user_to_dict(file_comment.author, request=request, avatar_size=avatar_size)) comments.append(comment) result = {'comments': comments, 'total_count': total_count} resp = Response(result) base_url = reverse('api2-file-comments', args=[repo_id]) links_header = generate_links_header_for_paginator(base_url, page, per_page, total_count) resp['Links'] = links_header return resp
def get(self, request): """ Get all abuse reports. Permission checking: 1. only admin can perform this action. """ if not ENABLE_SHARE_LINK_REPORT_ABUSE: error_msg = 'Feature not enabled.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if not request.user.admin_permissions.other_permission(): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') abuse_type = request.GET.get('abuse_type', '') handled = request.GET.get('handled', '') if handled: if handled not in ('true', 'false'): error_msg = 'handled invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) handled = to_python_boolean(handled) try: reports = AbuseReport.objects.get_abuse_reports( abuse_type=abuse_type, handled=handled) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) info_list = [] for report in reports: info = get_abuse_report_info(report) info_list.append(info) return Response({ 'abuse_report_list': info_list, })
def put(self, request, virus_id): """ignore or un-ignore virus file """ if not request.user.admin_permissions.other_permission(): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') ignore = request.data.get('ignore') if ignore not in ('true', 'false'): error_msg = 'ignore invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) ignore = to_python_boolean(ignore) virus_file = get_virus_file_by_vid(virus_id) if not virus_file: error_msg = 'Virus file %s not found.' % virus_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: operate_virus_file(virus_id, ignore) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) virus_file = get_virus_file_by_vid(virus_id) repo = seafile_api.get_repo(virus_file.repo_id) repo_owner = seafile_api.get_repo_owner(virus_file.repo_id) res = dict(repo_name=repo.name) res["repo_owner"] = repo_owner res["file_path"] = virus_file.file_path res["has_deleted"] = virus_file.has_deleted res["has_ignored"] = virus_file.has_ignored res["virus_id"] = virus_file.vid return Response({"virus_file": res}, status=status.HTTP_200_OK)
def put(self, request, email): if not request.user.admin_permissions.can_manage_user(): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') # 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 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) # argument check for login_id login_id = request.data.get("login_id", None) if login_id is not None: login_id = login_id.strip() username_by_login_id = Profile.objects.get_username_by_login_id( login_id) if username_by_login_id is not None: return api_error(status.HTTP_400_BAD_REQUEST, _("Login id %s already exists." % login_id)) contact_email = request.data.get("contact_email", None) if contact_email is not None and contact_email.strip() != '': if not is_valid_email(contact_email): error_msg = 'Contact email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) password = request.data.get("password") reference_id = request.data.get("reference_id", None) if reference_id: if ' ' in reference_id: return api_error(status.HTTP_400_BAD_REQUEST, 'Reference ID can not contain spaces.') primary_id = ccnet_api.get_primary_id(reference_id) if primary_id: return api_error( status.HTTP_400_BAD_REQUEST, 'Reference ID %s already exists.' % reference_id) 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) institution = request.data.get("institution", None) if institution: try: Institution.objects.get(name=institution) except Institution.DoesNotExist: error_msg = 'Institution %s does not exist' % institution return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # query user info try: user_obj = User.objects.get(email=email) except User.DoesNotExist: error_msg = 'User %s not found.' % email return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: update_user_info(request, user=user_obj, password=password, is_active=is_active, is_staff=is_staff, role=role, nickname=name, login_id=login_id, contact_email=contact_email, reference_id=reference_id, quota_total_mb=quota_total_mb, institution_name=institution) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) # update user try: user_obj.save() except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) update_status_tip = '' if is_active is not None: update_status_tip = _('Edit succeeded') if user_obj.is_active and IS_EMAIL_CONFIGURED: try: send_html_email( _(u'Your account on %s is activated') % get_site_name(), 'sysadmin/user_activation_email.html', {'username': user_obj.email}, None, [email2contact_email(user_obj.email)]) update_status_tip = _( 'Edit succeeded, an email has been sent.') except Exception as e: logger.error(e) update_status_tip = _( 'Edit succeeded, but failed to send email, please check your email configuration.' ) user_info = get_user_info(email) user_info['update_status_tip'] = update_status_tip return Response(user_info)
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 get(self, request, slug): """List all dir files in a wiki. """ try: wiki = Wiki.objects.get(slug=slug) except Wiki.DoesNotExist: error_msg = "Wiki not found." return api_error(status.HTTP_404_NOT_FOUND, error_msg) # perm check if not wiki.has_read_perm(request): error_msg = "Permission denied" return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: repo = seafile_api.get_repo(wiki.repo_id) if not repo: error_msg = "Wiki library not found." return api_error(status.HTTP_404_NOT_FOUND, error_msg) except SearpcError: error_msg = "Internal Server Error" return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) with_parents = request.GET.get('with_parents', 'false') if with_parents not in ('true', 'false'): error_msg = 'with_parents invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) with_parents = to_python_boolean(with_parents) parent_dir = request.GET.get("p", '/') parent_dir = normalize_dir_path(parent_dir) dir_id = seafile_api.get_dir_id_by_path(repo.repo_id, parent_dir) if not dir_id: error_msg = 'Folder %s not found.' % parent_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) parent_dir_list = [] if not with_parents: # only return dirent list in current parent folder parent_dir_list.append(parent_dir) else: # if value of 'p' parameter is '/a/b/c' add with_parents's is 'true' # then return dirent list in '/', '/a', '/a/b' and '/a/b/c'. if parent_dir == '/': parent_dir_list.append(parent_dir) else: tmp_parent_dir = '/' parent_dir_list.append(tmp_parent_dir) for folder_name in parent_dir.strip('/').split('/'): tmp_parent_dir = posixpath.join(tmp_parent_dir, folder_name) parent_dir_list.append(tmp_parent_dir) all_dirs_info = [] for parent_dir in parent_dir_list: all_dirs = get_wiki_dirs_by_path(repo.repo_id, parent_dir, []) all_dirs_info += all_dirs return Response({"dirent_list": all_dirs_info})
def put(self, request, email, format=None): # argument check for email if not is_valid_username(email): return api_error(status.HTTP_400_BAD_REQUEST, 'Email %s invalid.' % email) # argument check for name name = request.data.get("name", None) if name is not None: if len(name) > 64: return api_error(status.HTTP_400_BAD_REQUEST, _(u'Name is too long (maximum is 64 characters)')) if "/" in name: return api_error(status.HTTP_400_BAD_REQUEST, _(u"Name should not include '/'.")) # argument check for list_in_address_book list_in_address_book = request.data.get("list_in_address_book", None) if list_in_address_book is not None: if list_in_address_book.lower() not in ('true', 'false'): return api_error(status.HTTP_400_BAD_REQUEST, 'list_in_address_book invalid') #argument check for loginid loginid = request.data.get("login_id", None) if loginid is not None: loginid = loginid.strip() if loginid == "": return api_error(status.HTTP_400_BAD_REQUEST, _(u"Login id can't be empty")) usernamebyloginid = Profile.objects.get_username_by_login_id(loginid) if usernamebyloginid is not None: return api_error(status.HTTP_400_BAD_REQUEST, _(u"Login id %s already exists." % loginid)) # argument check for department department = request.data.get("department", None) if department is not None: if len(department) > 512: return api_error(status.HTTP_400_BAD_REQUEST, _(u'Department is too long (maximum is 512 characters)')) # argument check for institution institution = request.data.get("institution", None) if institution is not None and institution != '': try: obj_insti = Institution.objects.get(name=institution) except Institution.DoesNotExist: return api_error(status.HTTP_400_BAD_REQUEST, "Institution %s does not exist" % institution) # argument check for storage space_quota_mb = request.data.get("storage", None) if space_quota_mb is not None: if space_quota_mb == '': return api_error(status.HTTP_400_BAD_REQUEST, _('Space quota can\'t be empty')) try: space_quota_mb = int(space_quota_mb) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, _('Must be an integer that is greater than or equal to 0.')) if space_quota_mb < 0: return api_error(status.HTTP_400_BAD_REQUEST, _('Space quota is too low (minimum value is 0)')) if is_org_context(request): org_id = request.user.org.org_id org_quota_mb = seaserv.seafserv_threaded_rpc.get_org_quota(org_id) / \ get_file_size_unit('MB') if space_quota_mb > org_quota_mb: return api_error(status.HTTP_400_BAD_REQUEST, \ _(u'Failed to set quota: maximum quota is %d MB' % org_quota_mb)) # argument check for is_trial is_trial = request.data.get("is_trial", None) if is_trial is not None: try: is_trial = to_python_boolean(is_trial) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, 'is_trial invalid') try: # update account basic info user = User.objects.get(email=email) # argument check for is_staff is_staff = request.data.get("is_staff", None) if is_staff is not None: try: is_staff = to_python_boolean(is_staff) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, 'is_staff invalid.') user.is_staff = is_staff # argument check for is_active is_active = request.data.get("is_active", None) if is_active is not None: try: is_active = to_python_boolean(is_active) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, 'is_active invalid.') user.is_active = is_active # update password password = request.data.get("password", None) if password is not None: user.set_password(password) # save user result_code = user.save() if result_code == -1: return api_error(status.HTTP_520_OPERATION_FAILED, 'Failed to update user.') try: # update account additional info self._update_account_additional_info(request, email) except Exception as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Internal Server Error') # get account info and return info = get_account_info(user) return Response(info) except User.DoesNotExist: # create user account copy = request.data.copy() copy['email'] = email serializer = AccountSerializer(data=copy) if not serializer.is_valid(): return api_error(status.HTTP_400_BAD_REQUEST, serializer.errors) try: user = User.objects.create_user(serializer.data['email'], serializer.data['password'], serializer.data['is_staff'], serializer.data['is_active']) except User.DoesNotExist as e: logger.error(e) return api_error(status.HTTP_520_OPERATION_FAILED, 'Failed to add user.') try: # update account additional info self._update_account_additional_info(request, email) except Exception as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Internal Server Error') # get account info and return info = get_account_info(user) resp = Response(info, status=status.HTTP_201_CREATED) resp['Location'] = reverse('api2-account', args=[email]) return resp
def get(self, request, repo_id, format=None): """ Get sub dirent list info. Permission checking: 1. user with either 'r' or 'rw' permission. """ # argument check recursive = request.GET.get('recursive', '0') if recursive not in ('1', '0'): error_msg = "If you want to get recursive dir entries, you should set 'recursive' argument as '1'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) request_type = request.GET.get('t', '') if request_type and request_type not in ('f', 'd'): error_msg = "'t'(type) should be 'f' or 'd'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) with_thumbnail = request.GET.get('with_thumbnail', 'false') if with_thumbnail not in ('true', 'false'): error_msg = 'with_thumbnail invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) with_thumbnail = to_python_boolean(with_thumbnail) thumbnail_size = request.GET.get('thumbnail_size', 48) try: thumbnail_size = int(thumbnail_size) except ValueError: error_msg = 'thumbnail_size invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) with_parents = request.GET.get('with_parents', 'false') if with_parents not in ('true', 'false'): error_msg = 'with_parents invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) with_parents = to_python_boolean(with_parents) # recource check repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) parent_dir = request.GET.get('p', '/') parent_dir = normalize_dir_path(parent_dir) dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir) if not dir_id: error_msg = 'Folder %s not found.' % parent_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check permission = check_folder_permission(request, repo_id, parent_dir) if not permission: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # get dir/file list recursively username = request.user.username if recursive == '1': try: dir_file_info_list = get_dir_file_recursively( username, repo_id, parent_dir, []) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) response_dict = {} response_dict['dirent_list'] = [] if request_type == 'f': for item in dir_file_info_list: if item['type'] == 'file': response_dict['dirent_list'].append(item) elif request_type == 'd': for item in dir_file_info_list: if item['type'] == 'dir': response_dict['dirent_list'].append(item) else: response_dict['dirent_list'] = dir_file_info_list return Response(response_dict) parent_dir_list = [] if not with_parents: # only return dirent list in current parent folder parent_dir_list.append(parent_dir) else: # if value of 'p' parameter is '/a/b/c' add with_parents's is 'true' # then return dirent list in '/', '/a', '/a/b' and '/a/b/c'. if parent_dir == '/': parent_dir_list.append(parent_dir) else: tmp_parent_dir = '/' parent_dir_list.append(tmp_parent_dir) for folder_name in parent_dir.strip('/').split('/'): tmp_parent_dir = posixpath.join(tmp_parent_dir, folder_name) tmp_parent_dir = normalize_dir_path(tmp_parent_dir) parent_dir_list.append(tmp_parent_dir) all_dir_info_list = [] all_file_info_list = [] try: for parent_dir in parent_dir_list: # get dir file info list dir_info_list, file_info_list = get_dir_file_info_list( username, request_type, repo, parent_dir, with_thumbnail, thumbnail_size) all_dir_info_list.extend(dir_info_list) all_file_info_list.extend(file_info_list) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) response_dict = {} response_dict["user_perm"] = permission response_dict["dir_id"] = dir_id if request_type == 'f': response_dict['dirent_list'] = all_file_info_list elif request_type == 'd': response_dict['dirent_list'] = all_dir_info_list else: response_dict[ 'dirent_list'] = all_dir_info_list + all_file_info_list return Response(response_dict)
def get(self, request): """ Get smart link of a file/dir. """ # argument check repo_id = request.GET.get('repo_id', None) if not repo_id or not is_valid_repo_id_format(repo_id): error_msg = 'repo_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) path = request.GET.get('path', None) if not path: error_msg = 'path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) is_dir = request.GET.get('is_dir', None) if not is_dir: error_msg = 'is_dir invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) is_dir = is_dir.lower() if is_dir not in ('true', 'false'): error_msg = "is_dir can only be 'true' or 'false'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) is_dir = to_python_boolean(is_dir) if is_dir: if not seafile_api.get_dir_id_by_path(repo_id, normalize_dir_path(path)): error_msg = 'Folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) else: if not seafile_api.get_file_id_by_path(repo_id, normalize_file_path(path)): error_msg = 'File %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check if not check_folder_permission(request, repo_id, '/'): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # make sure path: # 1. starts with '/' # 2. NOT ends with '/' path = normalize_file_path(path) parent_dir = os.path.dirname(path) dirent_name = os.path.basename(path) # get file/dir uuid if repo.is_virtual: repo_id = repo.origin_repo_id path = posixpath.join(repo.origin_path, path.strip('/')) path = normalize_file_path(path) parent_dir = os.path.dirname(path) dirent_name = os.path.basename(path) try: uuid_map = FileUUIDMap.objects.get_or_create_fileuuidmap(repo_id, parent_dir, dirent_name, is_dir) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) dirent_uuid = uuid_map.uuid smart_link = gen_smart_link(dirent_uuid) result = {} result['smart_link'] = smart_link result['smart_link_token'] = dirent_uuid result['name'] = dirent_name return Response(result)
def get(self, request, slug): """List all dir files in a wiki. """ try: wiki = Wiki.objects.get(slug=slug) except Wiki.DoesNotExist: error_msg = "Wiki not found." return api_error(status.HTTP_404_NOT_FOUND, error_msg) # perm check if not wiki.has_read_perm(request): error_msg = "Permission denied" return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: repo = seafile_api.get_repo(wiki.repo_id) if not repo: error_msg = "Wiki library not found." return api_error(status.HTTP_404_NOT_FOUND, error_msg) except SearpcError: error_msg = "Internal Server Error" return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) with_parents = request.GET.get('with_parents', 'false') if with_parents not in ('true', 'false'): error_msg = 'with_parents invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) with_parents = to_python_boolean(with_parents) parent_dir = request.GET.get("p", '/') parent_dir = normalize_dir_path(parent_dir) dir_id = seafile_api.get_dir_id_by_path(repo.repo_id, parent_dir) if not dir_id: error_msg = 'Folder %s not found.' % parent_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) parent_dir_list = [] if not with_parents: # only return dirent list in current parent folder parent_dir_list.append(parent_dir) else: # if value of 'p' parameter is '/a/b/c' add with_parents's is 'true' # then return dirent list in '/', '/a', '/a/b' and '/a/b/c'. if parent_dir == '/': parent_dir_list.append(parent_dir) else: tmp_parent_dir = '/' parent_dir_list.append(tmp_parent_dir) for folder_name in parent_dir.strip('/').split('/'): tmp_parent_dir = posixpath.join(tmp_parent_dir, folder_name) parent_dir_list.append(tmp_parent_dir) all_dirs_info = [] for parent_dir in parent_dir_list: all_dirs = get_wiki_dirs_by_path(repo.repo_id, parent_dir, []) all_dirs_info += all_dirs return Response({ "dirent_list": all_dirs_info })
def get(self, request): """get virus files """ if not request.user.admin_permissions.other_permission(): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') try: page = int(request.GET.get('page', '')) except ValueError: page = 1 try: per_page = int(request.GET.get('per_page', '')) except ValueError: per_page = 25 try: has_handled = to_python_boolean(request.GET.get('has_handled', '')) except ValueError: has_handled = None start = (page - 1) * per_page count = per_page + 1 try: virus_files = get_virus_files(has_handled=has_handled, start=start, limit=count) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if len(virus_files) > per_page: virus_files = virus_files[:per_page] has_next_page = True else: has_next_page = False virus_file_list = list() for virus_file in virus_files: try: repo = seafile_api.get_repo(virus_file.repo_id) repo_owner = seafile_api.get_repo_owner(virus_file.repo_id) except Exception as e: logger.error(e) continue if not repo: continue else: record = dict() record["repo_name"] = repo.name record["repo_owner"] = repo_owner record["file_path"] = virus_file.file_path record["has_deleted"] = virus_file.has_deleted record["has_ignored"] = virus_file.has_ignored record["virus_id"] = virus_file.vid virus_file_list.append(record) return Response( { "virus_file_list": virus_file_list, "has_next_page": has_next_page }, status=status.HTTP_200_OK)
def update_user_info(request, user): # update basic user info password = request.data.get("password") if password: user.set_password(password) is_staff = request.data.get("is_staff") if is_staff: is_staff = to_python_boolean(is_staff) user.is_staff = is_staff is_active = request.data.get("is_active") if is_active: is_active = to_python_boolean(is_active) user.is_active = is_active # update user user.save() email = user.username # update additional user info if is_pro_version(): role = request.data.get("role") if role: User.objects.update_role(email, role) name = request.data.get("name") if name: profile = Profile.objects.get_profile_by_user(email) if profile is None: profile = Profile(user=email) profile.nickname = name profile.save() # update account login_id login_id = request.data.get("login_id", None) if login_id is not None: login_id = login_id.strip() profile = Profile.objects.get_profile_by_user(email) if profile is None: profile = Profile(user=email) profile.login_id = None if login_id == "" else login_id profile.save() reference_id = request.data.get("reference_id", None) if reference_id is not None: reference_id = reference_id.strip() ccnet_api.set_reference_id(email, reference_id) department = request.data.get("department") if department: d_profile = DetailedProfile.objects.get_detailed_profile_by_user(email) if d_profile is None: d_profile = DetailedProfile(user=email) d_profile.department = department d_profile.save() quota_total_mb = request.data.get("quota_total") if quota_total_mb: quota_total = int(quota_total_mb) * get_file_size_unit('MB') if is_org_context(request): org_id = request.user.org.org_id seafile_api.set_org_user_quota(org_id, email, quota_total) else: seafile_api.set_user_quota(email, quota_total)
def _decorated(view, request, *args, **kwargs): file_path = None is_dir = None repo_id = kwargs.get('repo_id') if request.method == 'GET': file_path = request.GET.get('path', '') is_dir = request.GET.get('is_dir', '') elif request.method in ['POST', 'PUT']: file_path = request.data.get('path', '') is_dir = request.data.get('is_dir', '') elif request.method == 'DELETE': file_path = request.GET.get('path', '') is_dir = request.GET.get('is_dir', '') try: repo = seafile_api.get_repo(repo_id) except Exception as e: logger.error(e) error_msg = _('Internal Server Error') return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) if not file_path: error_msg = "p %s invalid." % file_path return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: is_dir = to_python_boolean(is_dir) except ValueError: error_msg = 'is_dir invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # split file_path to filename and parent_path # and check if the file exists new_file_path = file_path.rstrip('/') parent_path = os.path.dirname(new_file_path) filename = os.path.basename(new_file_path) if is_dir: dir_id = seafile_api.get_dir_id_by_path(repo_id, new_file_path) if not dir_id: error_msg = 'Folder %s not found.' % file_path return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if check_folder_permission(request, repo_id, new_file_path) != 'rw': error_msg = _('Permission denied.') return api_error(status.HTTP_403_FORBIDDEN, error_msg) else: if filename.strip() == '': error_msg = 'p %s invalid' % file_path return api_error(status.HTTP_400_BAD_REQUEST, error_msg) file_id = seafile_api.get_file_id_by_path(repo_id, new_file_path) if not file_id: error_msg = 'File %s not found.' % file_path return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if check_folder_permission(request, repo_id, parent_path) != 'rw': error_msg = _('Permission denied.') return api_error(status.HTTP_403_FORBIDDEN, error_msg) kwargs['parent_path'] = parent_path kwargs['filename'] = filename kwargs['is_dir'] = is_dir return func(view, request, *args, **kwargs)
def post(self, request): 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) user_info = get_user_info(email) return Response(user_info)
def get(self, request, org_id): """List organization user """ # resource check org_id = int(org_id) org = ccnet_api.get_org_by_id(org_id) if not org: error_msg = 'Organization %s not found.' % org_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) if request.user.org.org_id != org.org_id: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) is_staff = request.GET.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) org_users = ccnet_api.get_org_users_by_url_prefix( org.url_prefix, -1, -1) users = [] if is_staff: for user in org_users: if is_org_staff(org.org_id, user.email): users.append(user) else: # 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 order_by = request.GET.get('order_by', '').lower().strip() if order_by: if order_by not in ('quota_usage'): error_msg = 'order_by invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) direction = request.GET.get('direction', 'desc').lower().strip() if direction not in ('asc', 'desc'): error_msg = 'direction invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) all_users = ccnet_api.get_org_users_by_url_prefix( org.url_prefix, -1, -1) total_count = len(all_users) if total_count > 500 and \ not getattr(settings, 'ALWAYS_SORT_USERS_BY_QUOTA_USAGE', False): error_msg = _( "There are more than 500 users, and sort is not offered." ) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: data = self.get_info_of_users_order_by_quota_usage( org, all_users, direction, current_page, per_page) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) result = { 'user_list': data, 'page': current_page, 'per_page': per_page, 'page_next': (current_page - 1) * per_page + len(data) < total_count, 'total_count': total_count } return Response(result) else: users_plus_one = ccnet_api.get_org_users_by_url_prefix( org.url_prefix, per_page * (current_page - 1), per_page + 1) if len(users_plus_one) == per_page + 1: page_next = True else: page_next = False users = users_plus_one[:per_page] last_logins = UserLastLogin.objects.filter( username__in=[x.email for x in users]) user_list = [] for user in users: user_info = get_user_info(user.email, org_id) # populate user last login time user_info['last_login'] = None for last_login in last_logins: if last_login.username == user.email: user_info['last_login'] = datetime_to_isoformat_timestr( last_login.last_login) user_info['is_active'] = user.is_active user_info['is_staff'] = user.is_staff user_info['create_time'] = timestamp_to_isoformat_timestr( user.ctime) user_list.append(user_info) if is_staff: return Response({'user_list': user_list}) else: return Response({ 'user_list': user_list, 'page': current_page, 'per_page': per_page, 'page_next': page_next })
def update_user_info(request, user): # update basic user info password = request.data.get("password") if password: user.set_password(password) is_staff = request.data.get("is_staff") if is_staff: is_staff = to_python_boolean(is_staff) user.is_staff = is_staff is_active = request.data.get("is_active") if is_active: is_active = to_python_boolean(is_active) user.is_active = is_active # update user user.save() email = user.username # update additional user info if is_pro_version(): role = request.data.get("role") if role: User.objects.update_role(email, role) nickname = request.data.get("name", None) if nickname is not None: Profile.objects.add_or_update(email, nickname) # update account login_id login_id = request.data.get("login_id", None) if login_id is not None: Profile.objects.add_or_update(email, login_id=login_id) # update account contact email contact_email = request.data.get('contact_email', None) if contact_email is not None: Profile.objects.add_or_update(email, contact_email=contact_email) key = normalize_cache_key(email, CONTACT_CACHE_PREFIX) cache.set(key, contact_email, CONTACT_CACHE_TIMEOUT) reference_id = request.data.get("reference_id", None) if reference_id is not None: if reference_id.strip(): ccnet_api.set_reference_id(email, reference_id.strip()) else: # remove reference id ccnet_api.set_reference_id(email, None) department = request.data.get("department") if department: d_profile = DetailedProfile.objects.get_detailed_profile_by_user(email) if d_profile is None: d_profile = DetailedProfile(user=email) d_profile.department = department d_profile.save() quota_total_mb = request.data.get("quota_total") if quota_total_mb: quota_total = int(quota_total_mb) * get_file_size_unit('MB') if is_org_context(request): org_id = request.user.org.org_id seafile_api.set_org_user_quota(org_id, email, quota_total) else: seafile_api.set_user_quota(email, quota_total)
def put(self, request, email): # 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) # argument check for login_id login_id = request.data.get("login_id", None) if login_id is not None: login_id = login_id.strip() username_by_login_id = Profile.objects.get_username_by_login_id(login_id) if username_by_login_id is not None: return api_error(status.HTTP_400_BAD_REQUEST, _(u"Login id %s already exists." % login_id)) contact_email = request.data.get("contact_email", None) if contact_email is not None and contact_email.strip() != '': if not is_valid_email(contact_email): error_msg = 'Contact email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) profile = Profile.objects.get_profile_by_contact_email(contact_email) if profile: error_msg = 'Contact email %s already exists.' % contact_email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) reference_id = request.data.get("reference_id", "") if reference_id: if ' ' in reference_id: return api_error(status.HTTP_400_BAD_REQUEST, 'Reference ID can not contain spaces.') primary_id = ccnet_api.get_primary_id(reference_id) if primary_id: return api_error(status.HTTP_400_BAD_REQUEST, 'Reference ID %s already exists.' % reference_id) 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) # query user info try: user_obj = User.objects.get(email=email) except User.DoesNotExist: error_msg = 'User %s not found.' % email return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: 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) user_info = get_user_info(email) return Response(user_info)
def _update_account(self, request, user): password = request.DATA.get("password", None) is_staff = request.DATA.get("is_staff", None) if is_staff is not None: try: is_staff = to_python_boolean(is_staff) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, '%s is not a valid value' % is_staff) is_active = request.DATA.get("is_active", None) if is_active is not None: try: is_active = to_python_boolean(is_active) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, '%s is not a valid value' % is_active) if password is not None: user.set_password(password) if is_staff is not None: user.is_staff = is_staff if is_active is not None: user.is_active = is_active result_code = user.save() if result_code == -1: return api_error(status.HTTP_403_FORBIDDEN, 'Fail to update user.') self._update_account_profile(request, user.username) try: self._update_account_quota(request, user.username) except SearpcError as e: logger.error(e) return api_error(HTTP_520_OPERATION_FAILED, 'Failed to set account quota') is_trial = request.DATA.get("is_trial", None) if is_trial is not None: try: from seahub_extra.trialaccount.models import TrialAccount except ImportError: pass else: try: is_trial = to_python_boolean(is_trial) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, '%s is not a valid value' % is_trial) if is_trial is True: expire_date = timezone.now() + relativedelta(days=7) TrialAccount.object.create_or_update(user.username, expire_date) else: TrialAccount.objects.filter(user_or_org=user.username).delete() return Response('success')
def get(self, request, org_id): """List organization user """ # 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) org = request.user.org is_staff = request.GET.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) org_users = ccnet_api.get_org_users_by_url_prefix( org.url_prefix, -1, -1) users = [] if is_staff: for user in org_users: if is_org_staff(org.org_id, user.email): users.append(user) else: # 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 users_plus_one = ccnet_api.get_org_users_by_url_prefix( org.url_prefix, per_page * (current_page - 1), per_page + 1) if len(users_plus_one) == per_page + 1: page_next = True else: page_next = False users = users_plus_one[:per_page] last_logins = UserLastLogin.objects.filter( username__in=[x.email for x in users]) user_list = [] for user in users: user_info = get_user_info(user.email, org_id) # populate user last login time user_info['last_login'] = None for last_login in last_logins: if last_login.username == user.email: user_info['last_login'] = datetime_to_isoformat_timestr( last_login.last_login) user_info['id'] = user.id user_info['is_active'] = user.is_active user_info['ctime'] = timestamp_to_isoformat_timestr(user.ctime) # these two fields are designed to be compatible with the old API user_info['self_usage'] = user_info.get('quota_usage') user_info['quota'] = user_info.get('quota_total') user_list.append(user_info) if is_staff: return Response({'user_list': user_list}) else: return Response({ 'user_list': user_list, 'per_page': per_page, 'page': current_page, 'page_next': page_next })
def get(self, request): """ Get smart link of a file/dir. """ # argument check repo_id = request.GET.get('repo_id', None) if not repo_id or not is_valid_repo_id_format(repo_id): error_msg = 'repo_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) path = request.GET.get('path', None) if not path: error_msg = 'path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) is_dir = request.GET.get('is_dir', None) if not is_dir: error_msg = 'is_dir invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) is_dir = is_dir.lower() if is_dir not in ('true', 'false'): error_msg = "is_dir can only be 'true' or 'false'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) is_dir = to_python_boolean(is_dir) if is_dir: if not seafile_api.get_dir_id_by_path(repo_id, normalize_dir_path(path)): error_msg = 'Folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) else: if not seafile_api.get_file_id_by_path(repo_id, normalize_file_path(path)): error_msg = 'File %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check if not check_folder_permission(request, repo_id, '/'): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # make sure path: # 1. starts with '/' # 2. NOT ends with '/' path = normalize_file_path(path) parent_dir = os.path.dirname(path) dirent_name = os.path.basename(path) # get file/dir uuid if repo.is_virtual: repo_id = repo.origin_repo_id path = posixpath.join(repo.origin_path, path.strip('/')) path = normalize_file_path(path) parent_dir = os.path.dirname(path) dirent_name = os.path.basename(path) try: uuid_map = FileUUIDMap.objects.get_or_create_fileuuidmap(repo_id, parent_dir, dirent_name, is_dir) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) dirent_uuid = uuid_map.uuid smart_link = gen_smart_link(dirent_uuid, dirent_name) result = {} result['smart_link'] = smart_link result['smart_link_token'] = dirent_uuid return Response(result)
def put(self, request, email, format=None): # argument check for email if not is_valid_username(email): return api_error(status.HTTP_400_BAD_REQUEST, 'Email %s invalid.' % email) # argument check for name name = request.data.get("name", None) if name is not None: if len(name) > 64: return api_error( status.HTTP_400_BAD_REQUEST, _(u'Name is too long (maximum is 64 characters)')) if "/" in name: return api_error(status.HTTP_400_BAD_REQUEST, _(u"Name should not include '/'.")) # argument check for department department = request.data.get("department", None) if department is not None: if len(department) > 512: return api_error( status.HTTP_400_BAD_REQUEST, _(u'Department is too long (maximum is 512 characters)')) # argument check for storage space_quota_mb = request.data.get("storage", None) if space_quota_mb is not None: if space_quota_mb == '': return api_error(status.HTTP_400_BAD_REQUEST, _('Space quota can\'t be empty')) try: space_quota_mb = int(space_quota_mb) except ValueError: return api_error( status.HTTP_400_BAD_REQUEST, _('Must be an integer that is greater than or equal to 0.') ) if space_quota_mb < 0: return api_error( status.HTTP_400_BAD_REQUEST, _('Space quota is too low (minimum value is 0)')) if is_org_context(request): org_id = request.user.org.org_id org_quota_mb = seaserv.seafserv_threaded_rpc.get_org_quota(org_id) / \ get_file_size_unit('MB') if space_quota_mb > org_quota_mb: return api_error(status.HTTP_400_BAD_REQUEST, \ _(u'Failed to set quota: maximum quota is %d MB' % org_quota_mb)) # argument check for is_trial is_trial = request.data.get("is_trial", None) if is_trial is not None: try: is_trial = to_python_boolean(is_trial) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, 'is_trial invalid') try: # update account basic info user = User.objects.get(email=email) # argument check for is_staff is_staff = request.data.get("is_staff", None) if is_staff is not None: try: is_staff = to_python_boolean(is_staff) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, 'is_staff invalid.') user.is_staff = is_staff # argument check for is_active is_active = request.data.get("is_active", None) if is_active is not None: try: is_active = to_python_boolean(is_active) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, 'is_active invalid.') user.is_active = is_active # update password password = request.data.get("password", None) if password is not None: user.set_password(password) # save user result_code = user.save() if result_code == -1: return api_error(status.HTTP_520_OPERATION_FAILED, 'Failed to update user.') try: # update account additional info self._update_account_additional_info(request, email) except Exception as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Internal Server Error') # get account info and return info = get_account_info(user) return Response(info) except User.DoesNotExist: # create user account copy = request.data.copy() copy['email'] = email serializer = AccountSerializer(data=copy) if not serializer.is_valid(): return api_error(status.HTTP_400_BAD_REQUEST, serializer.errors) try: user = User.objects.create_user(serializer.data['email'], serializer.data['password'], serializer.data['is_staff'], serializer.data['is_active']) except User.DoesNotExist as e: logger.error(e) return api_error(status.HTTP_520_OPERATION_FAILED, 'Failed to add user.') try: # update account additional info self._update_account_additional_info(request, email) except Exception as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Internal Server Error') # get account info and return info = get_account_info(user) resp = Response(info, status=status.HTTP_201_CREATED) resp['Location'] = reverse('api2-account', args=[email]) return resp
def put(self, request, repo_id, comment_id, format=None): """Update a comment, only comment author or repo owner can perform this op 1.Change resolved of comment 2.Add comment_detail """ # argument check resolved = request.data.get('resolved') if resolved not in ('true', 'false', None): error_msg = 'resolved invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) detail = request.data.get('detail') # resource check try: file_comment = FileComment.objects.get(pk=comment_id) except FileComment.DoesNotExist: error_msg = 'FileComment %s not found.' % comment_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check if check_folder_permission(request, repo_id, '/') != PERMISSION_READ_WRITE: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if resolved is not None: comment_resolved = to_python_boolean(resolved) try: file_comment.resolved = comment_resolved file_comment.save() except Exception as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Internal error.') if detail is not None: try: file_comment.detail = detail file_comment.save() except Exception as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Internal error.') comment = request.data.get('comment') if comment is not None: try: file_comment.comment = comment file_comment.save() except Exception as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Internal error.') try: avatar_size = int(request.GET.get('avatar_size', AVATAR_DEFAULT_SIZE)) except ValueError: avatar_size = AVATAR_DEFAULT_SIZE comment = file_comment.to_dict() comment.update(user_to_dict(file_comment.author, request=request, avatar_size=avatar_size)) return Response(comment)
def put(self, request, email): # 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) # argument check for login_id login_id = request.data.get("login_id", None) if login_id is not None: login_id = login_id.strip() username_by_login_id = Profile.objects.get_username_by_login_id( login_id) if username_by_login_id is not None: return api_error(status.HTTP_400_BAD_REQUEST, _(u"Login id %s already exists." % login_id)) reference_id = request.data.get("reference_id", "").strip() if reference_id: if ' ' in reference_id: return api_error(status.HTTP_400_BAD_REQUEST, 'Reference ID can not contain spaces.') primary_id = ccnet_api.get_primary_id(reference_id) if primary_id: return api_error( status.HTTP_400_BAD_REQUEST, 'Reference ID %s already exists.' % reference_id) 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) # query user info try: user_obj = User.objects.get(email=email) except User.DoesNotExist: error_msg = 'User %s not found.' % email return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: 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) user_info = get_user_info(email) return Response(user_info)
def get(self, request, repo_id, format=None): """ Get sub dirent list info. Permission checking: 1. user with either 'r' or 'rw' permission. """ # argument check recursive = request.GET.get('recursive', '0') if recursive not in ('1', '0'): error_msg = "If you want to get recursive dir entries, you should set 'recursive' argument as '1'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) request_type = request.GET.get('t', '') if request_type and request_type not in ('f', 'd'): error_msg = "'t'(type) should be 'f' or 'd'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) with_thumbnail = request.GET.get('with_thumbnail', 'false') if with_thumbnail not in ('true', 'false'): error_msg = 'with_thumbnail invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) with_thumbnail = to_python_boolean(with_thumbnail) thumbnail_size = request.GET.get('thumbnail_size', 48) try: thumbnail_size = int(thumbnail_size) except ValueError: error_msg = 'thumbnail_size invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) with_parents = request.GET.get('with_parents', 'false') if with_parents not in ('true', 'false'): error_msg = 'with_parents invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) with_parents = to_python_boolean(with_parents) # recource check repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) parent_dir = request.GET.get('p', '/') parent_dir = normalize_dir_path(parent_dir) dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir) if not dir_id: error_msg = 'Folder %s not found.' % parent_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check permission = check_folder_permission(request, repo_id, parent_dir) if not permission: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # get dir/file list recursively username = request.user.username if recursive == '1': try: dir_file_info_list = get_dir_file_recursively(username, repo_id, parent_dir, []) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) response_dict = {} response_dict['dirent_list'] = [] if request_type == 'f': for item in dir_file_info_list: if item['type'] == 'file': response_dict['dirent_list'].append(item) elif request_type == 'd': for item in dir_file_info_list: if item['type'] == 'dir': response_dict['dirent_list'].append(item) else: response_dict['dirent_list'] = dir_file_info_list return Response(response_dict) parent_dir_list = [] if not with_parents: # only return dirent list in current parent folder parent_dir_list.append(parent_dir) else: # if value of 'p' parameter is '/a/b/c' add with_parents's is 'true' # then return dirent list in '/', '/a', '/a/b' and '/a/b/c'. if parent_dir == '/': parent_dir_list.append(parent_dir) else: tmp_parent_dir = '/' parent_dir_list.append(tmp_parent_dir) for folder_name in parent_dir.strip('/').split('/'): tmp_parent_dir = posixpath.join(tmp_parent_dir, folder_name) tmp_parent_dir = normalize_dir_path(tmp_parent_dir) parent_dir_list.append(tmp_parent_dir) all_dir_info_list = [] all_file_info_list = [] try: for parent_dir in parent_dir_list: # get dir file info list dir_info_list, file_info_list = get_dir_file_info_list(username, request_type, repo, parent_dir, with_thumbnail, thumbnail_size) all_dir_info_list.extend(dir_info_list) all_file_info_list.extend(file_info_list) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) response_dict = {} response_dict["user_perm"] = permission response_dict["dir_id"] = dir_id if request_type == 'f': response_dict['dirent_list'] = all_file_info_list elif request_type == 'd': response_dict['dirent_list'] = all_dir_info_list else: response_dict['dirent_list'] = all_dir_info_list + all_file_info_list return Response(response_dict)
def put(self, request, org_id, email): """ update name of an org user. Permission checking: 1. only admin can perform this action. """ # 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) try: user = User.objects.get(email=email) except User.DoesNotExist: error_msg = 'User %s not found.' % email return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check if not is_org_user(email, org_id): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # update user's name name = request.data.get("name", None) if name is not None: name = name.strip() 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: Profile.objects.add_or_update(email, nickname=name) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) # update user's contact email contact_email = request.data.get("contact_email", None) if contact_email is not None: contact_email = contact_email.strip() 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) try: Profile.objects.add_or_update(email, contact_email=contact_email) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) is_staff = request.data.get("is_staff", None) if is_staff is not None: 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) if is_staff: if is_org_staff(org_id, user.username): error_msg = '%s is already organization staff.' % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) set_org_staff(org_id, user.username) if not is_staff: if not is_org_staff(org_id, user.username): error_msg = '%s is not organization staff.' % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) unset_org_staff(org_id, user.username) 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) org_quota = seafile_api.get_org_quota(org_id) org_quota_mb = org_quota / get_file_size_unit('MB') # -1 means org has unlimited quota if org_quota > 0 and quota_total_mb > org_quota_mb: error_msg = _(u'Failed to set quota: maximum quota is %d MB' % org_quota_mb) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) quota_total = int(quota_total_mb) * get_file_size_unit('MB') try: seafile_api.set_org_user_quota(org_id, email, quota_total) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) info = get_user_info(email, org_id) info['is_active'] = user.is_active info['id'] = user.id info['ctime'] = timestamp_to_isoformat_timestr(user.ctime) try: last_login = UserLastLogin.objects.get(username=user.email) info['last_login'] = datetime_to_isoformat_timestr( last_login.last_login) except UserLastLogin.DoesNotExist: info['last_login'] = None # these two fields are designed to be compatible with the old API info['self_usage'] = info.get('quota_usage') info['quota'] = info.get('quota_total') return Response(info)
def parse_repo_perm(perm): RP = namedtuple( 'RepoPerm', [ 'can_download', 'can_upload', # download/upload files/folders 'can_edit_on_web', # edit files on web 'can_delete', # delete files/folders 'can_copy', # copy files/folders on web 'can_preview', # preview files on web 'can_generate_share_link', # generate share link ]) if perm not in get_available_repo_perms(): try: if CUSTOM_PERMISSION_PREFIX in perm: perm = perm.split('-')[1] custom_perm_obj = CustomSharePermissions.objects.get( id=int(perm)).to_dict() RP.can_download = to_python_boolean( str(custom_perm_obj['permission'].get('download', False))) RP.can_upload = to_python_boolean( str(custom_perm_obj['permission'].get('upload', False))) RP.can_edit_on_web = to_python_boolean( str(custom_perm_obj['permission'].get('modify', False))) RP.can_copy = to_python_boolean( str(custom_perm_obj['permission'].get('copy', False))) RP.can_delete = to_python_boolean( str(custom_perm_obj['permission'].get('delete', False))) RP.can_preview = to_python_boolean( str(custom_perm_obj['permission'].get('preview', False))) RP.can_generate_share_link = to_python_boolean( str(custom_perm_obj['permission'].get('download_external_link', False))) return RP except Exception as e: logger.warning(e) RP.can_download = True if perm in [ PERMISSION_READ, PERMISSION_READ_WRITE, PERMISSION_ADMIN ] else False RP.can_upload = True if perm in [PERMISSION_READ_WRITE, PERMISSION_ADMIN ] else False RP.can_edit_on_web = True if perm in [ PERMISSION_READ_WRITE, PERMISSION_ADMIN, PERMISSION_PREVIEW_EDIT ] else False RP.can_copy = True if perm in [ PERMISSION_READ, PERMISSION_READ_WRITE, PERMISSION_ADMIN, ] else False RP.can_delete = True if perm in [ PERMISSION_READ_WRITE, PERMISSION_ADMIN, ] else False RP.can_preview = True if perm in [ PERMISSION_READ, PERMISSION_READ_WRITE, PERMISSION_ADMIN, PERMISSION_PREVIEW, PERMISSION_PREVIEW_EDIT ] else False RP.can_generate_share_link = True if perm in [ PERMISSION_READ_WRITE, PERMISSION_READ, PERMISSION_ADMIN, PERMISSION_PREVIEW, PERMISSION_PREVIEW_EDIT ] else False return RP