Exemple #1
0
def get_related_users_by_repo(repo_id, org_id=None):
    """ Return all users who can view this library.

    1. repo owner
    2. users repo has been shared to
    3. members of groups repo has been shared to
    """

    users = []

    if org_id:
        repo_owner = seafile_api.get_org_repo_owner(repo_id)
        user_shared_to = seafile_api.list_org_repo_shared_to(org_id,
                repo_owner, repo_id)
    else:
        repo_owner = seafile_api.get_repo_owner(repo_id)
        user_shared_to = seafile_api.list_repo_shared_to(
                repo_owner, repo_id)

    # 1. repo owner
    users.append(repo_owner)

    # 2. users repo has been shared to
    for user in user_shared_to:
        users.append(user.user)

    # 3. members of groups repo has been shared to
    groups = get_shared_groups_by_repo(repo_id, org_id)
    for group in groups:
        members = ccnet_api.get_group_members(group.id)
        for member in members:
            if member.user_name not in users:
                users.append(member.user_name)

    return users
Exemple #2
0
    def format_repo_share_msg(self, notice):
        d = json.loads(notice.detail)
        repo_id = d['repo_id']
        repo = seafile_api.get_repo(repo_id)
        path = d['path']
        org_id = d.get('org_id', None)
        if path == '/':
            shared_type = 'library'
        else:
            shared_type = 'folder'
            if org_id:
                owner = seafile_api.get_org_repo_owner(repo_id)
                repo = seafile_api.get_org_virtual_repo(
                    org_id, repo_id, path, owner)
            else:
                owner = seafile_api.get_repo_owner(repo_id)
                repo = seafile_api.get_virtual_repo(repo_id, path, owner)

        repo_url = reverse('lib_view', args=[repo_id, repo.name, ''])
        notice.repo_url = repo_url
        notice.notice_from = escape(email2nickname(d['share_from']))
        notice.repo_name = repo.name
        notice.avatar_src = self.get_avatar_src(d['share_from'])
        notice.shared_type = shared_type

        return notice
Exemple #3
0
def is_repo_admin(username, repo_id):

    repo_owner = seafile_api.get_repo_owner(repo_id)

    try:
        if '@seafile_group' in repo_owner:
            # is group owned repo
            group_id = int(repo_owner.split('@')[0])
            if is_group_admin(group_id, username):
                return True
        else:
            user_share_permission = ExtraSharePermission.objects.\
                    get_user_permission(repo_id, username)
            if user_share_permission == PERMISSION_ADMIN:
                return True

            # get all groups that repo is shared to with admin permission
            group_ids = ExtraGroupsSharePermission.objects.get_admin_groups_by_repo(repo_id)
            for group_id in group_ids:
                if is_group_admin(group_id, username):
                    return True
        return False
    except Exception as e:
        logger.error(e)
        return False
