Пример #1
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 joined groups to new user
            for g in seaserv.get_personal_groups_by_user(from_user):
                if not seaserv.is_group_user(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")
        else:
            return api_error(status.HTTP_400_BAD_REQUEST, 'op can only be migrate.')
Пример #2
0
def repo_remove_share(request):
    """
    If repo is shared from one person to another person, only these two peson
    can remove share.
    If repo is shared from one person to a group, then only the one share the
    repo and group staff can remove share.
    """
    repo_id = request.GET.get('repo_id', '')
    group_id = request.GET.get('gid', '')
    from_email = request.GET.get('from', '')
    if not is_valid_username(from_email):
        return render_error(request, _(u'Argument is not valid'))
    username = request.user.username

    # if request params don't have 'gid', then remove repos that share to
    # to other person; else, remove repos that share to groups
    if not group_id:
        to_email = request.GET.get('to', '')
        if not is_valid_username(to_email):
            return render_error(request, _(u'Argument is not valid'))

        if username != from_email and username != to_email:
            return render_permission_error(request, _(u'Failed to remove share'))

        if is_org_context(request):
            org_id = request.user.org.org_id
            org_remove_share(org_id, repo_id, from_email, to_email)
        else:
            seaserv.remove_share(repo_id, from_email, to_email)
    else:
        try:
            group_id = int(group_id)
        except:
            return render_error(request, _(u'group id is not valid'))

        group = seaserv.get_group(group_id)
        if not group:
            return render_error(request, _(u"Failed to unshare: the group doesn't exist."))

        if not seaserv.check_group_staff(group_id, username) \
                and username != from_email:
            return render_permission_error(request, _(u'Failed to remove share'))

        if is_org_group(group_id):
            org_id = get_org_id_by_group(group_id)
            del_org_group_repo(repo_id, org_id, group_id)
        else:
            seafile_api.unset_group_repo(repo_id, group_id, from_email)

    messages.success(request, _('Successfully removed share'))

    next = request.META.get('HTTP_REFERER', SITE_ROOT)
    return HttpResponseRedirect(next)
Пример #3
0
def repo_remove_share(request):
    """
    If repo is shared from one person to another person, only these two peson
    can remove share.
    If repo is shared from one person to a group, then only the one share the
    repo and group staff can remove share.
    """
    repo_id = request.GET.get('repo_id', '')
    group_id = request.GET.get('gid', '')
    from_email = request.GET.get('from', '')
    if not is_valid_username(from_email):
        return render_error(request, _(u'Argument is not valid'))

    # if request params don't have 'gid', then remove repos that share to
    # to other person; else, remove repos that share to groups
    if not group_id:
        to_email = request.GET.get('to', '')
        if not is_valid_username(to_email):
            return render_error(request, _(u'Argument is not valid'))

        if request.user.username != from_email and \
                request.user.username != to_email:
            return render_permission_error(request, _(u'Failed to remove share'))
        remove_share(repo_id, from_email, to_email)
    else:
        try:
            group_id_int = int(group_id)
        except:
            return render_error(request, _(u'group id is not valid'))

        if not check_group_staff(group_id_int, request.user.username) \
                and request.user.username != from_email:
            return render_permission_error(request, _(u'Failed to remove share'))

        if is_org_group(group_id_int):
            org_id = get_org_id_by_group(group_id_int)
            del_org_group_repo(repo_id, org_id, group_id_int)
        else:
            from seahub.group.views import group_unshare_repo
            group_unshare_repo(request, repo_id, group_id_int, from_email)

    messages.success(request, _('Successfully removed share'))

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

    return HttpResponseRedirect(next)
Пример #4
0
def gen_private_file_share(request, repo_id):
    emails = request.POST.getlist('emails', '')
    s_type = request.POST.get('s_type', '')
    path = request.POST.get('path', '')
    perm = request.POST.get('perm', 'r')
    file_or_dir = os.path.basename(path.rstrip('/'))
    username = request.user.username

    for email in [e.strip() for e in emails if e.strip()]:
        if not is_valid_username(email):
            continue

        if not is_registered_user(email):
            messages.error(request, _('Failed to share to "%s", user not found.') % email)
            continue

        if s_type == 'f':
            pfds = PrivateFileDirShare.objects.add_read_only_priv_file_share(
                username, email, repo_id, path)
        elif s_type == 'd':
            pfds = PrivateFileDirShare.objects.add_private_dir_share(
                username, email, repo_id, path, perm)
        else:
            continue

        # send a signal when sharing file successful
        share_file_to_user_successful.send(sender=None, priv_share_obj=pfds)
        messages.success(request, _('Successfully shared %s.') % file_or_dir)

    next = request.META.get('HTTP_REFERER', None)
    if not next:
        next = SITE_ROOT
    return HttpResponseRedirect(next)
Пример #5
0
def gen_private_file_share(request, repo_id):
    emails = request.POST.getlist('emails', '')
    s_type = request.POST.get('s_type', '')
    path = request.POST.get('path', '')
    perm = request.POST.get('perm', 'r')
    file_or_dir = os.path.basename(path.rstrip('/'))
    username = request.user.username

    for email in [e.strip() for e in emails if e.strip()]:
        if not is_valid_username(email):
            continue

        if not is_registered_user(email):
            messages.error(
                request,
                _('Failed to share to "%s", user not found.') % email)
            continue

        if s_type == 'f':
            pfds = PrivateFileDirShare.objects.add_read_only_priv_file_share(
                username, email, repo_id, path)
        elif s_type == 'd':
            pfds = PrivateFileDirShare.objects.add_private_dir_share(
                username, email, repo_id, path, perm)
        else:
            continue

        # send a signal when sharing file successful
        share_file_to_user_successful.send(sender=None, priv_share_obj=pfds)
        messages.success(request, _('Successfully shared %s.') % file_or_dir)

    next = request.META.get('HTTP_REFERER', None)
    if not next:
        next = SITE_ROOT
    return HttpResponseRedirect(next)
Пример #6
0
def user_profile(request, username):
    if is_valid_username(username):
        try:
            user = User.objects.get(email=username)
        except User.DoesNotExist:
            user = None
    else:
        user = None

    if user is not None:
        nickname = email2nickname(user.username)
        contact_email = Profile.objects.get_contact_email_by_user(user.username)
        d_profile = DetailedProfile.objects.get_detailed_profile_by_user(
            user.username)
    else:
        nickname = ''
        contact_email = ''
        d_profile = None

    return render(request, 'profile/user_profile.html', {
            'user': user,
            'nickname': nickname,
            'contact_email': contact_email,
            'd_profile': d_profile,
            })
Пример #7
0
def user_profile(request, username):
    if is_valid_username(username):
        try:
            user = User.objects.get(email=username)
        except User.DoesNotExist:
            user = None
    else:
        user = None

    if user is not None:
        nickname = email2nickname(user.username)
        contact_email = Profile.objects.get_contact_email_by_user(user.username)
        d_profile = DetailedProfile.objects.get_detailed_profile_by_user(
            user.username)
    else:
        nickname = ''
        contact_email = ''
        d_profile = None

    return render_to_response('profile/user_profile.html', {
            'user': user,
            'nickname': nickname,
            'contact_email': contact_email,
            'd_profile': d_profile,
            }, context_instance=RequestContext(request))
Пример #8
0
def user_profile(request, username):
    if is_valid_username(username):
        try:
            user = User.objects.get(email=username)
        except User.DoesNotExist:
            user = None
    else:
        user = None

    nickname = '' if user is None else email2nickname(user.username)

    if user is not None:
        profile = Profile.objects.get_profile_by_user(user.username)
        intro = profile.intro if profile else ''
        d_profile = DetailedProfile.objects.get_detailed_profile_by_user(
            user.username)
    else:
        intro = _(u'Has not accepted invitation yet')
        d_profile = None

    return render_to_response('profile/user_profile.html', {
            'user': user,
            'nickname': nickname,
            'intro': intro,
            'd_profile': d_profile,
            }, context_instance=RequestContext(request))
Пример #9
0
def check_user_folder_perm_args(request_user, repo_id, path, user, perm=None):
    if not seafile_api.get_repo(repo_id):
        return {'error': _(u'Library does not exist.'), 'status': 400}

    if check_repo_access_permission(repo_id, request_user) != 'rw':
        return {'error': _('Permission denied'), 'status': 403}

    if perm is not None:
        # add or toggle folder perm
        if seafile_api.get_dir_id_by_path(repo_id, path) is None:
            return {'error': _('Invalid path'), 'status': 400}

        if perm != 'r' and perm != 'rw':
            return {'error': _('Invalid folder permission'), 'status': 400}

    if not path.startswith('/'):
        return {'error': _('Path should start with "/"'), 'status': 400}

    if path != '/' and path.endswith('/'):
        return {'error': _('Path should NOT ends with "/"'), 'status': 400}

    if user and not is_valid_username(user):
        return {'error': _('Invalid username'), 'status': 400}

    return {'success': True}
Пример #10
0
def user_toggle_status(request, email):
    content_type = 'application/json; charset=utf-8'

    if not is_valid_username(email):
        return HttpResponse(json.dumps({'success': False}), status=400,
                            content_type=content_type)

    try:
        user_status = int(request.GET.get('s', 0))
    except ValueError:
        user_status = 0

    try:
        user = User.objects.get(email)
        user.is_active = bool(user_status)
        user.save()

        if user.is_active is True:
            try:
                email_user_on_activation(user)
                email_sent = True
            except Exception as e:
                logger.error(e)
                email_sent = False

            return HttpResponse(json.dumps({'success': True,
                                            'email_sent': email_sent,
                                            }), content_type=content_type)
        return HttpResponse(json.dumps({'success': True}),
                            content_type=content_type)
    except User.DoesNotExist:
        return HttpResponse(json.dumps({'success': False}), status=500,
                            content_type=content_type)
Пример #11
0
def user_toggle_role(request, email):
    content_type = 'application/json; charset=utf-8'

    if not is_valid_username(email):
        return HttpResponse(json.dumps({'success': False}), status=400,
                            content_type=content_type)

    if not ENABLE_GUEST:
        return HttpResponse(json.dumps({'success': False}), status=403,
                            content_type=content_type)

    try:
        user_role = request.GET.get('r', DEFAULT_USER)
    except ValueError:
        user_role = DEFAULT_USER

    try:
        user = User.objects.get(email)
        User.objects.update_role(user.email, user_role)

        return HttpResponse(json.dumps({'success': True}),
                            content_type=content_type)
    except User.DoesNotExist:
        return HttpResponse(json.dumps({'success': False}), status=500,
                            content_type=content_type)
Пример #12
0
    def get(self, request, email):
        """ return all groups user joined

        Permission checking:
        1. Admin user;
        """

        if not is_valid_username(email):
            error_msg = 'email invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        try:
            User.objects.get(email=email)
        except User.DoesNotExist as e:
            logger.error(e)
            error_msg = 'User %s not found.' % email
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        groups_info = []
        try:
            groups = ccnet_api.get_personal_groups_by_user(email)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        # Use dict to reduce memcache fetch cost in large for-loop.
        nickname_dict = {}
        creator_name_set = set([g.creator_name for g in groups])
        for e in creator_name_set:
            if e not in nickname_dict:
                nickname_dict[e] = email2nickname(e)

        for group in groups:
            isoformat_timestr = timestamp_to_isoformat_timestr(group.timestamp)
            group_info = {
                "id": group.id,
                "name": group.group_name,
                "owner_email": group.creator_name,
                "owner_name": nickname_dict.get(group.creator_name, ''),
                "created_at": isoformat_timestr,
                "parent_group_id": group.parent_group_id if is_pro_version() else 0
            }
            groups_info.append(group_info)

            try:
                is_group_staff = ccnet_api.check_group_staff(group.id, 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 email == group.creator_name:
                group_info['role'] = 'Owner'
            elif is_group_staff:
                group_info['role'] = 'Admin'
            else:
                group_info['role'] = 'Member'
        return Response({'group_list': groups_info})
Пример #13
0
    def get(self, request, format=None):
        """ List deleted repos (by owner)

        Permission checking:
        1. only admin can perform this action.
        """

        if not request.user.admin_permissions.can_manage_library():
            return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')

        # list by owner
        search_owner = request.GET.get('owner', '')
        if search_owner:
            if not is_valid_username(search_owner):
                error_msg = 'owner invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            repos = seafile_api.get_trash_repos_by_owner(search_owner)

            return_repos = []
            for repo in repos:
                result = get_trash_repo_info(repo)
                return_repos.append(result)

            return Response({
                "search_owner": search_owner,
                "repos": return_repos
            })

        # list by 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

        start = (current_page - 1) * per_page
        limit = per_page + 1

        repos_all = seafile_api.get_trash_repo_list(start, limit)

        if len(repos_all) > per_page:
            repos_all = repos_all[:per_page]
            has_next_page = True
        else:
            has_next_page = False

        return_results = []
        for repo in repos_all:
            repo_info = get_trash_repo_info(repo)
            return_results.append(repo_info)

        page_info = {
            'has_next_page': has_next_page,
            'current_page': current_page
        }

        return Response({"page_info": page_info, "repos": return_results})
Пример #14
0
    def put(self, request, email, format=None):
        if not is_valid_username(email):
            return api_error(status.HTTP_400_BAD_REQUEST, 'Email %s invalid.' % email)

        try:
            user = User.objects.get(email=email)
            return self._update_account(request, user)
        except User.DoesNotExist:
            return self._create_account(request, email)
Пример #15
0
    def put(self, request, email, format=None):
        if not is_valid_username(email):
            return api_error(status.HTTP_404_NOT_FOUND, 'User not found.')

        try:
            user = User.objects.get(email=email)
            return self._update_account(request, user)
        except User.DoesNotExist:
            return self._create_account(request, email)
Пример #16
0
    def post(self, request):
        """ Add admin in batch
        """

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

        emails = string2list(emails)
        new_admin_info = []

        for email in emails:
            if not is_valid_username(email):
                error_msg = 'email %s invalid.' % email
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            try:
                user = User.objects.get(email=email)
            except User.DoesNotExist:
                error_msg = 'email %s invalid.' % email
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            user.is_staff = True
            user.save()

            profile = Profile.objects.get_profile_by_user(user.email)
            user_info = {}
            user_info['email'] = user.email
            user_info['name'] = email2nickname(user.email)
            user_info[
                'contact_email'] = profile.contact_email if profile and profile.contact_email else ''
            user_info[
                'login_id'] = profile.login_id if profile and profile.login_id else ''

            user_info['is_staff'] = user.is_staff
            user_info['is_active'] = user.is_active

            user_info['quota_total'] = seafile_api.get_user_quota(user.email)
            user_info['quota_usage'] = seafile_api.get_user_self_usage(
                user.email)

            user_info['create_time'] = timestamp_to_isoformat_timestr(
                user.ctime)
            user_info['last_login'] = UserLastLogin.objects.get_by_username(
                user.email
            ).last_login if UserLastLogin.objects.get_by_username(
                user.email) else ''

            try:
                admin_role = AdminRole.objects.get_admin_role(user.email)
                user_info['admin_role'] = admin_role.role
            except AdminRole.DoesNotExist:
                user_info['admin_role'] = DEFAULT_ADMIN
            new_admin_info.append(user_info)

        return Response({'new_admin_user_list': new_admin_info})
Пример #17
0
    def clean_email(self):
        email = self.cleaned_data['email']
        if not is_valid_username(email):
            raise forms.ValidationError(_("Enter a valid email address."))

        emailuser = ccnet_threaded_rpc.get_emailuser(email)
        if not emailuser:
            return self.cleaned_data['email']
        else:
            raise forms.ValidationError(_("A user with this email already"))
Пример #18
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.')
Пример #19
0
    def clean_email(self):
        email = self.cleaned_data['email']
        if not is_valid_username(email):
            raise forms.ValidationError(_("Enter a valid email address."))

        emailuser = ccnet_threaded_rpc.get_emailuser(email)
        if not emailuser:
            return self.cleaned_data['email']
        else:
            raise forms.ValidationError(_("A user with this email already"))
Пример #20
0
    def put(self, request, email, format=None):
        if not is_valid_username(email):
            return api_error(status.HTTP_400_BAD_REQUEST,
                             'Email %s invalid.' % email)

        try:
            user = User.objects.get(email=email)
            return self._update_account(request, user)
        except User.DoesNotExist:
            return self._create_account(request, email)
Пример #21
0
    def put(self, request, group_id):
        """ Rename, transfer a specific group
        """

        group = seaserv.get_group(group_id)
        username = request.user.username

        new_group_name = request.data.get('name', None)
        if new_group_name:
            # rename a group
            # Check whether group name is validate.
            if not validate_group_name(new_group_name):
                error_msg = _(u'Group name can only contain letters, numbers, blank, hyphen or underscore')
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            # Check whether group name is duplicated.
            if check_group_name_conflict(request, new_group_name):
                error_msg = _(u'There is already a group with that name.')
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            try:
                seaserv.ccnet_threaded_rpc.set_group_name(group_id, new_group_name)
            except SearpcError as e:
                logger.error(e)
                error_msg = _(u'Internal Server Error')
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        new_creator= request.data.get('creator', None)
        if new_creator:
            # transfer a group
            if not is_valid_username(new_creator):
                error_msg = _('Creator %s is not valid.') % new_creator
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            if new_creator == group.creator_name:
                error_msg = _('%s is already group owner') % new_creator
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            try:
                if not seaserv.is_group_user(group_id, new_creator):
                    seaserv.ccnet_threaded_rpc.group_add_member(group_id, username, new_creator)

                if not seaserv.check_group_staff(group_id, new_creator):
                    seaserv.ccnet_threaded_rpc.group_set_admin(group_id, new_creator)

                seaserv.ccnet_threaded_rpc.set_group_creator(group_id, new_creator)
            except SearpcError as e:
                logger.error(e)
                error_msg = _(u'Internal Server Error')
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        # get new info of this group
        group_info = get_group_info(request, group_id, GROUP_AVATAR_DEFAULT_SIZE)

        return Response(group_info)
Пример #22
0
    def put(self, request, repo_id, org_id):
        """ Update repo user share permission.

        Permission checking:
        1. is group admin
        """

        # parameter check
        to_user = request.data.get('username', None)
        if not to_user:
            error_msg = 'username invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        if not is_valid_username(to_user):
            error_msg = 'username invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        permission = request.data.get('permission', PERMISSION_READ)
        if permission not in [PERMISSION_READ, PERMISSION_READ_WRITE]:
            error_msg = 'permission 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)

        repo_owner = get_repo_owner(request, repo_id)
        group_id = get_group_id_by_repo_owner(repo_owner)
        if not ccnet_api.get_group(group_id):
            error_msg = 'Group %s not found.' % group_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        path = request.data.get('path', '/')
        if not seafile_api.get_dir_id_by_path(repo_id, path):
            error_msg = 'Folder %s not found.' % path
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

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

        # permission check
        username = request.user.username
        if not is_group_admin(group_id, username):
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        update_user_dir_permission(repo_id, path, repo_owner, to_user, permission, org_id)

        send_perm_audit_msg('modify-repo-perm', username, to_user, repo_id, path, permission)
        return Response({'success': True})
Пример #23
0
def share_permission_admin(request):
    """Change repo share permission in ShareAdmin.
    """
    share_type = request.GET.get('share_type', '')
    content_type = 'application/json; charset=utf-8'

    form = RepoShareForm(request.POST)
    form.is_valid()

    email_or_group = form.cleaned_data['email_or_group']
    repo_id = form.cleaned_data['repo_id']
    permission = form.cleaned_data['permission']
    from_email = request.user.username

    if share_type == 'personal':
        if not is_valid_username(email_or_group):
            return HttpResponse(json.dumps({'success': False}), status=400,
                                content_type=content_type)

        try:
            seafile_api.set_share_permission(repo_id, from_email,
                                             email_or_group, permission)
        except SearpcError:
            return HttpResponse(json.dumps({'success': False}), status=500,
                                content_type=content_type)
        return HttpResponse(json.dumps({'success': True}),
                            content_type=content_type)

    elif share_type == 'group':
        try:
            seafile_api.set_group_repo_permission(int(email_or_group),
                                                  repo_id, permission)
        except SearpcError:
            return HttpResponse(json.dumps({'success': False}), status=500,
                                content_type=content_type)
        return HttpResponse(json.dumps({'success': True}),
                            content_type=content_type)

    elif share_type == 'public':
        try:        
            if is_org_context(request):
                org_id = request.user.org.org_id
                seaserv.seafserv_threaded_rpc.set_org_inner_pub_repo(
                    org_id, repo_id, permission)
            else:
                seafile_api.add_inner_pub_repo(repo_id, permission)
        except SearpcError:
            return HttpResponse(json.dumps({'success': False}), status=500,
                                content_type=content_type)
        return HttpResponse(json.dumps({'success': True}),
                            content_type=content_type)

    else:
        return HttpResponse(json.dumps({'success': False}), status=400,
                            content_type=content_type)
Пример #24
0
    def put(self, request, repo_id, org_id):
        """ Update repo user share permission.

        Permission checking:
        1. is group admin
        """

        # parameter check
        to_user = request.data.get('username', None)
        if not to_user:
            error_msg = 'username invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        if not is_valid_username(to_user):
            error_msg = 'username invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        permission = request.data.get('permission', PERMISSION_READ)
        if permission not in [PERMISSION_READ, PERMISSION_READ_WRITE]:
            error_msg = 'permission 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)

        repo_owner = get_repo_owner(request, repo_id)
        group_id = get_group_id_by_repo_owner(repo_owner)
        if not ccnet_api.get_group(group_id):
            error_msg = 'Group %s not found.' % group_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        path = request.data.get('path', '/')
        if not seafile_api.get_dir_id_by_path(repo_id, path):
            error_msg = 'Folder %s not found.' % path
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

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

        # permission check
        username = request.user.username
        if not is_group_admin(group_id, username):
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        update_user_dir_permission(repo_id, path, repo_owner, to_user, permission, org_id)

        send_perm_audit_msg('modify-repo-perm', username, to_user, repo_id, path, permission)
        return Response({'success': True})
Пример #25
0
    def clean_email(self):
        email = self.cleaned_data['email'].lower()
        if not is_valid_username(email):
            raise forms.ValidationError(_("Email address is not valid"))

        try:
            user = User.objects.get(email=email)
        except User.DoesNotExist:
            return email

        raise forms.ValidationError(
            _("A user with this email already exists."))
Пример #26
0
    def get(self, request, email, format=None):
        if not is_valid_username(email):
            return api_error(status.HTTP_400_BAD_REQUEST, 'Email %s invalid.' % email)

        # query account info
        try:
            user = User.objects.get(email=email)
        except User.DoesNotExist:
            return api_error(status.HTTP_404_NOT_FOUND, 'User %s not found.' % email)

        info = get_account_info(user)
        return Response(info)
Пример #27
0
    def delete(self, request, email, format=None):
        if not is_valid_username(email):
            return api_error(status.HTTP_400_BAD_REQUEST, 'Email %s invalid.' % email)

        # delete account
        try:
            user = User.objects.get(email=email)
            user.delete()
            return Response({'success': True})
        except User.DoesNotExist:
            resp = Response({'success': True}, status=status.HTTP_202_ACCEPTED)
            return resp
Пример #28
0
    def get(self, request, format=None):
        """ List deleted repos (by owner)

        Permission checking:
        1. only admin can perform this action.
        """

        # list by owner
        search_owner = request.GET.get('owner', '')
        if search_owner:
            if not is_valid_username(search_owner):
                error_msg = 'owner invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            repos = seafile_api.get_trash_repos_by_owner(search_owner)

            return_repos = []
            for repo in repos:
                result = get_trash_repo_info(repo)
                return_repos.append(result)

            return Response({"search_owner": search_owner, "repos": return_repos})

        # list by 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

        start = (current_page - 1) * per_page
        limit = per_page + 1

        repos_all = seafile_api.get_trash_repo_list(start, limit)

        if len(repos_all) > per_page:
            repos_all = repos_all[:per_page]
            has_next_page = True
        else:
            has_next_page = False

        return_results = []
        for repo in repos_all:
            repo_info = get_trash_repo_info(repo)
            return_results.append(repo_info)

        page_info = {
            'has_next_page': has_next_page,
            'current_page': current_page
        }

        return Response({"page_info": page_info, "repos": return_results})
Пример #29
0
    def get(self, request, email, format=None):
        if not is_valid_username(email):
            return api_error(status.HTTP_400_BAD_REQUEST, 'Email %s invalid.' % email)

        # query account info
        try:
            user = User.objects.get(email=email)
        except User.DoesNotExist:
            return api_error(status.HTTP_404_NOT_FOUND, 'User %s not found.' % email)

        info = get_account_info(user)
        return Response(info)
Пример #30
0
    def delete(self, request, email, format=None):
        if not is_valid_username(email):
            return api_error(status.HTTP_400_BAD_REQUEST, 'Email %s invalid.' % email)

        # delete account
        try:
            user = User.objects.get(email=email)
            user.delete()
            return Response("success")
        except User.DoesNotExist:
            resp = Response("success", status=status.HTTP_202_ACCEPTED)
            return resp
Пример #31
0
    def delete(self, request, email, format=None):
        if not is_valid_username(email):
            return api_error(status.HTTP_404_NOT_FOUND, 'User not found.')

        # delete account
        try:
            user = User.objects.get(email=email)
            user.delete()
            return Response("success")
        except User.DoesNotExist:
            resp = Response("success", status=status.HTTP_202_ACCEPTED)
            return resp
Пример #32
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})
Пример #33
0
    def put(self, request, group_id):
        """ Admin transfer a group

        Permission checking:
        1. Admin user;
        """

        # argument check
        new_owner = request.data.get('new_owner', None)
        if not new_owner or not is_valid_username(new_owner):
            error_msg = 'new_owner %s invalid.' % new_owner
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # recourse check
        group_id = int(group_id) # Checked by URL Conf
        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)

        # check if new_owner exists,
        # NOT need to check old_owner for old_owner may has been deleted.
        try:
            User.objects.get(email=new_owner)
        except User.DoesNotExist:
            error_msg = 'User %s not found.' % new_owner
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        old_owner = group.creator_name
        if new_owner == old_owner:
            error_msg = _(u'User %s is already group owner.') % new_owner
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # transfer a group
        try:
            if not is_group_member(group_id, new_owner):
                ccnet_api.group_add_member(group_id, old_owner, new_owner)

            if not is_group_admin(group_id, new_owner):
                ccnet_api.group_set_admin(group_id, new_owner)

            ccnet_api.set_group_creator(group_id, new_owner)
            ccnet_api.group_unset_admin(group_id, old_owner)
        except SearpcError as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        group_info = get_group_info(group_id)

        return Response(group_info)
