1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-07-05 11:17:36 +00:00

Fixed a few bugs in share and api2

This commit is contained in:
zhengxie 2012-12-25 11:09:34 +08:00
parent 2b400d9156
commit 0ec2900bc4
5 changed files with 110 additions and 45 deletions

View File

@ -10,7 +10,7 @@ SAFE_METHODS = ['GET', 'HEAD', 'OPTIONS']
class IsRepoWritable(BasePermission): class IsRepoWritable(BasePermission):
""" """
Allows access only for users who has write permission to the repo. Allows access only for user who has write permission to the repo.
""" """
def has_permission(self, request, view, obj=None): def has_permission(self, request, view, obj=None):
@ -23,3 +23,14 @@ class IsRepoWritable(BasePermission):
if user and check_permission(repo_id, user) == 'rw': if user and check_permission(repo_id, user) == 'rw':
return True return True
return False return False
class IsRepoAccessible(BasePermission):
"""
Check whether user has Read or Write permission to a repo.
"""
def has_permission(self, request, view, obj=None):
repo_id = view.kwargs.get('repo_id', '')
user = request.user.username if request.user else ''
return True if check_permission(repo_id, user) else False

View File

@ -25,6 +25,7 @@ urlpatterns = patterns('',
url(r'^repos/$', Repos.as_view()), url(r'^repos/$', Repos.as_view()),
url(r'^repos/(?P<repo_id>[-0-9a-f]{36})/$', Repo.as_view()), url(r'^repos/(?P<repo_id>[-0-9a-f]{36})/$', Repo.as_view()),
url(r'^repos/(?P<repo_id>[-0-9a-f]{36})/download-info/$', DownloadRepo.as_view()), url(r'^repos/(?P<repo_id>[-0-9a-f]{36})/download-info/$', DownloadRepo.as_view()),
url(r'^repos/(?P<repo_id>[-0-9a-f]{36})/upload-link/$', UploadLinkView.as_view()),
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/$', FileView.as_view(), name='FileView'), url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/$', FileView.as_view(), name='FileView'),
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/shared-link/$', FileSharedLinkView.as_view()), url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/shared-link/$', FileSharedLinkView.as_view()),
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/dir/$', DirView.as_view(), name='DirView'), url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/dir/$', DirView.as_view(), name='DirView'),

View File