Exemple #4
0
def repo_history_view(request, repo_id):
    """View repo in history.
    """
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    username = request.user.username
    path = get_path_from_request(request)
    user_perm = check_folder_permission(request, repo.id, '/')
    if user_perm is None:
        return render_error(request, _(u'Permission denied'))

    try:
        server_crypto = UserOptions.objects.is_server_crypto(username)
    except CryptoOptionNotSetError:
        # Assume server_crypto is ``False`` if this option is not set.
        server_crypto = False

    if repo.encrypted and \
        (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \
        and not is_password_set(repo.id, username):
        return render_to_response(
            'decrypt_repo_form.html', {
                'repo':
                repo,
                'next':
                get_next_url_from_request(request)
                or reverse('repo', args=[repo.id]),
                'force_server_crypto':
                FORCE_SERVER_CRYPTO,
            },
            context_instance=RequestContext(request))

    commit_id = request.GET.get('commit_id', None)
    if commit_id is None:
        return HttpResponseRedirect(reverse('repo', args=[repo.id]))
    current_commit = get_commit(repo.id, repo.version, commit_id)
    if not current_commit:
        current_commit = get_commit(repo.id, repo.version, repo.head_cmmt_id)

    file_list, dir_list, dirent_more = get_repo_dirents(
        request, repo, current_commit, path)
    zipped = get_nav_path(path, repo.name)

    repo_owner = seafile_api.get_repo_owner(repo.id)
    is_repo_owner = True if username == repo_owner else False

    return render_to_response(
        'repo_history_view.html', {
            'repo': repo,
            "is_repo_owner": is_repo_owner,
            'user_perm': user_perm,
            'current_commit': current_commit,
            'dir_list': dir_list,
            'file_list': file_list,
            'path': path,
            'zipped': zipped,
        },
        context_instance=RequestContext(request))
def get_group_repos(username, org_id, groups):
    """Get repos shared to groups.
    """
    group_repos = []
    if org_id:
        # For each group I joined...
        for grp in groups:
            # Get group repos, and for each group repos...
            for r_id in seafile_api.get_org_group_repoids(org_id, grp.id):
                # No need to list my own repo
                repo_owner = seafile_api.get_org_repo_owner(r_id)
                if repo_owner == username:
                    continue
                group_repos.append(r_id)
    else:
        # For each group I joined...
        for grp in groups:
            # Get group repos, and for each group repos...
            for r_id in seafile_api.get_group_repoids(grp.id):
                # No need to list my own repo
                repo_owner = seafile_api.get_repo_owner(r_id)
                if repo_owner == username:
                    continue
                group_repos.append(r_id)
    return group_repos
Exemple #6
0
def repo_online_gc(request, repo_id):
    if request.method != 'POST':
        raise Http404

    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    referer = request.META.get('HTTP_REFERER', None)
    next = settings.SITE_ROOT if referer is None else referer

    username = request.user.username
    if is_org_context(request):
        repo_owner = seafile_api.get_org_repo_owner(repo.id)
    else:
        repo_owner = seafile_api.get_repo_owner(repo.id)
    is_repo_owner = True if repo_owner == username else False
    if not is_repo_owner:
        messages.error(request, _('Permission denied'))
        return HttpResponseRedirect(next)

    day = int(request.POST.get('day'))
    try:
        seafile_api.clean_up_repo_history(repo.id, day)
    except SearpcError as e:
        logger.error(e)
        messages.error(request, _('Internal server error'))
        return HttpResponseRedirect(next)

    return HttpResponseRedirect(next)
    def check_repo_owner_quota(self, isnewfile=True, contentlength=-1):
        """Check if the upload would cause the user quota be exceeded

        `contentlength` is only positive when the client does not use "transfer-encode: chunking"

        Return True if the quota would not be exceeded, otherwise return False.
        """
        if contentlength <= 0:
            # When client use "transfer-encode: chunking", the content length
            # is not included in the request headers
            if isnewfile:
                return check_repo_quota(self.repo.id) >= 0
            else:
                return True

        if not self.owner:
            self.owner = seafile_api.get_repo_owner(self.repo.id)
        quota = seafile_api.get_user_quota(self.owner)
        if quota == INFINITE_QUOTA:
            return True
        self_usage = seafile_api.get_user_self_usage(self.owner)
        share_usage = seafile_api.get_user_share_usage(self.owner) if CALC_SHARE_USAGE else 0

        remain = quota - self_usage - share_usage
        if not isnewfile:
            remain -= self.obj.size

        return contentlength <= remain
Exemple #8
0
    def repo_restored_cb(sender, **kwargs):
        repo_id = kwargs['repo_id']
        operator = kwargs['operator']
        repo = seafile_api.get_repo(repo_id)
        org_id = get_org_id_by_repo_id(repo_id)
        if org_id > 0:
            related_users = seafile_api.org_get_shared_users_by_repo(org_id, repo_id)
            repo_owner = seafile_api.get_org_repo_owner(repo_id)
        else:
            related_users = seafile_api.get_shared_users_by_repo(repo_id)
            repo_owner = seafile_api.get_repo_owner(repo_id)

        related_users.append(repo_owner)

        record = {
            'op_type':'recover',
            'obj_type':'repo',
            'timestamp': datetime.datetime.utcnow(),
            'repo_id': repo_id,
            'repo_name': repo.repo_name,
            'path': '/',
            'op_user': operator,
            'related_users': [related_users],
            'org_id': org_id,
        }

        from utils import SeafEventsSession
        session = SeafEventsSession()
        seafevents.save_user_activity(session, record)
        session.close()
Exemple #9
0
def sys_repo_admin(request):
    # 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', '25'))
    except ValueError:
        current_page = 1
        per_page = 25

    repos_all = seafile_api.get_repo_list(per_page * (current_page -1),
                                          per_page + 1)
    repos = repos_all[:per_page]
    if len(repos_all) == per_page + 1:
        page_next = True
    else:
        page_next = False

    for repo in repos:
        try:
            repo.owner = seafile_api.get_repo_owner(repo.id)
        except:
            repo.owner = "failed to get"

    return render_to_response(
        'sysadmin/sys_repo_admin.html', {
            'repos': repos,
            'current_page': current_page,
            'prev_page': current_page-1,
            'next_page': current_page+1,
            'per_page': per_page,
            'page_next': page_next,
        },
        context_instance=RequestContext(request))
Exemple #10
0
def get_repo_info(repo):

    repo_owner = seafile_api.get_repo_owner(repo.repo_id)
    if not repo_owner:
        try:
            org_repo_owner = seafile_api.get_org_repo_owner(repo.repo_id)
        except Exception:
            org_repo_owner = None

    owner = repo_owner or org_repo_owner or ''

    result = {}
    result['id'] = repo.repo_id
    result['name'] = repo.repo_name
    result['owner'] = owner
    result['owner_email'] = owner
    result['owner_name'] = email2nickname(owner)
    result['owner_contact_email'] = email2contact_email(owner)
    result['size'] = repo.size
    result['size_formatted'] = filesizeformat(repo.size)
    result['encrypted'] = repo.encrypted
    result['file_count'] = repo.file_count

    if '@seafile_group' in owner:
        group_id = get_group_id_by_repo_owner(owner)
        result['group_name'] = group_id_to_name(group_id)

    return result
Exemple #11
0
    def get(self, request, format=None):
        username = request.user.username
        shared_repos = []
        shared_repos += seafile_api.get_share_in_repo_list(username, -1, -1)

        joined_groups = get_personal_groups_by_user(username)
        for grp in joined_groups:
        # Get group repos, and for each group repos...
            for r_id in get_group_repoids(grp.id):
                # No need to list my own repo
                if seafile_api.is_repo_owner(username, r_id):
                    continue
                 # Convert repo properties due to the different collumns in Repo
                 # and SharedRepo
                r = get_repo(r_id)
                if not r:
                    continue
                r.repo_id = r.id
                r.repo_name = r.name
                r.repo_desc = r.desc
                cmmts = get_commits(r_id, 0, 1)
                last_commit = cmmts[0] if cmmts else None
                r.last_modified = last_commit.ctime if last_commit else 0
                r.share_type = 'group'
                r.user = seafile_api.get_repo_owner(r_id)
                r.user_perm = check_permission(r_id, username)
                shared_repos.append(r)

        if not CLOUD_MODE:
            shared_repos += list_inner_pub_repos(username)

        return HttpResponse(json.dumps(shared_repos, cls=SearpcObjEncoder),
                            status=200, content_type=json_content_type)
    def email_repo_owner(self, repo_file):
        repo_id, file_path = repo_file.split(':', 1)
        owner = seafile_api.get_repo_owner(repo_id)
        if not owner:
            return

        # save current language
        cur_language = translation.get_language()

        # get and active user language
        user_language = self.get_user_language(owner)
        translation.activate(user_language)

        contact_email = Profile.objects.get_contact_email_by_user(owner)
        send_html_email_with_dj_template(
            contact_email, dj_template='notifications/notify_virus.html',
            context={'owner': owner,
                     'file_url': reverse('view_lib_file',
                                         args=[repo_id, file_path]),
                     'file_name': os.path.basename(file_path),
                 },
            subject=_('Virus detected on %s') % get_site_name(),
            priority=MAIL_PRIORITY.now
        )

        # restore current language
        translation.activate(cur_language)
Exemple #13
0
    def format_repo_share_to_group_msg(self):
        """

        Arguments:
        - `self`:
        """
        try:
            d = json.loads(self.detail)
        except Exception as e:
            logger.error(e)
            return _(u"Internal error")

        share_from = email2nickname(d['share_from'])
        repo_id = d['repo_id']
        group_id = d['group_id']
        path = d.get('path', '/')
        org_id = d.get('org_id', None)

        repo = None
        try:
            group = ccnet_api.get_group(group_id)
            if path == '/':
                repo = seafile_api.get_repo(repo_id)
            else:
                if org_id:
                    owner = seafile_api.get_org_repo_owner(repo_id)
                    repo = seafile_api.get_org_virtual_repo(
                        org_id, repo_id, path, owner)
                else:
                    owner = seafile_api.get_repo_owner(repo_id)
                    repo = seafile_api.get_virtual_repo(repo_id, path, owner)
        except Exception as e:
            logger.error(e)
            return None

        if not repo or not group:
            self.delete()
            return None

        if path == '/':
            tmpl = 'notifications/notice_msg/repo_share_to_group_msg.html'
        else:
            tmpl = 'notifications/notice_msg/folder_share_to_group_msg.html'

        lib_url = reverse('lib_view', args=[repo.id, repo.name, ''])
        group_url = reverse('group', args=[group.id])
        msg = render_to_string(tmpl, {
            'user': share_from,
            'lib_url': lib_url,
            'lib_name': repo.name,
            'group_url': group_url,
            'group_name': group.group_name,
        })

        return msg
Exemple #14
0
def get_repo_owner(request, repo_id):
    if is_org_context(request):
        repo_owner = seafile_api.get_org_repo_owner(repo_id)
    else:
        # for admin panel
        # administrator may get org repo's owner
        repo_owner = seafile_api.get_repo_owner(repo_id)
        if not repo_owner:
            repo_owner = seafile_api.get_org_repo_owner(repo_id)

    return repo_owner
Exemple #15
0
def unsetinnerpub(request, repo_id):
    """Unshare repos in organization or in share admin page.

    Only system admin, organization admin or repo owner can perform this op.
    """
    repo = get_repo(repo_id)
    perm = request.GET.get('permission', None)
    if perm is None:
        return render_error(request, _(u'Argument is not valid'))
    if not repo:
        messages.error(request, _('Failed to unshare the library, as it does not exist.'))
        return HttpResponseRedirect(reverse('share_admin'))

    # permission check
    username = request.user.username
    if is_org_context(request):
        org_id = request.user.org.org_id
        repo_owner = seafile_api.get_org_repo_owner(repo.id)
        is_repo_owner = True if repo_owner == username else False
        if not (request.user.org.is_staff or is_repo_owner):
            raise Http404
    else:
        repo_owner = seafile_api.get_repo_owner(repo.id)
        is_repo_owner = True if repo_owner == username else False
        if not (request.user.is_staff or is_repo_owner):
            raise Http404

    try:
        if is_org_context(request):
            org_id = request.user.org.org_id
            seaserv.seafserv_threaded_rpc.unset_org_inner_pub_repo(org_id,
                                                                   repo.id)
        else:
            seaserv.unset_inner_pub_repo(repo.id)

            origin_repo_id, origin_path = get_origin_repo_info(repo.id)
            if origin_repo_id is not None:
                perm_repo_id = origin_repo_id
                perm_path = origin_path
            else:
                perm_repo_id = repo.id
                perm_path =  '/'

            send_perm_audit_msg('delete-repo-perm', username, 'all',
                                perm_repo_id, perm_path, perm)

        messages.success(request, _('Unshare "%s" successfully.') % repo.name)
    except SearpcError:
        messages.error(request, _('Failed to unshare "%s".') % repo.name)

    referer = request.META.get('HTTP_REFERER', None)
    next = settings.SITE_ROOT if referer is None else referer

    return HttpResponseRedirect(next)
Exemple #16
0
def get_repo_owner(request, repo_id):
    if is_org_context(request):
        repo_owner = seafile_api.get_org_repo_owner(repo_id)
    else:
        # for admin panel
        # administrator may get org repo's owner
        repo_owner = seafile_api.get_repo_owner(repo_id)
        if not repo_owner:
            repo_owner = seafile_api.get_org_repo_owner(repo_id)

    return repo_owner
Exemple #17
0
def list_repos_by_name(repo_name):
    repos = []
    repos_all = seafile_api.get_repo_list(-1, -1)
    for repo in repos_all:
        if repo_name in repo.name:
            try:
                repo.owner = seafile_api.get_repo_owner(repo.id)
            except SearpcError:
                repo.owner = "failed to get"
            repos.append(repo)
    return repos
Exemple #18
0
def list_repos_by_name(repo_name):
    repos = []
    repos_all = seafile_api.get_repo_list(-1, -1)
    for repo in repos_all:
        if repo_name in repo.name:
            try:
                repo.owner = seafile_api.get_repo_owner(repo.id)
            except SearpcError:
                repo.owner = "failed to get"
            repos.append(repo)
    return repos
Exemple #19
0
def render_recycle_root(request, repo_id, referer):
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    scan_stat = request.GET.get('scan_stat', None)
    try:
        deleted_entries = seafile_api.get_deleted(repo_id, 0, '/', scan_stat)
    except SearpcError as e:
        logger.error(e)
        referer = request.META.get('HTTP_REFERER', None)
        next = settings.SITE_ROOT if referer is None else referer
        return HttpResponseRedirect(next)

    if not deleted_entries:
        new_scan_stat = None
    else:
        new_scan_stat = deleted_entries[-1].scan_stat

    trash_more = True if new_scan_stat is not None else False

    deleted_entries = deleted_entries[0:-1]
    for dirent in deleted_entries:
        if stat.S_ISDIR(dirent.mode):
            dirent.is_dir = True
        else:
            dirent.is_dir = False

    # Entries sort by deletion time in descending order.
    deleted_entries.sort(lambda x, y: cmp(y.delete_time, x.delete_time))

    username = request.user.username
    if is_org_context(request):
        repo_owner = seafile_api.get_org_repo_owner(repo.id)
    else:
        repo_owner = seafile_api.get_repo_owner(repo.id)
    is_repo_owner = True if repo_owner == username else False

    enable_clean = False
    if is_repo_owner:
        enable_clean = True

    return render_to_response('repo_dir_recycle_view.html', {
        'show_recycle_root': True,
        'repo': repo,
        'repo_dir_name': repo.name,
        'dir_entries': deleted_entries,
        'scan_stat': new_scan_stat,
        'trash_more': trash_more,
        'enable_clean': enable_clean,
        'referer': referer,
    },
                              context_instance=RequestContext(request))
Exemple #20
0
def get_repo_info(repo):

    result = {}
    result['id'] = repo.repo_id
    result['name'] = repo.repo_name
    result['owner'] = seafile_api.get_repo_owner(repo.repo_id)
    result['size'] = repo.size
    result['size_formatted'] = filesizeformat(repo.size)
    result['encrypted'] = repo.encrypted
    result['file_count'] = repo.file_count

    return result
Exemple #21
0
    def delete(self, request, repo_id, format=None):
        """ delete a library

        Permission checking:
        1. only admin can perform this action.
        """
        if get_system_default_repo_id() == repo_id:
            error_msg = _('System library can not be deleted.')
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        repo = seafile_api.get_repo(repo_id)
        if not repo:
            # for case of `seafile-data` has been damaged
            # no `repo object` will be returned from seafile api
            # delete the database record anyway
            try:
                seafile_api.remove_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)

            return Response({'success': True})

        repo_name = repo.name
        repo_owner = seafile_api.get_repo_owner(repo_id)
        if not repo_owner:
            repo_owner = seafile_api.get_org_repo_owner(repo_id)

        try:
            related_usernames = seaserv.get_related_users_by_repo(repo_id)
            seafile_api.remove_repo(repo_id)

            # send signal for seafevents
            repo_deleted.send(sender=None, org_id=-1, operator=request.user.username,
                    usernames=related_usernames, repo_owner=repo_owner,
                    repo_id=repo_id, repo_name=repo.name)

        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        # send admin operation log signal
        admin_op_detail = {
            "id": repo_id,
            "name": repo_name,
            "owner": repo_owner,
        }
        admin_operation.send(sender=None, admin_name=request.user.username,
                operation=REPO_DELETE, detail=admin_op_detail)

        return Response({'success': True})