Пример #34
0
    def put(self, request, group_id):
        """ Admin transfer a group

        Permission checking:
        1. Admin user;
        """

        # argument check
        new_owner = request.data.get('new_owner', None)
        if not new_owner or not is_valid_username(new_owner):
            error_msg = 'new_owner %s invalid.' % new_owner
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # recourse check
        group_id = int(group_id) # Checked by URL Conf
        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)

        # check if new_owner exists,
        # NOT need to check old_owner for old_owner may has been deleted.
        try:
            User.objects.get(email=new_owner)
        except User.DoesNotExist:
            error_msg = 'User %s not found.' % new_owner
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        old_owner = group.creator_name
        if new_owner == old_owner:
            error_msg = _(u'User %s is already group owner.') % new_owner
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # transfer a group
        try:
            if not is_group_member(group_id, new_owner):
                ccnet_api.group_add_member(group_id, old_owner, new_owner)

            if not is_group_admin(group_id, new_owner):
                ccnet_api.group_set_admin(group_id, new_owner)

            ccnet_api.set_group_creator(group_id, new_owner)
            ccnet_api.group_unset_admin(group_id, old_owner)
        except SearpcError as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        group_info = get_group_info(group_id)

        return Response(group_info)
Пример #35
0
    def put(self, request, email):
        """Reset password for user

        Permission checking:
        1. only admin can perform this action.
        """

        if not is_valid_username(email):
            error_msg = 'email invalid'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        try:
            user = User.objects.get(email=email)
        except User.DoesNotExist as e:
            logger.error(e)
            error_msg = 'email invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        if isinstance(INIT_PASSWD, FunctionType):
            new_password = INIT_PASSWD()
        else:
            new_password = INIT_PASSWD
        user.set_password(new_password)
        user.save()

        if config.FORCE_PASSWORD_CHANGE:
            UserOptions.objects.set_force_passwd_change(user.username)

        contact_email = Profile.objects.get_contact_email_by_user(email)
        if IS_EMAIL_CONFIGURED:
            if SEND_EMAIL_ON_RESETTING_USER_PASSWD:
                c = {'email': contact_email, 'password': new_password}
                try:
                    send_html_email(
                        _(u'Password has been reset on %s') % get_site_name(),
                        'sysadmin/user_reset_email.html', c, None,
                        [contact_email])
                    reset_tip = _('Successfully reset password to %(passwd)s, an email has been sent to %(user)s.') % \
                        {'passwd': new_password, 'user': contact_email}
                except Exception as e:
                    logger.warning(e)
                    reset_tip = _('Successfully reset password to %(passwd)s, but failed to send email to %(user)s, please check your email configuration.') % \
                        {'passwd': new_password, 'user': contact_email}
            else:
                reset_tip = _('Successfully reset password to %(passwd)s for user %(user)s.') % \
                    {'passwd': new_password, 'user': contact_email}
        else:
            reset_tip = _('Successfully reset password to %(passwd)s for user %(user)s. But email notification can not be sent, because Email service is not properly configured.') % \
                {'passwd': new_password, 'user': contact_email}

        return Response({'new_password': new_password, 'reset_tip': reset_tip})