@ -17,7 +17,7 @@ from django.http import HttpResponse
from models import Token from models import Token
from authentication import TokenAuthentication from authentication import TokenAuthentication
from permissions import IsRepoWritable from permissions import IsRepoWritable, IsRepoAccessible
from serializers import AuthTokenSerializer from serializers import AuthTokenSerializer
from base.accounts import User from base.accounts import User
from share.models import FileShare from share.models import FileShare
@ -99,7 +99,6 @@ class Account(APIView):
info['email'] = email info['email'] = email
info['usage'] = seafserv_threaded_rpc.get_user_quota_usage(email) info['usage'] = seafserv_threaded_rpc.get_user_quota_usage(email)
info['total'] = seafserv_threaded_rpc.get_user_quota(email) info['total'] = seafserv_threaded_rpc.get_user_quota(email)
info['feedback'] = settings.DEFAULT_FROM_EMAIL
return Response(info) return Response(info)
def calculate_repo_info(repo_list, username): def calculate_repo_info(repo_list, username):
@ -193,9 +192,6 @@ def can_access_repo(request, repo_id):
return True return True
def check_repo_access_permission(request, repo): def check_repo_access_permission(request, repo):
if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
if not can_access_repo(request, repo.id): if not can_access_repo(request, repo.id):
return api_error(status.HTTP_403_FORBIDDEN, 'Forbid to access this repo.') return api_error(status.HTTP_403_FORBIDDEN, 'Forbid to access this repo.')
@ -219,22 +215,14 @@ def check_repo_access_permission(request, repo):
class Repo(APIView): class Repo(APIView):
authentication_classes = (TokenAuthentication, ) authentication_classes = (TokenAuthentication, )
permission_classes = (IsAuthenticated,) permission_classes = (IsAuthenticated, IsRepoAccessible, )
def head(self, request, repo_id, format=None):
# TODO
assert False
def get(self, request, repo_id, format=None): def get(self, request, repo_id, format=None):
# check whether user can view repo
repo = get_repo(repo_id) repo = get_repo(repo_id)
if not repo: if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.') return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
# if not can_access_repo(request, repo.id): # check whether user is repo owner
# return api_error('403')
# check whether use is repo owner
if validate_owner(request, repo_id): if validate_owner(request, repo_id):
owner = "self" owner = "self"
else: else:
@ -263,7 +251,11 @@ class Repo(APIView):
return Response(repo_json) return Response(repo_json)
def post(self, request, repo_id, format=None): def post(self, request, repo_id, format=None):
resp = check_repo_access_permission(request, get_repo(repo_id)) repo = get_repo(repo_id)
if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
resp = check_repo_access_permission(request, repo)
if resp: if resp:
return resp return resp
op = request.GET.get('op', 'setpassword') op = request.GET.get('op', 'setpassword')
@ -274,22 +266,20 @@ class Repo(APIView):
class DownloadRepo(APIView): class DownloadRepo(APIView):
authentication_classes = (TokenAuthentication, ) authentication_classes = (TokenAuthentication, )
permission_classes = (IsAuthenticated,) permission_classes = (IsAuthenticated, IsRepoAccessible, )
def get(self, request, repo_id, format=None): def get(self, request, repo_id, format=None):
repo = get_repo(repo_id) repo = get_repo(repo_id)
if not repo: if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.') return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
# TODO: check whether user can access this repo
# generate download url for client # generate download url for client
ccnet_applet_root = get_ccnetapplet_root() ccnet_applet_root = get_ccnetapplet_root()
relay_id = get_session_info().id relay_id = get_session_info().id
addr, port = get_ccnet_server_addr_port () addr, port = get_ccnet_server_addr_port ()
email = quote(request.user.username) email = request.user.username
token = get_repo_token_nonnull(repo_id, request.user.username) token = get_repo_token_nonnull(repo_id, request.user.username)
quote_repo_name = quote(repo.name.encode('utf-8')) repo_name = repo.name
enc = 1 if repo.encrypted else '' enc = 1 if repo.encrypted else ''
info_json = { info_json = {
@ -300,11 +290,31 @@ class DownloadRepo(APIView):
'email': email, 'email': email,
'token': token, 'token': token,
'repo_id': repo_id, 'repo_id': repo_id,
'repo_name': quote_repo_name, 'repo_name': repo_name,
'encrypted': enc, 'encrypted': enc,
} }
return Response(info_json) return Response(info_json)
class UploadLinkView(APIView):
authentication_classes = (TokenAuthentication, )
permission_classes = (IsAuthenticated, )
def get(self, request, repo_id, format=None):
repo = get_repo(repo_id)
if check_permission(repo_id, request.user.username) == 'rw':
token = seafserv_rpc.web_get_access_token(repo_id,
'dummy',
'upload',
request.user.username)
else:
return api_error(status.HTTP_403_FORBIDDEN, "Can not access repo")
if request.cloud_mode and seafserv_threaded_rpc.check_quota(repo_id) < 0:
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Above quota')
upload_url = gen_file_upload_url(token, 'upload')
return Response(upload_url)
def get_file_size (id): def get_file_size (id):
size = seafserv_threaded_rpc.get_file_size(id) size = seafserv_threaded_rpc.get_file_size(id)
return size if size else 0 return size if size else 0
@ -348,6 +358,9 @@ class RepoDirents(APIView):
def get(self, request, repo_id): def get(self, request, repo_id):
repo = get_repo(repo_id) repo = get_repo(repo_id)
if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
resp = check_repo_access_permission(request, repo) resp = check_repo_access_permission(request, repo)
if resp: if resp:
return resp return resp
@ -391,6 +404,9 @@ class RepoDirs(APIView):
def get(self, request, repo_id, dir_id, format=None): def get(self, request, repo_id, dir_id, format=None):
repo = get_repo(repo_id) repo = get_repo(repo_id)
if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
resp = check_repo_access_permission(request, repo) resp = check_repo_access_permission(request, repo)
if resp: if resp:
return resp return resp
@ -449,6 +465,9 @@ class RepoFilepath(APIView):
def get(self, request, repo_id, format=None): def get(self, request, repo_id, format=None):
repo = get_repo(repo_id) repo = get_repo(repo_id)
if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
resp = check_repo_access_permission(request, repo) resp = check_repo_access_permission(request, repo)
if resp: if resp:
return resp return resp
@ -474,6 +493,9 @@ class RepoFilepath(APIView):
def post(self, request, repo_id, format=None): def post(self, request, repo_id, format=None):
repo = get_repo(repo_id) repo = get_repo(repo_id)
if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
resp = check_repo_access_permission(request, repo) resp = check_repo_access_permission(request, repo)
if resp: if resp:
return resp return resp
@ -501,6 +523,9 @@ class RepoFiles(APIView):
def get(self, request, repo_id, file_id, format=None): def get(self, request, repo_id, file_id, format=None):
repo = get_repo(repo_id) repo = get_repo(repo_id)
if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
resp = check_repo_access_permission(request, repo) resp = check_repo_access_permission(request, repo)
if resp: if resp:
return resp return resp
@ -545,7 +570,11 @@ class OpDeleteView(APIView):
permission_classes = (IsAuthenticated, IsRepoWritable, ) permission_classes = (IsAuthenticated, IsRepoWritable, )
def post(self, request, repo_id, format=None): def post(self, request, repo_id, format=None):
resp = check_repo_access_permission(request, get_repo(repo_id)) repo = get_repo(repo_id)
if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
resp = check_repo_access_permission(request, repo)
if resp: if resp:
return resp return resp
@ -577,7 +606,11 @@ class OpRenameView(APIView):
permission_classes = (IsAuthenticated, IsRepoWritable, ) permission_classes = (IsAuthenticated, IsRepoWritable, )
def post(self, request, repo_id, format=None): def post(self, request, repo_id, format=None):
resp = check_repo_access_permission(request, get_repo(repo_id)) repo = get_repo(repo_id)
if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
resp = check_repo_access_permission(request, repo)
if resp: if resp:
return resp return resp
@ -668,7 +701,11 @@ class OpMkdirView(APIView):
permission_classes = (IsAuthenticated, IsRepoWritable, ) permission_classes = (IsAuthenticated, IsRepoWritable, )
def post(self, request, repo_id, format=None): def post(self, request, repo_id, format=None):
resp = check_repo_access_permission(request, get_repo(repo_id)) repo = get_repo(repo_id)
if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
resp = check_repo_access_permission(request, repo)
if resp: if resp:
return resp return resp
path = request.GET.get('p') path = request.GET.get('p')
@ -788,6 +825,9 @@ class FileView(APIView):
def get(self, request, repo_id, format=None): def get(self, request, repo_id, format=None):
# view file # view file
repo = get_repo(repo_id) repo = get_repo(repo_id)
if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
resp = check_repo_access_permission(request, repo) resp = check_repo_access_permission(request, repo)
if resp: if resp:
return resp return resp
@ -813,7 +853,11 @@ class FileView(APIView):
def post(self, request, repo_id, format=None): def post(self, request, repo_id, format=None):
# rename or move file # rename or move file
resp = check_repo_access_permission(request, get_repo(repo_id)) repo = get_repo(repo_id)
if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
resp = check_repo_access_permission(request, repo)
if resp: if resp:
return resp return resp
@ -918,6 +962,9 @@ class FileView(APIView):
def delete(self, request, repo_id, format=None): def delete(self, request, repo_id, format=None):
# delete file # delete file
repo = get_repo(repo_id) repo = get_repo(repo_id)
if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
resp = check_repo_access_permission(request, repo) resp = check_repo_access_permission(request, repo)
if resp: if resp:
return resp return resp
@ -993,6 +1040,9 @@ class DirView(APIView):
def get(self, request, repo_id, format=None): def get(self, request, repo_id, format=None):
# list dir # list dir
repo = get_repo(repo_id) repo = get_repo(repo_id)
if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
resp = check_repo_access_permission(request, repo) resp = check_repo_access_permission(request, repo)
if resp: if resp:
return resp return resp
@ -1022,7 +1072,11 @@ class DirView(APIView):
def post(self, request, repo_id, format=None): def post(self, request, repo_id, format=None):
# new dir # new dir
resp = check_repo_access_permission(request, get_repo(repo_id)) repo = get_repo(repo_id)
if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
resp = check_repo_access_permission(request, repo)
if resp: if resp:
return resp return resp
path = request.GET.get('p', '') path = request.GET.get('p', '')
@ -1071,6 +1125,9 @@ class DirView(APIView):
def delete(self, request, repo_id, format=None): def delete(self, request, repo_id, format=None):
# delete dir or file # delete dir or file
repo = get_repo(repo_id) repo = get_repo(repo_id)
if not repo:
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
resp = check_repo_access_permission(request, repo) resp = check_repo_access_permission(request, repo)
if resp: if resp:
return resp return resp