Exemple #22
0
def get_repo_info(repo):

    result = {}
    result['id'] = repo.repo_id
    result['name'] = repo.repo_name
    result['owner'] = seafile_api.get_repo_owner(repo.repo_id)
    result['size'] = repo.size
    result['size_formatted'] = filesizeformat(repo.size)
    result['encrypted'] = repo.encrypted
    result['file_count'] = repo.file_count

    return result
def get_group_repos(username, org_id, groups):
    """Get repos shared to groups.
    """
    group_repos = []
    if org_id:
        # For each group I joined...
        for grp in groups:
            # Get group repos, and for each group repos...
            for r_id in seafile_api.get_org_group_repoids(org_id, grp.id):
                # No need to list my own repo
                repo_owner = seafile_api.get_org_repo_owner(r_id)
                if repo_owner == username:
                    continue
                # Convert repo properties due to the different collumns in Repo
                # and SharedRepo
                r = seafile_api.get_repo(r_id)
                if not r:
                    continue
                r.repo_id = r.id
                r.repo_name = r.name
                r.repo_desc = r.desc
                r.last_modified = get_repo_last_modify(r)
                r.share_type = 'group'
                r.user = repo_owner
                r.user_perm = seafile_api.check_repo_access_permission(
                    r_id, username)
                r.group = grp
                group_repos.append(r)
    else:
        # For each group I joined...
        for grp in groups:
            # Get group repos, and for each group repos...
            for r_id in seafile_api.get_group_repoids(grp.id):
                # No need to list my own repo
                repo_owner = seafile_api.get_repo_owner(r_id)
                if repo_owner == username:
                    continue
                # Convert repo properties due to the different collumns in Repo
                # and SharedRepo
                r = seafile_api.get_repo(r_id)
                if not r:
                    continue
                r.repo_id = r.id
                r.repo_name = r.name
                r.repo_desc = r.desc
                r.last_modified = get_repo_last_modify(r)
                r.share_type = 'group'
                r.user = repo_owner
                r.user_perm = seafile_api.check_repo_access_permission(
                    r_id, username)
                r.group = grp
                group_repos.append(r)
    return group_repos
Exemple #24
0
    def format_repo_share_msg(self):
        """

        Arguments:
        - `self`:
        """
        try:
            d = json.loads(self.detail)
        except Exception as e:
            logger.error(e)
            return _(u"Internal error")

        share_from = email2nickname(d['share_from'])
        repo_id = d['repo_id']
        path = d.get('path', '/')
        org_id = d.get('org_id', None)
        repo = None
        try:
            if path == '/':
                repo = seafile_api.get_repo(repo_id)
            else:
                if org_id:
                    owner = seafile_api.get_org_repo_owner(repo_id)
                    repo = seafile_api.get_org_virtual_repo(
                        org_id, repo_id, path, owner)
                else:
                    owner = seafile_api.get_repo_owner(repo_id)
                    repo = seafile_api.get_virtual_repo(repo_id, path, owner)

        except Exception as e:
            logger.error(e)
            return None

        if repo is None:
            self.delete()
            return None

        if path == '/':
            tmpl = 'notifications/notice_msg/repo_share_msg.html'
        else:
            tmpl = 'notifications/notice_msg/folder_share_msg.html'

        msg = render_to_string(
            tmpl, {
                'user': share_from,
                'lib_url': HASH_URLS["VIEW_COMMON_LIB_DIR"] % {
                    'repo_id': repo.id,
                    'path': ''
                },
                'lib_name': repo.name,
            })

        return msg