Пример #36
0
    def post(self, request, repo_id, format=None):
        """Post a participant of a file.
        """
        # argument check
        path = request.data.get('path')
        if not path:
            return api_error(status.HTTP_400_BAD_REQUEST, 'path invalid.')
        path = normalize_file_path(path)

        email = request.data.get('email')
        if not email or not is_valid_username(email):
            return api_error(status.HTTP_400_BAD_REQUEST, 'email invalid.')

        # resource check
        file_id = seafile_api.get_file_id_by_path(repo_id, path)
        if not file_id:
            return api_error(status.HTTP_404_NOT_FOUND,
                             'File %s not found.' % path)

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

        # permission check
        if not check_folder_permission(request, repo_id, '/'):
            return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')

        if not seafile_api.check_permission_by_path(repo_id, '/',
                                                    user.username):
            return api_error(status.HTTP_403_FORBIDDEN,
                             _('%s Permission denied.') % email)

        # main
        try:
            file_uuid = FileUUIDMap.objects.get_or_create_fileuuidmap_by_path(
                repo_id, path, False)

            if FileParticipant.objects.get_participant(file_uuid, email):
                return api_error(status.HTTP_409_CONFLICT,
                                 _('Participant %s already exists.') % email)

            FileParticipant.objects.add_participant(file_uuid, email)
            participant = get_user_common_info(email)
        except Exception as e:
            logger.error(e)
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                             'Internal Server Error.')

        return Response(participant, status=201)
