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.')
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)
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)
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)
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)
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, })
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))
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))
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}
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)
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)
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})
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})
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)
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)
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})
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"))
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.')
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)
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})
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)
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."))
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)
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
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})
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
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
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})
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)
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})
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)
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')
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)
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
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})
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'))
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
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)
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)
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)
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)
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)
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))
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})
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})
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})
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))
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), )
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)
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)
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)
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)