Exemple #25
0
    def test_can_clean_department_repo_trash(self):
        if not LOCAL_PRO_DEV_ENV:
            return

        # create a department
        group_id = ccnet_api.create_group('department_test', 'system admin', parent_group_id=-1)
        seafile_api.set_group_quota(group_id, -2)
        repo_id = seafile_api.add_group_owned_repo(group_id, 'dep_test', 'rw')
        repo_owner = seafile_api.get_repo_owner(repo_id)
        assert '@seafile_group' in repo_owner
        group_repos = seafile_api.get_repos_by_group(group_id)
        assert len(group_repos) == 1
        group = ccnet_api.get_group(group_id)

        # department add user
        ccnet_api.group_add_member(group_id, group.creator_name, self.user_name)
        ccnet_api.group_add_member(group_id, group.creator_name, self.tmp_user.username)
        ccnet_api.group_set_admin(group_id, self.user_name)
        ccnet_api.group_unset_admin(group_id, self.tmp_user.username)
        assert is_group_admin(group_id, self.user_name)
        assert not is_group_admin(group_id, self.tmp_user.username)

        file_name = 'dep_test.txt'
        self.create_file(
            repo_id=repo_id, parent_dir='/', filename=file_name, username=self.user_name)

        # delete a file first
        seafile_api.del_file(repo_id, '/', file_name, self.user_name)

        # get trash item count
        self.login_as(self.user)
        resp = self.client.get(reverse('api-v2.1-repo-trash', args=[repo_id]))
        json_resp = json.loads(resp.content)
        assert len(json_resp['data']) > 0

        # department member can not clean trash
        self.logout()
        self.login_as(self.tmp_user)
        resp = self.client.delete(self.url)
        self.assertEqual(403, resp.status_code)

        # department admin can clean library trash
        self.logout()
        self.login_as(self.user)
        ccnet_api.group_set_admin(group_id, self.user_name)
        resp = self.client.delete(self.url)
        self.assertEqual(200, resp.status_code)

        # get trash item count again
        resp = self.client.get(self.url)
        json_resp = json.loads(resp.content)
        assert len(json_resp['data']) == 0
Exemple #26
0
def render_recycle_root(request, repo_id):
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    scan_stat = request.GET.get('scan_stat', None)
    try:
        deleted_entries = seafile_api.get_deleted(repo_id, 0, '/', scan_stat)
    except SearpcError as e:
        logger.error(e)
        referer = request.META.get('HTTP_REFERER', None)
        next = settings.SITE_ROOT if referer is None else referer
        return HttpResponseRedirect(next)

    if not deleted_entries:
        new_scan_stat = None
    else:
        new_scan_stat = deleted_entries[-1].scan_stat

    trash_more = True if new_scan_stat is not None else False

    deleted_entries = deleted_entries[0:-1]
    for dirent in deleted_entries:
        if stat.S_ISDIR(dirent.mode):
            dirent.is_dir = True
        else:
            dirent.is_dir = False

    # Entries sort by deletion time in descending order.
    deleted_entries.sort(lambda x, y : cmp(y.delete_time,
                                           x.delete_time))

    username = request.user.username
    if is_org_context(request):
        repo_owner = seafile_api.get_org_repo_owner(repo.id)
    else:
        repo_owner = seafile_api.get_repo_owner(repo.id)
    is_repo_owner = True if repo_owner == username else False

    enable_clean = False
    if is_repo_owner:
        enable_clean = True

    return render_to_response('repo_dir_recycle_view.html', {
            'show_recycle_root': True,
            'repo': repo,
            'repo_dir_name': repo.name,
            'dir_entries': deleted_entries,
            'scan_stat': new_scan_stat,
            'trash_more': trash_more,
            'enable_clean': enable_clean,
            }, context_instance=RequestContext(request))
Exemple #27
0
    def delete(self, request, repo_id, path, share_type):
        """ Delete user/group share permission.

        Permission checking:
        1. admin user.
        """

        # current `request.user.username` is admin user,
        # so need to identify the repo owner specifically.
        repo_owner = seafile_api.get_repo_owner(repo_id)

        share_to = request.data.get('share_to', None)

        if share_type == 'user':
            email = share_to
            if not email or not is_valid_username(email):
                error_msg = 'email %s invalid.' % email
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            try:
                if path == '/':
                    seafile_api.remove_share(repo_id, repo_owner, email)
                else:
                    seafile_api.unshare_subdir_for_user(
                        repo_id, path, repo_owner, email)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

        if share_type == 'group':
            group_id = share_to
            try:
                group_id = int(group_id)
            except ValueError:
                error_msg = 'group_id %s invalid' % group_id
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            try:
                if path == '/':
                    seafile_api.unset_group_repo(repo_id, group_id, repo_owner)
                else:
                    seafile_api.unshare_subdir_for_group(
                        repo_id, path, repo_owner, 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)

        return Response({'success': True})
Exemple #28
0
def permission_check_admin_owner(username, repo_id, request=None):  # maybe add more complex logic in the future
    """
    if repo is owned by user return true
    or check whether repo is owned by group and whether user is group's staff
    so finally the code is:
    check user == repo's owner
    else
    check user is the such group's staff
    """
    if username == seafile_api.get_repo_owner(repo_id):
        return True
    else:
        return is_group_repo_staff(request, repo_id, username)
Exemple #29
0
    def get(self, request, repo_id, format=None):
        """ get all file/folder in a library
        """

        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)

        if not can_view_sys_admin_repo(repo):
            error_msg = 'Feature disabled.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        parent_dir = request.GET.get('parent_dir', '/')
        if not parent_dir:
            error_msg = 'parent_dir invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        if parent_dir[-1] != '/':
            parent_dir = 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)

        if is_org_context(request):
            repo_owner = seafile_api.get_org_repo_owner(repo_id)
        else:
            repo_owner = seafile_api.get_repo_owner(repo_id)

        try:
            dirs = seafserv_threaded_rpc.list_dir_with_perm(
                repo_id, parent_dir, dir_id, repo_owner, -1, -1)
        except SearpcError as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        return_results = {}
        return_results['repo_name'] = repo.repo_name
        return_results['repo_id'] = repo.repo_id
        return_results['is_system_library'] = True if \
            repo.id == get_system_default_repo_id() else False
        return_results['dirent_list'] = []

        for dirent in dirs:
            dirent_info = get_dirent_info(dirent)
            return_results['dirent_list'].append(dirent_info)

        return Response(return_results)
Exemple #30
0
    def list_group_shared_items(self, request, repo_id, path):
        if is_org_context(request):
            # when calling seafile API to share authority related functions, change the uesrname to repo owner.
            repo_owner = seafile_api.get_org_repo_owner(repo_id)
            org_id = request.user.org.org_id
            if path == '/':
                share_items = seafile_api.list_org_repo_shared_group(org_id,
                        repo_owner, repo_id)
            else:
                share_items = seafile_api.get_org_shared_groups_for_subdir(org_id,
                        repo_id, path, repo_owner)
        else:
            repo_owner = seafile_api.get_repo_owner(repo_id)
            if path == '/':
                share_items = seafile_api.list_repo_shared_group_by_user(repo_owner, repo_id)
            else:
                share_items = seafile_api.get_shared_groups_for_subdir(repo_id,
                                                                       path, repo_owner)
        ret = []
        # change is_admin to True if user in admin groups.
        admin_groups = ExtraGroupsSharePermission.objects.get_admin_groups_by_repo(repo_id)
        for item in share_items:

            group_id = item.group_id
            group = ccnet_api.get_group(group_id)
            if not group:
                if is_org_context(request):
                    if path == '/':
                        seafile_api.del_org_group_repo(repo_id, org_id, group_id)
                    else:
                        seafile_api.org_unshare_subdir_for_group(
                                org_id, repo_id, path, repo_owner, group_id)
                else:
                    if path == '/':
                        seafile_api.unset_group_repo(repo_id, group_id,
                                repo_owner)
                    else:
                        seafile_api.unshare_subdir_for_group(
                                repo_id, path, repo_owner, group_id)
                continue

            ret.append({
                "share_type": "group",
                "group_info": {
                    "id": group_id,
                    "name": group.group_name,
                },
                "permission": item.perm,
                "is_admin": group_id in admin_groups,
            })
        return ret