Пример #37
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_404_NOT_FOUND, 'User not found.')

        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,
                                 '%s is not valid email.' % to_user)

            try:
                user2 = User.objects.get(email=to_user)
            except User.DoesNotExist:
                return api_error(status.HTTP_400_BAD_REQUEST,
                                 '%s does not exist.' % 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 joined groups to new user
            for g in seaserv.get_personal_groups_by_user(from_user):
                if not seaserv.is_group_user(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")
        else:
            return api_error(status.HTTP_400_BAD_REQUEST,
                             'Op can only be migrate')
Пример #38
0
def share_permission_admin(request):
    share_type = request.GET.get('share_type', '')
    content_type = 'application/json; charset=utf-8'

    form = RepoShareForm(request.POST)
    form.is_valid()

    email_or_group = form.cleaned_data['email_or_group']
    repo_id = form.cleaned_data['repo_id']
    permission = form.cleaned_data['permission']
    from_email = request.user.username

    if share_type == 'personal':
        if not is_valid_username(email_or_group):
            return HttpResponse(json.dumps({'success': False}),
                                status=400,
                                content_type=content_type)

        try:
            seafserv_threaded_rpc.set_share_permission(repo_id, from_email,
                                                       email_or_group,
                                                       permission)
        except:
            return HttpResponse(json.dumps({'success': False}),
                                status=500,
                                content_type=content_type)
        return HttpResponse(json.dumps({'success': True}),
                            content_type=content_type)

    if share_type == 'group':
        try:
            seafserv_threaded_rpc.set_group_repo_permission(
                int(email_or_group), repo_id, permission)
        except:
            return HttpResponse(json.dumps({'success': False}),
                                status=500,
                                content_type=content_type)
        return HttpResponse(json.dumps({'success': True}),
                            content_type=content_type)

    if share_type == 'public':
        try:
            seafserv_threaded_rpc.set_inner_pub_repo(repo_id, permission)
        except:
            return HttpResponse(json.dumps({'success': False}),
                                status=500,
                                content_type=content_type)
        return HttpResponse(json.dumps({'success': True}),
                            content_type=content_type)
Пример #39
0
    def validate(self, attrs):
        username = attrs.get('username')
        password = attrs.get('password')

        platform = attrs.get('platform', None)
        device_id = attrs.get('device_id', None)
        device_name = attrs.get('device_name', None)
        client_version = attrs.get('client_version', None)
        platform_version = attrs.get('platform_version', None)

        v2_fields = (platform, device_id, device_name, client_version,
                     platform_version)

        # Decide the version of token we need
        if all_none(v2_fields):
            v2 = False
        elif all_not_none(v2_fields):
            v2 = True
        else:
            raise serializers.ValidationError('invalid params')

        # first check username and password
        if username:
            if not is_valid_username(username):
                raise serializers.ValidationError('username is not valid.')

        if username and password:
            user = authenticate(username=username, password=password)
            if user:
                if not user.is_active:
                    raise serializers.ValidationError(
                        'User account is disabled.')
            else:
                raise serializers.ValidationError(
                    'Unable to login with provided credentials.')
        else:
            raise serializers.ValidationError(
                'Must include "username" and "password"')

        # Now user is authenticated

        if v2:
            token = self.get_token_v2(username, platform, device_id,
                                      device_name, client_version,
                                      platform_version)
        else:
            token = self.get_token_v1(username)
        return token.key
Пример #40
0
    def get(self, request, email):
        """ List 'all' libraries shared to a user

        Permission checking:
        1. only admin can perform this action.
        """

        if not is_valid_username(email):
            error_msg = 'email invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        try:
            User.objects.get(email=email)
        except User.DoesNotExist as e:
            logger.error(e)
            error_msg = 'User %s not found.' % email
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        try:
            beshared_repos = seafile_api.get_share_in_repo_list(email, -1, -1)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        # Use dict to reduce memcache fetch cost in large for-loop.
        nickname_dict = {}
        owner_set = set([x.user for x in beshared_repos])
        for e in owner_set:
            if e not in nickname_dict:
                nickname_dict[e] = email2nickname(e)

        repos_info = []
        for repo in beshared_repos:
            repo_info = {}
            repo_info['id'] = repo.repo_id
            repo_info['name'] = repo.repo_name
            repo_info['owner_email'] = repo.user
            repo_info['owner_name'] = nickname_dict.get(repo.user, '')
            repo_info['size'] = repo.size
            repo_info['encrypted'] = repo.encrypted
            repo_info['file_count'] = repo.file_count
            repo_info['status'] = normalize_repo_status_code(repo.status)
            repo_info['last_modify'] = timestamp_to_isoformat_timestr(repo.last_modify)

            repos_info.append(repo_info)

        return Response({'repo_list': repos_info})
Пример #41
0
def sys_repo_trash_clear(request):
    """Clear repo trash (by owner)"""

    next = reverse('sys_repo_trash')
    owner = request.GET.get('owner', '')
    try:
        if owner:
            if is_valid_username(owner):
                seafserv_threaded_rpc.empty_repo_trash_by_owner(owner)
            else:
                messages.error(request, _(u'Invalid username'))
                return HttpResponseRedirect(next)
        else:
            seafserv_threaded_rpc.empty_repo_trash()
    except SearpcError, e:
        logger.error(e)
        messages.error(request, _(u'Failed'))
Пример #42
0
    def validate(self, attrs):
        username = attrs.get("username")
        password = attrs.get("password")

        platform = attrs.get("platform", None)
        device_id = attrs.get("device_id", None)
        device_name = attrs.get("device_name", None)
        client_version = attrs.get("client_version", None)
        platform_version = attrs.get("platform_version", None)

        v2_fields = (platform, device_id, device_name, client_version, platform_version)

        # Decide the version of token we need
        if all_none(v2_fields):
            v2 = False
        elif all_not_none(v2_fields):
            v2 = True
        else:
            raise serializers.ValidationError("invalid params")

        # first check username and password
        if username:
            if not is_valid_username(username):
                raise serializers.ValidationError("username is not valid.")

        if username and password:
            user = authenticate(username=username, password=password)
            if user:
                if not user.is_active:
                    raise serializers.ValidationError("User account is disabled.")
            else:
                raise serializers.ValidationError("Unable to login with provided credentials.")
        else:
            raise serializers.ValidationError('Must include "username" and "password"')

        # Now user is authenticated

        if v2:
            token = get_token_v2(
                self.context["request"], username, platform, device_id, device_name, client_version, platform_version
            )
        else:
            token = get_token_v1(username)
        return token.key
Пример #43
0
def batch_add_user(request):
    """Batch add users. Import users from CSV file.
    """
    if request.method != 'POST':
        raise Http404

    form = BatchAddUserForm(request.POST, request.FILES)
    if form.is_valid():
        content = request.FILES['file'].read()
        encoding = chardet.detect(content)['encoding']
        if encoding != 'utf-8':
            content = content.decode(encoding, 'replace').encode('utf-8')

        filestream = StringIO.StringIO(content)
        reader = csv.reader(filestream)

        for row in reader:
            if not row:
                continue

            username = row[0].strip()
            password = row[1].strip()

            if not is_valid_username(username):
                continue

            if password == '':
                continue

            try:
                User.objects.get(email=username)
                continue
            except User.DoesNotExist:
                User.objects.create_user(username,
                                         password,
                                         is_staff=False,
                                         is_active=True)
        messages.success(request, _('Import succeeded'))
    else:
        messages.error(request, _(u'Please select a csv file first.'))

    next = request.META.get('HTTP_REFERER', reverse(sys_user_admin))
    return HttpResponseRedirect(next)
Пример #44
0
def user_toggle_status(request, email):
    content_type = 'application/json; charset=utf-8'

    if not is_valid_username(email):
        return HttpResponse(json.dumps({'success': False}),
                            status=400,
                            content_type=content_type)

    try:
        user_status = int(request.POST.get('s', 0))
    except ValueError:
        user_status = 0

    try:
        user = User.objects.get(email)
        user.is_active = bool(user_status)
        result_code = user.save()
        if result_code == -1:
            return HttpResponse(json.dumps({'success': False}),
                                status=403,
                                content_type=content_type)

        if user.is_active is True:
            try:
                email_user_on_activation(user)
                email_sent = True
            except Exception as e:
                logger.error(e)
                email_sent = False

            return HttpResponse(json.dumps({
                'success': True,
                'email_sent': email_sent,
            }),
                                content_type=content_type)
        else:
            clear_token(user.email)
        return HttpResponse(json.dumps({'success': True}),
                            content_type=content_type)
    except User.DoesNotExist:
        return HttpResponse(json.dumps({'success': False}),
                            status=500,
                            content_type=content_type)
Пример #45
0
    def get(self, request, email, format=None):
        if not is_valid_username(email):
            return api_error(status.HTTP_404_NOT_FOUND, "User not found.")

        # query account info
        try:
            user = User.objects.get(email=email)
        except User.DoesNotExist:
            return api_error(status.HTTP_404_NOT_FOUND, "User not found.")

        info = {}
        info["email"] = user.email
        info["id"] = user.id
        info["is_staff"] = user.is_staff
        info["is_active"] = user.is_active
        info["create_time"] = user.ctime
        info["total"] = seafile_api.get_user_quota(email)
        info["usage"] = seafile_api.get_user_self_usage(email)

        return Response(info)
Пример #46
0
    def get(self, request, email, format=None):
        if not is_valid_username(email):
            return api_error(status.HTTP_400_BAD_REQUEST, 'Email %s invalid.' % email)

        # query account info
        try:
            user = User.objects.get(email=email)
        except User.DoesNotExist:
            return api_error(status.HTTP_404_NOT_FOUND, 'User %s not found.' % email)

        info = {}
        info['email'] = user.email
        info['id'] = user.id
        info['is_staff'] = user.is_staff
        info['is_active'] = user.is_active
        info['create_time'] = user.ctime
        info['total'] = seafile_api.get_user_quota(email)
        info['usage'] = seafile_api.get_user_self_usage(email)

        return Response(info)
Пример #47
0
    def get(self, request, email, format=None):
        if not is_valid_username(email):
            return api_error(status.HTTP_404_NOT_FOUND, 'User not found.')

        # query account info
        try:
            user = User.objects.get(email=email)
        except User.DoesNotExist:
            return api_error(status.HTTP_404_NOT_FOUND, 'User not found.')

        info = {}
        info['email'] = user.email
        info['id'] = user.id
        info['is_staff'] = user.is_staff
        info['is_active'] = user.is_active
        info['create_time'] = user.ctime
        info['total'] = seafile_api.get_user_quota(email)
        info['usage'] = seafile_api.get_user_self_usage(email)

        return Response(info)
Пример #48
0
def sys_repo_trash(request):
    """ List deleted repos (by owner) """

    search_owner = request.GET.get('name', '')
    if search_owner:
        if is_valid_username(search_owner):
            repos = seafserv_threaded_rpc.get_trash_repos_by_owner(
                search_owner)
            return render_to_response('sysadmin/sys_repo_trash.html', {
                'repos': repos,
                'search_owner': search_owner,
            },
                                      context_instance=RequestContext(request))
        else:
            messages.error(request, _(u'Invalid username'))
            return HttpResponseRedirect(reverse('sys_repo_trash'))

    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 = seafserv_threaded_rpc.get_trash_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

    return render_to_response('sysadmin/sys_repo_trash.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))
Пример #49
0
def batch_add_user(request):
    """Batch add users. Import users from CSV file.
    """
    if request.method != 'POST':
        raise Http404

    form = BatchAddUserForm(request.POST, request.FILES)
    if form.is_valid():
        content = request.FILES['file'].read()
        encoding = chardet.detect(content)['encoding']
        if encoding != 'utf-8':
            content = content.decode(encoding, 'replace').encode('utf-8')

        filestream = StringIO.StringIO(content)
        reader = csv.reader(filestream)

        for row in reader:
            if not row:
                continue

            username = row[0].strip()
            password = row[1].strip()

            if not is_valid_username(username):
                continue

            if password == '':
                continue

            try:
                User.objects.get(email=username)
                continue
            except User.DoesNotExist:
                User.objects.create_user(username, password, is_staff=False,
                                         is_active=True)
        messages.success(request, _('Import succeeded'))
    else:
        messages.error(request, _(u'Please select a csv file first.'))

    next = request.META.get('HTTP_REFERER', reverse(sys_user_admin))
    return HttpResponseRedirect(next)
Пример #50
0
    def put(self, request, email):
        """Reset password for user

        Permission checking:
        1. only admin can perform this action.
        """

        if not is_valid_username(email):
            error_msg = 'email invalid'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        try:
            user = User.objects.get(email=email)
        except User.DoesNotExist as e:
            logger.error(e)
            error_msg = 'email invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        if isinstance(INIT_PASSWD, FunctionType):
            new_password = INIT_PASSWD()
        else:
            new_password = INIT_PASSWD
        user.set_password(new_password)
        user.save()

        if config.FORCE_PASSWORD_CHANGE:
            UserOptions.objects.set_force_passwd_change(user.username)

        if IS_EMAIL_CONFIGURED and SEND_EMAIL_ON_RESETTING_USER_PASSWD:
            c = {'email': email, 'password': new_password}
            try:
                send_html_email(_(u'Password has been reset on %s') % get_site_name(),
                                'sysadmin/user_reset_email.html', c, None, [email])
            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({'new_password': new_password})
Пример #51
0
    def delete(self, request, repo_id, format=None):
        """Delete a participant
        """
        # argument check
        path = request.data.get('path')
        if not path:
            return api_error(status.HTTP_400_BAD_REQUEST, 'path invalid.')
        path = normalize_file_path(path)

        email = request.data.get('email')
        if not email or not is_valid_username(email):
            return api_error(status.HTTP_400_BAD_REQUEST, 'email invalid.')

        # resource check
        file_id = seafile_api.get_file_id_by_path(repo_id, path)
        if not file_id:
            return api_error(status.HTTP_404_NOT_FOUND,
                             'File %s not found.' % path)

        # permission check
        if not check_folder_permission(request, repo_id, '/'):
            return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')

        # main
        try:
            file_uuid = FileUUIDMap.objects.get_or_create_fileuuidmap_by_path(
                repo_id, path, False)

            if not FileParticipant.objects.get_participant(file_uuid, email):
                return api_error(status.HTTP_404_NOT_FOUND,
                                 'Participant %s not found.' % email)

            FileParticipant.objects.delete_participant(file_uuid, email)
        except Exception as e:
            logger.error(e)
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                             'Internal Server Error.')

        return Response({'success': True})
Пример #52
0
    def delete(self, request, format=None):
        """ clean all deleted libraries(by owner)

        Permission checking:
        1. only admin can perform this action.
        """

        owner = request.data.get("owner", "")
        try:
            if owner:
                if not is_valid_username(owner):
                    error_msg = "owner invalid."
                    return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

                seafile_api.empty_repo_trash_by_owner(owner)
            else:
                seafile_api.empty_repo_trash()
        except SearpcError 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})