View File

@ -108,15 +108,6 @@ def share_repo(request):
mail_sended.send(sender=None, user=request.user.username, mail_sended.send(sender=None, user=request.user.username,
email=to_email) email=to_email)
# Record share info to db.
try:
seafserv_threaded_rpc.add_share(repo_id, from_email, to_email,
permission)
except SearpcError, e:
msg = _(u'Failed to share to %s .') % to_email
messages.add_message(request, messages.ERROR, msg)
continue
if not is_registered_user(to_email): if not is_registered_user(to_email):
# Generate shared link and send mail if user has not registered. # Generate shared link and send mail if user has not registered.
# kwargs = {'repo_id': repo_id, # kwargs = {'repo_id': repo_id,
@ -129,6 +120,15 @@ def share_repo(request):
messages.add_message(request, messages.ERROR, msg) messages.add_message(request, messages.ERROR, msg)
continue continue
else: else:
# Record share info to db.
try:
seafserv_threaded_rpc.add_share(repo_id, from_email, to_email,
permission)
except SearpcError, e:
msg = _(u'Failed to share to %s .') % to_email
messages.add_message(request, messages.ERROR, msg)
continue
msg = _(u'Shared to %(email)s successfullygo check it at <a href="%(share)s">Share</a>.') % \ msg = _(u'Shared to %(email)s successfullygo check it at <a href="%(share)s">Share</a>.') % \
{'email':to_email, 'share':reverse('share_admin')} {'email':to_email, 'share':reverse('share_admin')}
messages.add_message(request, messages.INFO, msg) messages.add_message(request, messages.INFO, msg)