Exemple #31
0
def my_group_repos(request):
    """Return html snippet of group repos.
    
    Arguments:
    - `request`:
    """
    if not request.is_ajax():
        raise Http404
    
    username = request.user.username
    
    group_repos = []
    # Get all personal groups I joined.
    joined_groups = request.user.joined_groups
    # For each group I joined... 
    for grp in joined_groups:
        # Get group repos, and for each group repos...
        for r_id in seaserv.get_group_repoids(grp.id):
            # No need to list my own repo
            repo_owner = seafile_api.get_repo_owner(r_id)
            if repo_owner == username:
                continue
            # Convert repo properties due to the different collumns in Repo
            # and SharedRepo
            r = seaserv.get_repo(r_id)
            if not r:
                continue
            r.repo_id = r.id
            r.repo_name = r.name
            r.repo_desc = r.desc
            r.last_modified = get_repo_last_modify(r)
            r.share_type = 'group'
            r.user = repo_owner
            r.user_perm = seaserv.check_permission(r_id, username)
            r.group = grp
            group_repos.append(r)
    group_repos.sort(key=lambda x: x.group.group_name)
    for i, repo in enumerate(group_repos):
        if i == 0:
            repo.show_group_name = True
        else:
            if repo.group.group_name != group_repos[i-1].group.group_name:
                repo.show_group_name = True

    ctx = {
        "group_repos": group_repos,
        }
    html = render_to_string('my_group_repos.html', ctx,
                            context_instance=RequestContext(request))

    return HttpResponse(html)
    def get(self, request, repo_id, format=None):
        """ get all file/folder in a library
        """

        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)

        if not can_view_sys_admin_repo(repo):
            error_msg = 'Feature disabled.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        parent_dir = request.GET.get('parent_dir', '/')
        if not parent_dir:
            error_msg = 'parent_dir invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        if parent_dir[-1] != '/':
            parent_dir = 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)

        if is_org_context(request):
            repo_owner = seafile_api.get_org_repo_owner(repo_id)
        else:
            repo_owner = seafile_api.get_repo_owner(repo_id)

        try:
            dirs = seafserv_threaded_rpc.list_dir_with_perm(repo_id,
                parent_dir, dir_id, repo_owner, -1, -1)
        except SearpcError as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        return_results = {}
        return_results['repo_name'] = repo.repo_name
        return_results['repo_id'] = repo.repo_id
        return_results['is_system_library'] = True if \
            repo.id == get_system_default_repo_id() else False
        return_results['dirent_list'] = []

        for dirent in dirs:
            dirent_info = get_dirent_info(dirent)
            return_results['dirent_list'].append(dirent_info)

        return Response(return_results)
Exemple #33
0
def repo_history_view(request, repo_id):
    """View repo in history.
    """
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    username = request.user.username
    path = get_path_from_request(request)
    user_perm = check_folder_permission(request, repo.id, '/')
    if user_perm is None:
        return render_error(request, _(u'Permission denied'))

    try:
        server_crypto = UserOptions.objects.is_server_crypto(username)
    except CryptoOptionNotSetError:
        # Assume server_crypto is ``False`` if this option is not set.
        server_crypto = False

    if repo.encrypted and \
        (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \
        and not is_password_set(repo.id, username):
        return render_to_response('decrypt_repo_form.html', {
                'repo': repo,
                'next': get_next_url_from_request(request) or reverse("view_common_lib_dir", args=[repo_id, '']),
                }, context_instance=RequestContext(request))

    commit_id = request.GET.get('commit_id', None)
    if commit_id is None:
        return HttpResponseRedirect(reverse("view_common_lib_dir", args=[repo_id, '']))
    current_commit = get_commit(repo.id, repo.version, commit_id)
    if not current_commit:
        current_commit = get_commit(repo.id, repo.version, repo.head_cmmt_id)

    file_list, dir_list, dirent_more = get_repo_dirents(request, repo,
                                                        current_commit, path)
    zipped = get_nav_path(path, repo.name)

    repo_owner = seafile_api.get_repo_owner(repo.id)
    is_repo_owner = True if username == repo_owner else False

    return render_to_response('repo_history_view.html', {
            'repo': repo,
            "is_repo_owner": is_repo_owner,
            'user_perm': user_perm,
            'current_commit': current_commit,
            'dir_list': dir_list,
            'file_list': file_list,
            'path': path,
            'zipped': zipped,
            }, context_instance=RequestContext(request))
Exemple #34
0
    def put(self, request, repo_id):
        """ Change repo password.

        Permission checking:
        1. repo owner
        """

        # argument check
        old_password = request.POST.get('old_password', None)
        if not old_password:
            error_msg = 'old_password invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        new_password = request.POST.get('new_password', None)
        if not new_password:
            error_msg = 'new_password invalid.'
            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)

        # permission check
        if is_org_context(request):
            repo_owner = seafile_api.get_org_repo_owner(repo.id)
        else:
            repo_owner = seafile_api.get_repo_owner(repo.id)

        username = request.user.username
        if username != repo_owner:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # change password
        try:
            seafile_api.change_repo_passwd(repo_id, old_password, new_password,
                                           username)
        except SearpcError as e:
            if e.msg == 'Incorrect password':
                error_msg = _(u'Wrong old password')
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)
            else:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

        return Response({'success': True})
Exemple #35
0
    def format_repo_share_to_group_msg(self):
        """

        Arguments:
        - `self`:
        """
        try:
            d = json.loads(self.detail)
        except Exception as e:
            logger.error(e)
            return _(u"Internal error")

        share_from = email2nickname(d['share_from'])
        repo_id = d['repo_id']
        group_id = d['group_id']
        path = d.get('path', '/')
        org_id = d.get('org_id', None)

        repo = None
        try:
            group = ccnet_api.get_group(group_id)
            if path == '/':
                repo = seafile_api.get_repo(repo_id)
            else:
                if org_id:
                    owner = seafile_api.get_org_repo_owner(repo_id)
                    repo = seafile_api.get_org_virtual_repo(
                        org_id, repo_id, path, owner)
                else:
                    owner = seafile_api.get_repo_owner(repo_id)
                    repo = seafile_api.get_virtual_repo(repo_id, path, owner)
        except Exception as e:
            logger.error(e)
            return None

        if not repo or not group:
            self.delete()
            return None

        msg = _(
            u"%(user)s has shared a library named <a href='%(repo_href)s'>%(repo_name)s</a> to group <a href='%(group_href)s'>%(group_name)s</a>."
        ) % {
            'user': escape(share_from),
            'repo_href': reverse('view_common_lib_dir', args=[repo.id, '']),
            'repo_name': escape(repo.name),
            'group_href': reverse('group_info', args=[group.id]),
            'group_name': escape(group.group_name),
        }

        return msg