Пример #53
0
def user_profile(request, username):
    if is_valid_username(username):
        try:
            user = User.objects.get(email=username)
        except User.DoesNotExist:
            user = None
    else:
        user = None

    nickname = '' if user is None else email2nickname(user.username)

    if user is not None:
        d_profile = DetailedProfile.objects.get_detailed_profile_by_user(
            user.username)
    else:
        d_profile = None

    return render_to_response('profile/user_profile.html', {
        'user': user,
        'nickname': nickname,
        'd_profile': d_profile,
    },
                              context_instance=RequestContext(request))
Пример #54
0
def user_profile(request, username):
    if is_valid_username(username):
        try:
            user = User.objects.get(email=username)
        except User.DoesNotExist:
            user = None
    else:
        user = None

    nickname = "" if user is None else email2nickname(user.username)

    if user is not None:
        profile = Profile.objects.get_profile_by_user(user.username)
        intro = profile.intro if profile else ""
        d_profile = DetailedProfile.objects.get_detailed_profile_by_user(user.username)
    else:
        intro = _(u"Has not accepted invitation yet")
        d_profile = None

    return render_to_response(
        "profile/user_profile.html",
        {"user": user, "nickname": nickname, "intro": intro, "d_profile": d_profile},
        context_instance=RequestContext(request),
    )