View File

@ -558,9 +558,7 @@ def list_inner_pub_repos(username):
shared_repos = [] shared_repos = []
for repo in shared_repos: for repo in shared_repos:
perm = seafserv_threaded_rpc.check_permission(repo.props.repo_id, repo.user_perm = check_permission(repo.props.repo_id, username)
username)
repo.user_perm = perm
shared_repos.sort(lambda x, y: cmp(y.props.last_modified, x.props.last_modified)) shared_repos.sort(lambda x, y: cmp(y.props.last_modified, x.props.last_modified))
return shared_repos return shared_repos
@ -588,9 +586,7 @@ def list_org_inner_pub_repos(org_id, username, start=None, limit=None):
shared_repos = [] shared_repos = []
for repo in shared_repos: for repo in shared_repos:
perm = seafserv_threaded_rpc.check_permission(repo.props.repo_id, repo.user_perm = check_permission(repo.props.repo_id, username)
username)
repo.user_perm = perm
# sort repos by last modify time # sort repos by last modify time
shared_repos.sort(lambda x, y: cmp(y.props.last_modified, x.props.last_modified)) shared_repos.sort(lambda x, y: cmp(y.props.last_modified, x.props.last_modified))
@ -600,12 +596,12 @@ def list_org_inner_pub_repos(org_id, username, start=None, limit=None):
def check_permission(repo_id, user): def check_permission(repo_id, user):
""" """
Check whether user has permission to access repo. Check whether user has permission to access repo.
Return true if user has permission otherwise false. Return values can be 'rw' or 'r' or None.
""" """
try: try:
ret = seafserv_threaded_rpc.check_permission(repo_id, user) ret = seafserv_threaded_rpc.check_permission(repo_id, user)
except SearpcError: except SearpcError:
ret = "" ret = None
return ret return ret
def is_personal_repo(repo_id): def is_personal_repo(repo_id):