Exemple #36
0
def repo_snapshot(request, repo_id):
    """View repo in history.
    """
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    username = request.user.username
    user_perm = check_folder_permission(request, repo.id, '/')
    if user_perm is None:
        return render_error(request, _('Permission denied'))

    try:
        server_crypto = UserOptions.objects.is_server_crypto(username)
    except CryptoOptionNotSetError:
        # Assume server_crypto is ``False`` if this option is not set.
        server_crypto = False

    reverse_url = reverse('lib_view', args=[repo_id, repo.name, ''])
    if repo.encrypted and \
        (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \
        and not is_password_set(repo.id, username):
        return render(
            request, 'decrypt_repo_form.html', {
                'repo': repo,
                'next': get_next_url_from_request(request) or reverse_url,
            })

    commit_id = request.GET.get('commit_id', None)
    if commit_id is None:
        return HttpResponseRedirect(reverse_url)
    current_commit = get_commit(repo.id, repo.version, commit_id)
    if not current_commit:
        current_commit = get_commit(repo.id, repo.version, repo.head_cmmt_id)

    has_perm = is_repo_owner(request, repo.id, username)
    # department admin
    if not has_perm:
        repo_owner = seafile_api.get_repo_owner(repo_id)
        if '@seafile_group' in repo_owner:
            group_id = get_group_id_by_repo_owner(repo_owner)
            has_perm = is_group_admin(group_id, username)

    return render(
        request, 'repo_snapshot_react.html', {
            'repo': repo,
            "can_restore_repo": has_perm,
            'current_commit': current_commit,
        })
Exemple #37
0
    def get(self, request):
        """get virus scan records
        """

        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

        start = (page - 1) * per_page
        count = per_page

        try:
            virus_records = get_virus_record(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)

        record_list = list()
        for virus_record in virus_records:
            try:
                repo = seafile_api.get_repo(virus_record.repo_id)
                repo_owner = seafile_api.get_repo_owner(virus_record.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_record.file_path
                record["has_handle"] = virus_record.has_handle
                record["virus_id"] = virus_record.vid
                record_list.append(record)

        return Response({"record_list": record_list},
                        status=status.HTTP_200_OK)
Exemple #38
0
    def post(self, request, repo_id, commit_id, format=None):
        """ revert commit in repo history

        Permission checking:
        1. only repo owner can perform this action.
        """
        username = request.user.username

        # 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)

        commit = seafile_api.get_commit(repo.id, repo.version, commit_id)
        if not commit:
            error_msg = 'Commit %s not found.' % commit_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # permission check
        has_perm = is_repo_owner(request, repo.id, username)
        if not has_perm:
            repo_owner = seafile_api.get_repo_owner(repo_id)
            # department admin
            if '@seafile_group' in repo_owner:
                group_id = get_group_id_by_repo_owner(repo_owner)
                has_perm = is_group_admin(group_id, username)
        if not has_perm:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # main
        if repo.encrypted:
            ret = seafile_api.is_password_set(repo_id, username)
            is_decrypted = False if ret == 0 else True

            if not is_decrypted:
                error_msg = _('This library has not been decrypted.')
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        try:
            seafile_api.revert_repo(repo_id, commit_id, username)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        return Response({'success': True})
Exemple #39
0
    def delete(self, request, repo_id, format=None):
        """ Delete repo share invitation.
        """
        # argument check
        path = request.data.get('path', None)
        if not path:
            return api_error(status.HTTP_400_BAD_REQUEST, 'path invalid.')

        token = request.data.get('token', None)
        if not token:
            return api_error(status.HTTP_400_BAD_REQUEST, 'token invalid.')

        # recourse check
        repo = seafile_api.get_repo(repo_id)
        if not repo:
            return api_error(status.HTTP_404_NOT_FOUND,
                             'Library %s not found.' % repo_id)

        if seafile_api.get_dir_id_by_path(repo.id, path) is None:
            return api_error(status.HTTP_404_NOT_FOUND,
                             'Folder %s not found.' % path)

        # permission check
        username = request.user.username
        if is_org_context(request):
            repo_owner = seafile_api.get_org_repo_owner(repo_id)
        else:
            repo_owner = seafile_api.get_repo_owner(repo_id)

        if username != repo_owner and not is_repo_admin(username, repo_id):
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # mian
        try:
            shared_obj = RepoShareInvitation.objects.get_by_token_and_path(
                token=token, repo_id=repo_id, path=path)
            if not shared_obj:
                error_msg = 'repo share invitation not found.'
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            shared_obj.delete()
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        return Response({'success': True})
    def get(self, request, repo_id, format=None):
        """ List repo share invitations.
        """
        # argument check
        path = request.GET.get('path', None)
        if not path:
            return api_error(status.HTTP_400_BAD_REQUEST, 'path invalid.')

        # 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)

        if seafile_api.get_dir_id_by_path(repo.id, path) is None:
            return api_error(status.HTTP_404_NOT_FOUND,
                             'Folder %s not found.' % path)

        # permission check
        username = request.user.username
        if is_org_context(request):
            repo_owner = seafile_api.get_org_repo_owner(repo_id)
        else:
            repo_owner = seafile_api.get_repo_owner(repo_id)

        if username != repo_owner and not is_repo_admin(username, repo_id):
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # main
        shared_list = list()
        try:
            shared_queryset = RepoShareInvitation.objects.list_by_repo_id_and_path(
                repo_id, path)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        for obj in shared_queryset:
            data = obj.invitation.to_dict()
            data['permission'] = obj.permission
            data['inviter_name'] = email2nickname(obj.invitation.inviter)

            shared_list.append(data)

        return Response({'repo_share_invitation_list': shared_list})
Exemple #41
0
def get_group_repos(request, groups):
    """Get repos shared to groups.
    """
    group_repos = []
    if is_org_context(request):
        org_id = request.user.org.org_id
        # For each group I joined...
        for grp in groups:
            # Get group repos, and for each group repos...
            for r_id in seafile_api.get_org_group_repoids(org_id, grp.id):
                repo_owner = seafile_api.get_org_repo_owner(r_id)
                # Convert repo properties due to the different collumns in Repo
                # and SharedRepo
                r = get_repo(r_id)
                if not r:
                    continue
                r.repo_id = r.id
                r.repo_name = r.name
                r.repo_desc = r.desc
                r.last_modified = get_repo_last_modify(r)
                r.share_type = 'group'
                r.user = repo_owner
                r.user_perm = check_folder_permission(request, r_id, '/')
                r.group = grp
                group_repos.append(r)
    else:
        # For each group I joined...
        for grp in groups:
            # Get group repos, and for each group repos...
            for r_id in seafile_api.get_group_repoids(grp.id):
                repo_owner = seafile_api.get_repo_owner(r_id)
                # Convert repo properties due to the different collumns in Repo
                # and SharedRepo
                r = get_repo(r_id)
                if not r:
                    continue
                r.repo_id = r.id
                r.repo_name = r.name
                r.repo_desc = r.desc
                r.last_modified = get_repo_last_modify(r)
                r.share_type = 'group'
                r.user = repo_owner
                r.user_perm = check_folder_permission(request, r_id, '/')
                r.group = grp
                group_repos.append(r)
    return group_repos
Exemple #42
0
    def test_can_set_department_repo(self):
        if not LOCAL_PRO_DEV_ENV:
            return

        # create a department
        group_id = ccnet_api.create_group('department_test',
                                          'system admin',
                                          parent_group_id=-1)
        seafile_api.set_group_quota(group_id, -2)
        repo_id = seafile_api.add_group_owned_repo(group_id, 'dep_test', 'rw')
        repo_owner = seafile_api.get_repo_owner(repo_id)
        assert '@seafile_group' in repo_owner
        group_repos = seafile_api.get_repos_by_group(group_id)
        assert len(group_repos) == 1
        group = ccnet_api.get_group(group_id)

        # department add user
        ccnet_api.group_add_member(group_id, group.creator_name,
                                   self.user.username)
        ccnet_api.group_add_member(group_id, group.creator_name,
                                   self.tmp_user.username)
        ccnet_api.group_set_admin(group_id, self.user.username)
        ccnet_api.group_unset_admin(group_id, self.tmp_user.username)
        assert is_group_admin(group_id, self.user.username)
        assert not is_group_admin(group_id, self.tmp_user.username)

        url = reverse("api2-repo-history-limit", args=[repo_id])
        self.config.ENABLE_REPO_HISTORY_SETTING = True

        # department member can not set
        self.logout()
        self.login_as(self.tmp_user)
        data = 'keep_days=%s' % 6
        resp = self.client.put(url, data, 'application/x-www-form-urlencoded')
        self.assertEqual(403, resp.status_code)

        # department admin can set
        self.logout()
        self.login_as(self.user)
        data = 'keep_days=%s' % 6
        resp = self.client.put(url, data, 'application/x-www-form-urlencoded')
        self.assertEqual(200, resp.status_code)

        self.remove_group(group_id)
        self.remove_repo(repo_id)
Exemple #43
0
def has_shared_to_user(repo_id, path, username, org_id=None):
    if is_valid_org_id(org_id):
        # when calling seafile API to share authority related functions, change the uesrname to repo owner.
        repo_owner = seafile_api.get_org_repo_owner(repo_id)
        if path == '/':
            share_items = seafile_api.list_org_repo_shared_to(
                org_id, repo_owner, repo_id)
        else:
            share_items = seafile_api.get_org_shared_users_for_subdir(
                org_id, repo_id, path, repo_owner)
    else:
        repo_owner = seafile_api.get_repo_owner(repo_id)
        if path == '/':
            share_items = seafile_api.list_repo_shared_to(repo_owner, repo_id)
        else:
            share_items = seafile_api.get_shared_users_for_subdir(
                repo_id, path, repo_owner)
    return username in [item.user for item in share_items]
Exemple #44
0
    def _decorated(view, request, repo_id, *args, **kwargs):
        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)

        # check permission
        if is_org_context(request):
            repo_owner = seafile_api.get_org_repo_owner(repo_id)
        else:
            repo_owner = seafile_api.get_repo_owner(repo_id)

        username = request.user.username
        if repo.is_virtual or username != repo_owner:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        return func(view, request, repo_id, *args, **kwargs)
Exemple #45
0
def upload_file_done(request):
    """Send a message when a file is uploaded.
    
    Arguments:
    - `request`:
    """
    ct = 'application/json; charset=utf-8'
    result = {}

    filename = request.GET.get('fn', '')
    if not filename:
        result['error'] = _('Argument missing')
        return HttpResponse(json.dumps(result), status=400, content_type=ct)
    repo_id = request.GET.get('repo_id', '')
    if not repo_id:
        result['error'] = _('Argument missing')
        return HttpResponse(json.dumps(result), status=400, content_type=ct)
    path = request.GET.get('p', '')
    if not path:
        result['error'] = _('Argument missing')
        return HttpResponse(json.dumps(result), status=400, content_type=ct)

    # a few checkings
    if not seafile_api.get_repo(repo_id):
        result['error'] = _('Wrong repo id')
        return HttpResponse(json.dumps(result), status=400, content_type=ct)

    owner = seafile_api.get_repo_owner(repo_id)
    if not owner:
        result['error'] = _('Wrong repo id')
        return HttpResponse(json.dumps(result), status=400, content_type=ct)

    file_path = path.rstrip('/') + '/' + filename
    if seafile_api.get_file_id_by_path(repo_id, file_path) is None:
        result['error'] = _('File does not exist')
        return HttpResponse(json.dumps(result), status=400, content_type=ct)

    # send singal
    upload_file_successful.send(sender=None,
                                repo_id=repo_id,
                                file_path=file_path,
                                owner=owner)

    return HttpResponse(json.dumps({'success': True}), content_type=ct)
Exemple #46
0
    def _decorated(view, request, repo_id, *args, **kwargs):
        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)

        # check permission
        if is_org_context(request):
            repo_owner = seafile_api.get_org_repo_owner(repo_id)
        else:
            repo_owner = seafile_api.get_repo_owner(repo_id)

        username = request.user.username
        if repo.is_virtual or username != repo_owner:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # check arguments
        group_id = request.data.get('group_id', None)
        path = request.data.get('folder_path', None)
        perm = request.data.get('permission', None)

        try:
            group_id = int(group_id)
        except ValueError:
            error_msg = 'group_id invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        if not seaserv.get_group(group_id):
            error_msg = 'Group %s not found.' % group_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        if path:
            path = path.rstrip('/') if path != '/' else path

        if seafile_api.get_dir_id_by_path(repo_id, path) is None:
            error_msg = 'Folder %s not found.' % path
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        if request.method in ('POST', 'PUT') and perm not in ('r', 'rw'):
            error_msg = 'permission invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        return func(view, request, repo_id, *args, **kwargs)