Пример #55
0
def share_repo(request):
    """
    Handle POST method to share a repo to public/groups/users based on form
    data. Return to ``myhome`` page and notify user whether success or failure.
    """
    next = request.META.get('HTTP_REFERER', None)
    if not next:
        next = SITE_ROOT

    form = RepoShareForm(request.POST)
    if not form.is_valid():
        # TODO: may display error msg on form
        raise Http404

    email_or_group = form.cleaned_data['email_or_group']
    repo_id = form.cleaned_data['repo_id']
    permission = form.cleaned_data['permission']

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

    # Test whether user is the repo owner.
    username = request.user.username
    if not seafile_api.is_repo_owner(username, repo_id) and \
            not is_org_repo_owner(username, repo_id):
        msg = _(u'Only the owner of the library has permission to share it.')
        messages.error(request, msg)
        return HttpResponseRedirect(next)

    # Parsing input values.
    share_to_all, share_to_groups, share_to_users = False, [], []
    user_groups = request.user.joined_groups
    share_to_list = string2list(email_or_group)
    for share_to in share_to_list:
        if share_to == 'all':
            share_to_all = True
        elif share_to.find('@') == -1:
            for user_group in user_groups:
                if user_group.group_name == share_to:
                    share_to_groups.append(user_group)
        else:
            share_to = share_to.lower()
            if is_valid_username(share_to):
                share_to_users.append(share_to)

    if share_to_all:
        share_to_public(request, repo, permission)

    if not check_user_share_quota(username, repo, users=share_to_users,
                                  groups=share_to_groups):
        messages.error(request, _('Failed to share "%s", no enough quota. <a href="http://seafile.com/">Upgrade account.</a>') % repo.name)
        return HttpResponseRedirect(next)

    for group in share_to_groups:
        share_to_group(request, repo, group, permission)

    for email in share_to_users:
        # Add email to contacts.
        mail_sended.send(sender=None, user=request.user.username, email=email)
        share_to_user(request, repo, email, permission)

    return HttpResponseRedirect(next)
