1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-14 22:33:17 +00:00

[api2] Clarify 403 error message

This commit is contained in:
zhengxie
2013-09-05 17:25:52 +08:00
parent 3a61898dec
commit 179c7a70dc
2 changed files with 101 additions and 22 deletions

30
seahub/api2/utils.py Normal file
View File

@@ -0,0 +1,30 @@
# Utility functions for api2
from seaserv import seafile_api
def is_repo_writable(repo_id, username):
"""Check whether a user has write permission to a repo.
Arguments:
- `repo_id`:
- `username`:
"""
if seafile_api.check_repo_access_permission(repo_id, username) == 'rw':
return True
else:
return False
def is_repo_accessible(repo_id, username):
"""Check whether a user can read or write to a repo.
Arguments:
- `repo_id`:
- `username`:
"""
if seafile_api.check_repo_access_permission(repo_id, username) is None:
return False
else:
return True

View File

@@ -19,8 +19,8 @@ from django.http import HttpResponse
from models import Token
from authentication import TokenAuthentication
from permissions import IsRepoWritable, IsRepoAccessible, IsRepoOwner
from serializers import AuthTokenSerializer
from utils import is_repo_writable, is_repo_accessible
from seahub.base.accounts import User
from seahub.base.models import FileDiscuss, UserStarredFiles
from seahub.share.models import FileShare
@@ -340,7 +340,7 @@ def check_repo_access_permission(request, repo):
class Repo(APIView):
authentication_classes = (TokenAuthentication, )
permission_classes = (IsAuthenticated, IsRepoAccessible, )
permission_classes = (IsAuthenticated, )
throttle_classes = (UserRateThrottle, )
def get(self, request, repo_id, format=None):
@@ -348,6 +348,11 @@ class Repo(APIView):
if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
username = request.user.username
if not is_repo_accessible(repo.id, username):
return api_error(status.HTTP_403_FORBIDDEN,
'You do not have permission to get repo.')
# check whether user is repo owner
if validate_owner(request, repo_id):
owner = "self"
@@ -373,7 +378,7 @@ class Repo(APIView):
"encrypted":repo.encrypted,
"encversion":r.encversion,
"root":root_id,
"permission": check_permission(repo.id, request.user.username),
"permission": check_permission(repo.id, username),
}
return Response(repo_json)
@@ -408,10 +413,15 @@ class Repo(APIView):
class DownloadRepo(APIView):
authentication_classes = (TokenAuthentication, )
permission_classes = (IsAuthenticated, IsRepoAccessible, )
permission_classes = (IsAuthenticated, )
throttle_classes = (UserRateThrottle, )
def get(self, request, repo_id, format=None):
username = request.user.username
if not is_repo_accessible(repo_id, username):
return api_error(status.HTTP_403_FORBIDDEN,
'You do not have permission to get repo.')
return repo_download_info(request, repo_id)
class UploadLinkView(APIView):
@@ -606,13 +616,18 @@ class OpDeleteView(APIView):
Delete a file.
"""
authentication_classes = (TokenAuthentication, )
permission_classes = (IsAuthenticated, IsRepoWritable, )
permission_classes = (IsAuthenticated, )
def post(self, request, repo_id, format=None):
repo = get_repo(repo_id)
if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
username = request.user.username
if not is_repo_writable(repo.id, username):
return api_error(status.HTTP_403_FORBIDDEN,
'You do not have permission to delete file.')
resp = check_repo_access_permission(request, repo)
if resp:
return resp
@@ -628,7 +643,7 @@ class OpDeleteView(APIView):
file_name = unquote(file_name.encode('utf-8'))
try:
seafserv_threaded_rpc.del_file(repo_id, parent_dir,
file_name, request.user.username)
file_name, username)
except SearpcError,e:
return api_error(HTTP_520_OPERATION_FAILED,
"Failed to delete file.")
@@ -707,7 +722,7 @@ class FileView(APIView):
"""
authentication_classes = (TokenAuthentication, )
permission_classes = (IsAuthenticated, IsRepoWritable, )
permission_classes = (IsAuthenticated, )
throttle_classes = (UserRateThrottle, )
def get(self, request, repo_id, format=None):
@@ -740,7 +755,7 @@ class FileView(APIView):
return get_repo_file(request, repo_id, file_id, file_name, op)
def post(self, request, repo_id, format=None):
# rename or move file
# rename, move or create file
repo = get_repo(repo_id)
if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
@@ -754,8 +769,13 @@ class FileView(APIView):
return api_error(status.HTTP_400_BAD_REQUEST,
'Path is missing or invalid.')
username = request.user.username
operation = request.POST.get('operation', '')
if operation.lower() == 'rename':
if not is_repo_writable(repo.id, username):
return api_error(status.HTTP_403_FORBIDDEN,
'You do not have permission to rename file.')
newname = request.POST.get('newname', '')
if not newname:
return api_error(status.HTTP_400_BAD_REQUEST,
@@ -777,7 +797,7 @@ class FileView(APIView):
try:
seafserv_threaded_rpc.rename_file (repo_id, parent_dir_utf8,
oldname_utf8, newname,
request.user.username)
username)
except SearpcError,e:
return api_error(HTTP_520_OPERATION_FAILED,
"Failed to rename file: %s" % e)
@@ -791,6 +811,10 @@ class FileView(APIView):
return resp
elif operation.lower() == 'move':
if not is_repo_writable(repo.id, username):
return api_error(status.HTTP_403_FORBIDDEN,
'You do not have permission to move file.')
src_dir = os.path.dirname(path)
src_dir_utf8 = src_dir.encode('utf-8')
src_repo_id = repo_id
@@ -826,7 +850,7 @@ class FileView(APIView):
seafserv_threaded_rpc.move_file(src_repo_id, src_dir_utf8,
filename_utf8, dst_repo_id,
dst_dir_utf8, new_filename_utf8,
request.user.username)
username)
except SearpcError, e:
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
"SearpcError:" + e.msg)
@@ -839,6 +863,10 @@ class FileView(APIView):
resp['Location'] = uri + '?p=' + quote(dst_dir_utf8) + quote(new_filename_utf8)
return resp
elif operation.lower() == 'create':
if not is_repo_writable(repo.id, username):
return api_error(status.HTTP_403_FORBIDDEN,
'You do not have permission to create file.')
parent_dir = os.path.dirname(path)
parent_dir_utf8 = parent_dir.encode('utf-8')
new_file_name = os.path.basename(path)
@@ -848,11 +876,10 @@ class FileView(APIView):
try:
seafserv_threaded_rpc.post_empty_file(repo_id, parent_dir,
new_file_name,
request.user.username)
new_file_name, username)
except SearpcError, e:
return api_error(HTTP_520_OPERATION_FAILED,
'Failed to make directory.')
'Failed to create file.')
if request.GET.get('reloaddir', '').lower() == 'true':
return reloaddir(request, repo_id, parent_dir)
@@ -877,6 +904,11 @@ class FileView(APIView):
if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
username = request.user.username
if not is_repo_writable(repo.id, username):
return api_error(status.HTTP_403_FORBIDDEN,
'You do not have permission to delete file.')
resp = check_repo_access_permission(request, repo)
if resp:
return resp
@@ -948,7 +980,7 @@ class DirView(APIView):
create/delete/rename/list, etc.
"""
authentication_classes = (TokenAuthentication, )
permission_classes = (IsAuthenticated, IsRepoWritable, )
permission_classes = (IsAuthenticated, )
throttle_classes = (UserRateThrottle, )
def get(self, request, repo_id, format=None):
@@ -993,18 +1025,22 @@ class DirView(APIView):
resp = check_repo_access_permission(request, repo)
if resp:
return resp
path = request.GET.get('p', '')
if not path or path[0] != '/':
return api_error(status.HTTP_400_BAD_REQUEST, "Path is missing.")
if path == '/': # Can not make root dir.
return api_error(status.HTTP_400_BAD_REQUEST, "Path is invalid.")
if path[-1] == '/': # Cut out last '/' if possible.
path = path[:-1]
username = request.user.username
operation = request.POST.get('operation', '')
if operation.lower() == 'mkdir':
if not is_repo_writable(repo.id, username):
return api_error(status.HTTP_403_FORBIDDEN,
'You do not have permission to create folder.')
parent_dir = os.path.dirname(path)
parent_dir_utf8 = parent_dir.encode('utf-8')
new_dir_name = os.path.basename(path)
@@ -1014,8 +1050,7 @@ class DirView(APIView):
try:
seafserv_threaded_rpc.post_dir(repo_id, parent_dir,
new_dir_name,
request.user.username)
new_dir_name, username)
except SearpcError, e:
return api_error(HTTP_520_OPERATION_FAILED,
'Failed to make directory.')
@@ -1042,6 +1077,11 @@ class DirView(APIView):
if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
username = request.user.username
if not is_repo_writable(repo.id, username):
return api_error(status.HTTP_403_FORBIDDEN,
'You do not have permission to delete folder.')
resp = check_repo_access_permission(request, repo)
if resp:
return resp
@@ -1062,8 +1102,7 @@ class DirView(APIView):
try:
seafserv_threaded_rpc.del_file(repo_id, parent_dir_utf8,
file_name_utf8,
request.user.username)
file_name_utf8, username)
except SearpcError, e:
return api_error(HTTP_520_OPERATION_FAILED,
"Failed to delete file.")
@@ -1138,13 +1177,18 @@ class SharedRepo(APIView):
Support uniform interface for shared libraries.
"""
authentication_classes = (TokenAuthentication, )
permission_classes = (IsAuthenticated, IsRepoOwner)
permission_classes = (IsAuthenticated, )
throttle_classes = (UserRateThrottle, )
def delete(self, request, repo_id, format=None):
"""
Unshare a library. Only repo owner can perform this operation.
"""
username = request.user.username
if not seafile_api.is_repo_owner(username, repo_id):
return api_error(status.HTTP_403_FORBIDDEN,
'You do not have permission to unshare library.')
share_type = request.GET.get('share_type', '')
user = request.GET.get('user', '')
group_id = request.GET.get('group_id', '')
@@ -1153,7 +1197,7 @@ class SharedRepo(APIView):
'share_type and user and group_id is required.')
if share_type == 'personal':
remove_share(repo_id, request.user.username, user)
remove_share(repo_id, username, user)
elif share_type == 'group':
unshare_group_repo(repo_id, group_id, user)
elif share_type == 'public':
@@ -1168,6 +1212,11 @@ class SharedRepo(APIView):
"""
Share a repo to users/groups/public.
"""
username = request.user.username
if not seafile_api.is_repo_owner(username, repo_id):
return api_error(status.HTTP_403_FORBIDDEN,
'You do not have permission to share library.')
share_type = request.GET.get('share_type')
user = request.GET.get('user')
group_id = request.GET.get('group_id')