Exemple #47
0
def upload_file_done(request):
    """Send a message when a file is uploaded.
    
    Arguments:
    - `request`:
    """
    ct = 'application/json; charset=utf-8'
    result = {}  
    
    filename = request.GET.get('fn', '')
    if not filename:
        result['error'] = _('Argument missing')
        return HttpResponse(json.dumps(result), status=400, content_type=ct)
    repo_id = request.GET.get('repo_id', '')
    if not repo_id:
        result['error'] = _('Argument missing')
        return HttpResponse(json.dumps(result), status=400, content_type=ct)
    path = request.GET.get('p', '')
    if not path:  
        result['error'] = _('Argument missing')
        return HttpResponse(json.dumps(result), status=400, content_type=ct)

    # a few checkings
    if not seafile_api.get_repo(repo_id):
        result['error'] = _('Wrong repo id')
        return HttpResponse(json.dumps(result), status=400, content_type=ct)

    owner = seafile_api.get_repo_owner(repo_id)
    if not owner:
        result['error'] = _('Wrong repo id')
        return HttpResponse(json.dumps(result), status=400, content_type=ct)

    file_path = path.rstrip('/') + '/' + filename
    if seafile_api.get_file_id_by_path(repo_id, file_path) is None:
        result['error'] = _('File does not exist')
        return HttpResponse(json.dumps(result), status=400, content_type=ct)

    # send singal
    upload_file_successful.send(sender=None,
                                repo_id=repo_id,
                                file_path=file_path,
                                owner=owner)

    return HttpResponse(json.dumps({'success': True}), content_type=ct)
Exemple #48
0
def can_access_repo_setting(request, repo_id, username):
    repo = seafile_api.get_repo(repo_id)
    if not repo:
        return (False, None)

    # no settings for virtual repo
    if ENABLE_SUB_LIBRARY and repo.is_virtual:
        return (False, None)

    # check permission
    if is_org_context(request):
        repo_owner = seafile_api.get_org_repo_owner(repo_id)
    else:
        repo_owner = seafile_api.get_repo_owner(repo_id)
    is_owner = True if username == repo_owner else False
    if not is_owner:
        return (False, None)

    return (True, repo)
Exemple #49
0
def get_repo_info(repo):

    repo_owner = seafile_api.get_repo_owner(repo.repo_id)
    if not repo_owner:
        try:
            org_repo_owner = seafile_api.get_org_repo_owner(repo.repo_id)
        except Exception:
            org_repo_owner = None

    result = {}
    result['id'] = repo.repo_id
    result['name'] = repo.repo_name
    result['owner'] = repo_owner or org_repo_owner
    result['size'] = repo.size
    result['size_formatted'] = filesizeformat(repo.size)
    result['encrypted'] = repo.encrypted
    result['file_count'] = repo.file_count

    return result
Exemple #50
0
    def post(self, request, email, format=None):
        # migrate an account's repos and groups to an exist account
        if not is_valid_username(email):
            return api_error(status.HTTP_400_BAD_REQUEST,
                             'Email %s invalid.' % email)

        op = request.data.get('op', '').lower()
        if op == 'migrate':
            from_user = email
            to_user = request.data.get('to_user', '')
            if not is_valid_username(to_user):
                return api_error(status.HTTP_400_BAD_REQUEST,
                                 'Email %s invalid.' % to_user)

            try:
                user2 = User.objects.get(email=to_user)
            except User.DoesNotExist:
                return api_error(status.HTTP_404_NOT_FOUND,
                                 'User %s not found.' % to_user)

            # transfer owned repos to new user
            for r in seafile_api.get_owned_repo_list(from_user):
                seafile_api.set_repo_owner(r.id, user2.username)

            # transfer shared repos to new user
            for r in seafile_api.get_share_in_repo_list(from_user, -1, -1):
                owner = seafile_api.get_repo_owner(r.repo_id)
                seafile_api.share_repo(r.repo_id, owner, to_user, r.permission)

            # transfer joined groups to new user
            for g in ccnet_api.get_groups(from_user):
                if not is_group_member(g.id, user2.username):
                    # add new user to the group on behalf of the group creator
                    ccnet_threaded_rpc.group_add_member(
                        g.id, g.creator_name, to_user)

                if from_user == g.creator_name:
                    ccnet_threaded_rpc.set_group_creator(g.id, to_user)

            return Response({'success': True})
        else:
            return api_error(status.HTTP_400_BAD_REQUEST,
                             'op can only be migrate.')
Exemple #51
0
def can_access_repo_setting(request, repo_id, username):
    repo = seafile_api.get_repo(repo_id)
    if not repo:
        return (False, None)

    # no settings for virtual repo
    if ENABLE_SUB_LIBRARY and repo.is_virtual:
        return (False, None)

    # check permission
    if is_org_context(request):
        repo_owner = seafile_api.get_org_repo_owner(repo_id)
    else:
        repo_owner = seafile_api.get_repo_owner(repo_id)
    is_owner = True if username == repo_owner else False
    if not is_owner:
        return (False, None)

    return (True, repo)
Exemple #52
0
    def format_repo_share_msg(self):
        """

        Arguments:
        - `self`:
        """
        try:
            d = json.loads(self.detail)
        except Exception as e:
            logger.error(e)
            return _(u"Internal error")

        share_from = email2nickname(d['share_from'])
        repo_id = d['repo_id']
        path = d.get('path', '/')
        org_id = d.get('org_id', None)
        repo = None
        try:
            if path == '/':
                repo = seafile_api.get_repo(repo_id)
            else:
                if org_id:
                    owner = seafile_api.get_org_repo_owner(repo_id)
                    repo = seafile_api.get_org_virtual_repo(
                        org_id, repo_id, path, owner)
                else:
                    owner = seafile_api.get_repo_owner(repo_id)
                    repo = seafile_api.get_virtual_repo(repo_id, path, owner)
        except Exception as e:
            logger.error(e)
            return None

        if repo is None:
            self.delete()
            return None

        msg = _(u"%(user)s has shared a library named <a href='%(href)s'>%(repo_name)s</a> to you.") %  {
            'user': escape(share_from),
            'href': HASH_URLS["VIEW_COMMON_LIB_DIR"] % {'repo_id':repo.id, 'path': ''}, 
            'repo_name': escape(repo.name),
            }

        return msg