Пример #56
0
    def put(self, request, group_id):
        """ Rename, transfer a specific group
        """

        username = request.user.username
        new_group_name = request.data.get('name', None)
        # rename a group
        if new_group_name:
            try:
                # only group owner/admin can rename a group
                if not is_group_admin_or_owner(group_id, username):
                    error_msg = 'Permission denied.'
                    return api_error(status.HTTP_403_FORBIDDEN, error_msg)

                # Check whether group name is validate.
                if not validate_group_name(new_group_name):
                    error_msg = _(u'Group name can only contain letters, numbers, blank, hyphen or underscore')
                    return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

                # Check whether group name is duplicated.
                if check_group_name_conflict(request, new_group_name):
                    error_msg = _(u'There is already a group with that name.')
                    return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

                seaserv.ccnet_threaded_rpc.set_group_name(group_id, new_group_name)

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

        new_owner = request.data.get('owner', None)
        # transfer a group
        if new_owner:
            try:
                # only group owner can transfer a group
                if not is_group_owner(group_id, username):
                    error_msg = 'Permission denied.'
                    return api_error(status.HTTP_403_FORBIDDEN, error_msg)

                # augument check
                if not is_valid_username(new_owner):
                    error_msg = 'Email %s invalid.' % new_owner
                    return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

                if is_group_owner(group_id, new_owner):
                    error_msg = _(u'User %s is already group owner.') % new_owner
                    return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

                # transfer a group
                if not is_group_member(group_id, new_owner):
                    ccnet_api.group_add_member(group_id, username, new_owner)

                if not is_group_admin(group_id, new_owner):
                    ccnet_api.group_set_admin(group_id, new_owner)

                ccnet_api.set_group_creator(group_id, new_owner)
                ccnet_api.group_unset_admin(group_id, username)

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

        wiki_enabled = request.data.get('wiki_enabled', None)
        # turn on/off group wiki
        if wiki_enabled:
            try:
                # only group owner/admin can turn on a group wiki
                if not is_group_admin_or_owner(group_id, username):
                    error_msg = 'Permission denied.'
                    return api_error(status.HTTP_403_FORBIDDEN, error_msg)

                # augument check
                if wiki_enabled != 'true' and wiki_enabled != 'false':
                    error_msg = 'wiki_enabled invalid.'
                    return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

                # turn on/off group wiki
                if wiki_enabled == 'true':
                    enable_mod_for_group(group_id, MOD_GROUP_WIKI)
                else:
                    disable_mod_for_group(group_id, MOD_GROUP_WIKI)

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

        group_info = get_group_info(request, group_id)

        return Response(group_info)
