Exemple #1
0
    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")
Exemple #2
0
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)
Exemple #3
0
    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)
Exemple #4
0
    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)
Exemple #5
0
    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
Exemple #6
0
    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)
Exemple #7
0
    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
Exemple #8
0
    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)
Exemple #9
0
    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)
Exemple #10
0
    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)
Exemple #11
0
    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)
Exemple #12
0
    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)
Exemple #13
0
    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
Exemple #14
0
    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,
        })
Exemple #15
0
    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)
Exemple #16
0
    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)
Exemple #17
0
    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)
Exemple #18
0
    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})
Exemple #19
0
    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
Exemple #20
0
    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)
Exemple #21
0
    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)
Exemple #22
0
    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
        })
Exemple #23
0
    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)
Exemple #24
0
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)
Exemple #25
0
    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)
Exemple #26
0
    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)
Exemple #27
0
    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
            })
Exemple #28
0
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)
Exemple #29
0
    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)
Exemple #30
0
    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)
Exemple #31
0
    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')
Exemple #32
0
    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
            })
Exemple #33
0
    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)
Exemple #34
0
    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)
Exemple #35
0
    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
Exemple #36
0
    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)
Exemple #37
0
    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)
Exemple #38
0
    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)
Exemple #39
0
    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)
Exemple #40
0
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