Exemple #53
0
def has_shared_to_group(repo_id, path, gid, org_id=None):
    if is_valid_org_id(org_id):
        # when calling seafile API to share authority related functions, change the uesrname to repo owner.
        repo_owner = seafile_api.get_org_repo_owner(repo_id)
        if path == '/':
            share_items = seafile_api.list_org_repo_shared_group(org_id,
                    repo_owner, repo_id)
        else:
            share_items = seafile_api.get_org_shared_groups_for_subdir(org_id,
                    repo_id, path, repo_owner)
    else:
        repo_owner = seafile_api.get_repo_owner(repo_id)
        if path == '/':
            share_items = seafile_api.list_repo_shared_group_by_user(repo_owner, repo_id)
        else:
            share_items = seafile_api.get_shared_groups_for_subdir(repo_id,
                                                                   path, repo_owner)

    return gid in [item.group_id for item in share_items]
Exemple #54
0
def has_shared_to_group(repo_id, path, gid, org_id=None):
    if org_id:
        # when calling seafile API to share authority related functions, change the uesrname to repo owner.
        repo_owner = seafile_api.get_org_repo_owner(repo_id)
        if path == '/':
            share_items = seafile_api.list_org_repo_shared_group(org_id,
                    repo_owner, repo_id)
        else:
            share_items = seafile_api.get_org_shared_groups_for_subdir(org_id,
                    repo_id, path, repo_owner)
    else:
        repo_owner = seafile_api.get_repo_owner(repo_id)
        if path == '/':
            share_items = seafile_api.list_repo_shared_group_by_user(repo_owner, repo_id)
        else:
            share_items = seafile_api.get_shared_groups_for_subdir(repo_id,
                                                                   path, repo_owner)

    return gid in [item.group_id for item in share_items]
Exemple #55
0
def repo_revert_history(request, repo_id):

    next = request.META.get('HTTP_REFERER', None)
    if not next:
        next = settings.SITE_ROOT

    repo = get_repo(repo_id)
    if not repo:
        messages.error(request, _("Library does not exist"))
        return HttpResponseRedirect(next)

    # perm check
    perm = check_folder_permission(request, repo_id, '/')
    username = request.user.username
    repo_owner = seafile_api.get_repo_owner(repo.id)

    if perm is None or repo_owner != username:
        messages.error(request, _("Permission denied"))
        return HttpResponseRedirect(next)

    try:
        server_crypto = UserOptions.objects.is_server_crypto(username)
    except CryptoOptionNotSetError:
        # Assume server_crypto is ``False`` if this option is not set.
        server_crypto = False

    password_set = False
    if repo.props.encrypted and \
            (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)):
        try:
            ret = seafserv_rpc.is_passwd_set(repo_id, username)
            if ret == 1:
                password_set = True
        except SearpcError, e:
            return render_error(request, e.msg)

        if not password_set:
            return HttpResponseRedirect(reverse("view_common_lib_dir", args=[repo_id, '']))
Exemple #56
0
    def put(self, request, repo_id, format=None):
        """
        Share a repo to users/groups/public.
        """
        share_type = request.GET.get('share_type')
        user = request.GET.get('user')
        group_id = request.GET.get('group_id')
        permission = request.GET.get('permission')

        if permission !='rw' and permission != "r":
            return api_error(status.HTTP_400_BAD_REQUEST,
                             'Permission need to be rw or r.')

        if share_type == 'personal':
            if not is_registered_user(user) :
                return api_error(status.HTTP_400_BAD_REQUEST,
                                 'User does not exist')
            try :
                from_email = seafile_api.get_repo_owner(repo_id)
                seafserv_threaded_rpc.add_share(repo_id, from_email, user,
                                                permission)
            except SearpcError, e:
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 "Searpc Error: " + e.msg)
 def get_repo_owner(self, request, repo_id):
     if is_org_context(request):
         return seafile_api.get_org_repo_owner(repo_id)
     else:
         return seafile_api.get_repo_owner(repo_id)
Exemple #58
0
def render_repo(request, repo):
    """Steps to show repo page:
    If user has permission to view repo
      If repo is encrypt and password is not set on server
        return decrypt repo page
      If repo is not encrypt or password is set on server
        Show repo direntries based on requested path
    If user does not have permission to view repo
      return permission deny page
    """
    username = request.user.username
    path = get_path_from_request(request)
    user_perm = check_repo_access_permission(repo.id, request.user)
    if user_perm is None:
        return render_to_response('repo_access_deny.html', {
                'repo': repo,
                }, context_instance=RequestContext(request))

    sub_lib_enabled = UserOptions.objects.is_sub_lib_enabled(username)

    server_crypto = False
    if repo.encrypted:
        try:
            server_crypto = UserOptions.objects.is_server_crypto(username)
        except CryptoOptionNotSetError:
            return render_to_response('options/set_user_options.html', {
                    }, context_instance=RequestContext(request))
            
        if (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \
                and not is_password_set(repo.id, username):
            return render_to_response('decrypt_repo_form.html', {
                    'repo': repo,
                    'next': get_next_url_from_request(request) or \
                        reverse('repo', args=[repo.id]),
                    'force_server_crypto': FORCE_SERVER_CRYPTO,
                    }, context_instance=RequestContext(request))

    # query context args
    fileserver_root = get_fileserver_root()
    max_upload_file_size = get_max_upload_file_size()

    protocol = request.is_secure() and 'https' or 'http'
    domain = RequestSite(request).domain

    for g in request.user.joined_groups:
        g.avatar = grp_avatar(g.id, 20)

    head_commit = get_commit(repo.id, repo.version, repo.head_cmmt_id)
    if not head_commit:
        raise Http404

    if new_merge_with_no_conflict(head_commit):
        info_commit = get_commit_before_new_merge(head_commit)
    else:
        info_commit = head_commit

    repo_size = get_repo_size(repo.id)
    no_quota = is_no_quota(repo.id)
    if is_org_context(request):
        repo_owner = seafile_api.get_org_repo_owner(repo.id)
    else:
        repo_owner = seafile_api.get_repo_owner(repo.id)
    is_repo_owner = True if repo_owner == username else False
    if is_repo_owner and not repo.is_virtual:
        show_repo_settings = True
    else:
        show_repo_settings = False

    more_start = None
    file_list, dir_list, dirent_more = get_repo_dirents(request, repo,
                                                        head_commit, path,
                                                        offset=0, limit=100)
    if dirent_more:
        more_start = 100
    zipped = get_nav_path(path, repo.name)
    repo_groups = get_shared_groups_by_repo_and_user(repo.id, username)
    if len(repo_groups) > 1:
        repo_group_str = render_to_string("snippets/repo_group_list.html",
                                          {'groups': repo_groups})
    else:
        repo_group_str = ''
    upload_url = get_upload_url(request, repo.id)

    fileshare = get_fileshare(repo.id, username, path)
    dir_shared_link = get_dir_share_link(fileshare)
    uploadlink = get_uploadlink(repo.id, username, path)
    dir_shared_upload_link = get_dir_shared_upload_link(uploadlink)

    return render_to_response('repo.html', {
            'repo': repo,
            'user_perm': user_perm,
            'repo_owner': repo_owner,
            'is_repo_owner': is_repo_owner,
            'show_repo_settings': show_repo_settings,
            'current_commit': head_commit,
            'info_commit': info_commit,
            'password_set': True,
            'repo_size': repo_size,
            'dir_list': dir_list,
            'file_list': file_list,
            'dirent_more': dirent_more,
            'more_start': more_start,
            'path': path,
            'zipped': zipped,
            'groups': repo_groups,
            'repo_group_str': repo_group_str,
            'no_quota': no_quota,
            'max_upload_file_size': max_upload_file_size,
            'upload_url': upload_url,
            'fileserver_root': fileserver_root,
            'protocol': protocol,
            'domain': domain,
            'fileshare': fileshare,
            'dir_shared_link': dir_shared_link,
            'uploadlink': uploadlink,
            'dir_shared_upload_link': dir_shared_upload_link,
            'ENABLE_SUB_LIBRARY': ENABLE_SUB_LIBRARY,
            'server_crypto': server_crypto,
            "sub_lib_enabled": sub_lib_enabled,
            }, context_instance=RequestContext(request))