Пример #57
0
    def delete(self, request, repo_id, format=None):
        username = request.user.username
        repo = seafile_api.get_repo(repo_id)
        if not repo:
            return api_error(status.HTTP_404_NOT_FOUND, 'Library %s not found.' % repo_id)

        path = request.GET.get('p', '/')
        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)

        if username != self.get_repo_owner(request, repo_id):
            return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')

        shared_to_user, shared_to_group = self.handle_shared_to_args(request)

        if path == '/':
            shared_repo = repo
        else:
            try:
                sub_repo = self.get_sub_repo_by_path(request, repo, path)
                if sub_repo:
                    shared_repo = sub_repo
                else:
                    return api_error(status.HTTP_404_NOT_FOUND, 'Sub-library not found.')
            except SearpcError as e:
                logger.error(e)
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Failed to get sub-library.')

        if shared_to_user:
            shared_to = request.GET.get('username')
            if shared_to is None or not is_valid_username(shared_to):
                return api_error(status.HTTP_400_BAD_REQUEST, 'Email %s invalid.' % shared_to)

            try:
                User.objects.get(email=shared_to)
            except User.DoesNotExist:
                return api_error(status.HTTP_400_BAD_REQUEST, 'Invalid user, should be registered')

            if is_org_context(request):
                org_id = request.user.org.org_id
                seaserv.seafserv_threaded_rpc.org_remove_share(
                    org_id, shared_repo.id, username, shared_to)
            else:
                seaserv.remove_share(shared_repo.id, username, shared_to)

            permission = seafile_api.check_permission_by_path(repo.id, path,
                                                              shared_to)
            send_perm_audit_msg('delete-repo-perm', username, shared_to,
                                repo_id, path, permission)

        if shared_to_group:
            group_id = request.GET.get('group_id')
            try:
                group_id = int(group_id)
            except ValueError:
                return api_error(status.HTTP_400_BAD_REQUEST, 'group_id %s invalid' % group_id)

            # hacky way to get group repo permission
            permission = ''
            for e in seafile_api.list_repo_shared_group_by_user(username, shared_repo.id):
                if e.group_id == group_id:
                    permission = e.perm
                    break

            if is_org_context(request):
                org_id = request.user.org.org_id
                seaserv.del_org_group_repo(shared_repo.id, org_id, group_id)
            else:
                seafile_api.unset_group_repo(shared_repo.id, group_id, username)

            send_perm_audit_msg('delete-repo-perm', username, group_id,
                                repo_id, path, permission)

        return HttpResponse(json.dumps({'success': True}), status=200,
                            content_type=json_content_type)
Пример #58
0
    def put(self, request, repo_id, format=None):
        username = request.user.username
        repo = seafile_api.get_repo(repo_id)
        if not repo:
            return api_error(status.HTTP_404_NOT_FOUND, 'Library %s not found.' % repo_id)

        path = request.GET.get('p', '/')
        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)

        if username != self.get_repo_owner(request, repo_id):
            return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')

        if path != '/':
            try:
                sub_repo = self.get_or_create_sub_repo_by_path(request, repo, path)
            except SearpcError as e:
                logger.error(e)
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Failed to get sub repo.')
        else:
            sub_repo = None

        share_type = request.data.get('share_type')
        if share_type != 'user' and share_type != 'group':
            return api_error(status.HTTP_400_BAD_REQUEST, 'share_type invalid.')

        permission = request.data.get('permission', 'r')
        if permission not in ['r', 'rw']:
            return api_error(status.HTTP_400_BAD_REQUEST, 'permission invalid.')

        shared_repo = repo if path == '/' else sub_repo
        result = {}
        result['failed'] = []
        result['success'] = []

        if share_type == 'user':
            share_to_users = request.data.getlist('username')
            for to_user in share_to_users:
                if not is_valid_username(to_user):
                    result['failed'].append({
                        'email': to_user,
                        'error_msg': 'username invalid.'
                        })
                    continue

                try:
                    User.objects.get(email=to_user)
                except User.DoesNotExist:
                    result['failed'].append({
                        'email': to_user,
                        'error_msg': 'User %s not found.' % to_user
                        })
                    continue

                try:
                    if is_org_context(request):
                        org_id = request.user.org.org_id
                        seaserv.seafserv_threaded_rpc.org_add_share(
                            org_id, shared_repo.id, username, to_user,
                            permission)
                    else:
                        seafile_api.share_repo(shared_repo.id, username,
                                               to_user, permission)

                    # send a signal when sharing repo successful
                    share_repo_to_user_successful.send(sender=None,
                                                       from_user=username,
                                                       to_user=to_user,
                                                       repo=shared_repo)
                    result['success'].append({
                        "share_type": "user",
                        "user_info": {
                            "name": to_user,
                            "nickname": email2nickname(to_user),
                        },
                        "permission": permission
                    })

                    send_perm_audit_msg('add-repo-perm', username, to_user,
                                        repo_id, path, permission)
                except SearpcError as e:
                    logger.error(e)
                    result['failed'].append({
                        'email': to_user,
                        'error_msg': 'Internal Server Error'
                        })
                    continue

        if share_type == 'group':
            group_ids = request.data.getlist('group_id')
            for gid in group_ids:
                try:
                    gid = int(gid)
                except ValueError:
                    return api_error(status.HTTP_400_BAD_REQUEST, 'group_id %s invalid.' % gid)
                group = seaserv.get_group(gid)
                if not group:
                    return api_error(status.HTTP_404_NOT_FOUND, 'Group %s not found' % gid)

                try:
                    if is_org_context(request):
                        org_id = request.user.org.org_id
                        seafile_api.add_org_group_repo(shared_repo.repo_id,
                                                       org_id, gid, username,
                                                       permission)
                    else:
                        seafile_api.set_group_repo(shared_repo.repo_id, gid,
                                                   username, permission)

                    share_repo_to_group_successful.send(sender=None,
                        from_user=username, group_id=gid, repo=shared_repo)

                    result['success'].append({
                        "share_type": "group",
                        "group_info": {
                            "id": gid,
                            "name": group.group_name,
                        },
                        "permission": permission
                    })

                    send_perm_audit_msg('add-repo-perm', username, gid,
                                        repo_id, path, permission)
                except SearpcError as e:
                    logger.error(e)
                    result['failed'].append({
                        'group_name': group.group_name,
                        'error_msg': 'Internal Server Error'
                        })
                    continue

        return HttpResponse(json.dumps(result),
            status=200, content_type=json_content_type)