diff --git a/seahub/api2/endpoints/share_links.py b/seahub/api2/endpoints/share_links.py index bda9c18594..e59fa78605 100644 --- a/seahub/api2/endpoints/share_links.py +++ b/seahub/api2/endpoints/share_links.py @@ -19,6 +19,7 @@ from pysearpc import SearpcError from seahub.api2.utils import api_error from seahub.api2.authentication import TokenAuthentication from seahub.api2.throttling import UserRateThrottle +from seahub.api2.permissions import CanGenerateShareLink from seahub.share.models import FileShare, OrgFileShare from seahub.utils import gen_shared_link, is_org_context @@ -75,13 +76,9 @@ def get_share_link_info(fileshare): class ShareLinks(APIView): authentication_classes = (TokenAuthentication, SessionAuthentication) - permission_classes = (IsAuthenticated,) + permission_classes = (IsAuthenticated, CanGenerateShareLink) throttle_classes = (UserRateThrottle,) - def _can_generate_shared_link(self, request): - - return request.user.permissions.can_generate_shared_link() - def _generate_obj_id_and_type_by_path(self, repo_id, path): file_id = seafile_api.get_file_id_by_path(repo_id, path) @@ -101,10 +98,6 @@ class ShareLinks(APIView): 1. default(NOT guest) user; """ - if not self._can_generate_shared_link(request): - error_msg = 'Permission denied.' - return api_error(status.HTTP_403_FORBIDDEN, error_msg) - # get all share links username = request.user.username fileshares = FileShare.objects.filter(username=username) @@ -219,10 +212,6 @@ class ShareLinks(APIView): return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check - if not self._can_generate_shared_link(request): - error_msg = 'Permission denied.' - return api_error(status.HTTP_403_FORBIDDEN, error_msg) - if not check_folder_permission(request, repo_id, path): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) @@ -250,13 +239,9 @@ class ShareLinks(APIView): class ShareLink(APIView): authentication_classes = (TokenAuthentication, SessionAuthentication) - permission_classes = (IsAuthenticated,) + permission_classes = (IsAuthenticated, CanGenerateShareLink) throttle_classes = (UserRateThrottle,) - def _can_generate_shared_link(self, request): - - return request.user.permissions.can_generate_shared_link() - def get(self, request, token): """ Get a special share link info. @@ -264,10 +249,6 @@ class ShareLink(APIView): 1. default(NOT guest) user; """ - if not self._can_generate_shared_link(request): - error_msg = 'Permission denied.' - return api_error(status.HTTP_403_FORBIDDEN, error_msg) - try: fs = FileShare.objects.get(token=token) except FileShare.DoesNotExist: @@ -285,10 +266,6 @@ class ShareLink(APIView): 2. link owner; """ - if not self._can_generate_shared_link(request): - error_msg = 'Permission denied.' - return api_error(status.HTTP_403_FORBIDDEN, error_msg) - try: fs = FileShare.objects.get(token=token) except FileShare.DoesNotExist: diff --git a/seahub/api2/endpoints/upload_links.py b/seahub/api2/endpoints/upload_links.py index c12b6dff49..e2c68aaa6e 100644 --- a/seahub/api2/endpoints/upload_links.py +++ b/seahub/api2/endpoints/upload_links.py @@ -17,6 +17,7 @@ from pysearpc import SearpcError from seahub.api2.utils import api_error from seahub.api2.authentication import TokenAuthentication from seahub.api2.throttling import UserRateThrottle +from seahub.api2.permissions import CanGenerateUploadLink from seahub.share.models import UploadLinkShare from seahub.utils import gen_shared_upload_link @@ -28,13 +29,9 @@ logger = logging.getLogger(__name__) class UploadLinks(APIView): authentication_classes = (TokenAuthentication, SessionAuthentication) - permission_classes = (IsAuthenticated,) + permission_classes = (IsAuthenticated, CanGenerateUploadLink) throttle_classes = (UserRateThrottle, ) - def _can_generate_shared_link(self, request): - - return request.user.permissions.can_generate_shared_link() - def _get_upload_link_info(self, uls): data = {} token = uls.token @@ -76,10 +73,6 @@ class UploadLinks(APIView): 1. default(NOT guest) user; """ - if not self._can_generate_shared_link(request): - error_msg = 'Permission denied.' - return api_error(status.HTTP_403_FORBIDDEN, error_msg) - # get all upload links username = request.user.username upload_link_shares = UploadLinkShare.objects.filter(username=username) @@ -166,11 +159,6 @@ class UploadLinks(APIView): error_msg = 'folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) - # permission check - if not self._can_generate_shared_link(request): - error_msg = 'Permission denied.' - return api_error(status.HTTP_403_FORBIDDEN, error_msg) - if check_folder_permission(request, repo_id, path) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) @@ -187,13 +175,9 @@ class UploadLinks(APIView): class UploadLink(APIView): authentication_classes = (TokenAuthentication, SessionAuthentication) - permission_classes = (IsAuthenticated,) + permission_classes = (IsAuthenticated, CanGenerateUploadLink) throttle_classes = (UserRateThrottle, ) - def _can_generate_shared_link(self, request): - - return request.user.permissions.can_generate_shared_link() - def get(self, request, token): """ Get upload link info. @@ -201,10 +185,6 @@ class UploadLink(APIView): 1. default(NOT guest) user; """ - if not self._can_generate_shared_link(request): - error_msg = 'Permission denied.' - return api_error(status.HTTP_403_FORBIDDEN, error_msg) - try: uls = UploadLinkShare.objects.get(token=token) except UploadLinkShare.DoesNotExist: @@ -222,10 +202,6 @@ class UploadLink(APIView): 2. link owner; """ - if not self._can_generate_shared_link(request): - error_msg = 'Permission denied.' - return api_error(status.HTTP_403_FORBIDDEN, error_msg) - try: uls = UploadLinkShare.objects.get(token=token) except UploadLinkShare.DoesNotExist: diff --git a/seahub/api2/permissions.py b/seahub/api2/permissions.py index 492d45d9e4..e307ed0d4b 100644 --- a/seahub/api2/permissions.py +++ b/seahub/api2/permissions.py @@ -26,7 +26,7 @@ class IsRepoWritable(BasePermission): if user and check_permission(repo_id, user) == 'rw': return True return False - + class IsRepoAccessible(BasePermission): """ Check whether user has Read or Write permission to a repo. @@ -64,3 +64,15 @@ class CanInviteGuest(BasePermission): def has_permission(self, request, *args, **kwargs): return settings.ENABLE_GUEST_INVITATION and \ request.user.permissions.can_invite_guest() + +class CanGenerateShareLink(BasePermission): + """Check user has permission to generate share link. + """ + def has_permission(self, request, *args, **kwargs): + return request.user.permissions.can_generate_share_link() + +class CanGenerateUploadLink(BasePermission): + """Check user has permission to generate upload link. + """ + def has_permission(self, request, *args, **kwargs): + return request.user.permissions.can_generate_upload_link() diff --git a/seahub/api2/serializers.py b/seahub/api2/serializers.py index 03bdb66e25..6e520abcbd 100644 --- a/seahub/api2/serializers.py +++ b/seahub/api2/serializers.py @@ -1,11 +1,17 @@ # Copyright (c) 2012-2016 Seafile Ltd. +import logging + from rest_framework import serializers from seahub.auth import authenticate -from seahub.api2.models import Token, TokenV2, DESKTOP_PLATFORMS +from seahub.api2.models import DESKTOP_PLATFORMS from seahub.api2.utils import get_token_v1, get_token_v2 from seahub.profile.models import Profile -from seahub.utils.two_factor_auth import has_two_factor_auth, two_factor_auth_enabled, verify_two_factor_token +from seahub.utils.two_factor_auth import has_two_factor_auth, \ + two_factor_auth_enabled, verify_two_factor_token +from seahub.utils.user_permissions import populate_user_permissions + +logger = logging.getLogger(__name__) def all_none(values): for value in values: @@ -72,6 +78,20 @@ class AuthTokenSerializer(serializers.Serializer): else: raise serializers.ValidationError('Must include "username" and "password"') + populate_user_permissions(user) + + if platform in DESKTOP_PLATFORMS: + if not user.permissions.can_connect_with_desktop_clients(): + raise serializers.ValidationError('Not allowed to connect to desktop client.') + elif platform == 'android': + if not user.permissions.can_connect_with_android_clients(): + raise serializers.ValidationError('Not allowed to connect to android client.') + elif platform == 'ios': + if not user.permissions.can_connect_with_ios_clients(): + raise serializers.ValidationError('Not allowed to connect to ios client.') + else: + logger.info('%s: unrecognized device' % login_id) + self._two_factor_auth(self.context['request'], user) # Now user is authenticated diff --git a/seahub/base/accounts.py b/seahub/base/accounts.py index 4bc1fc1742..6bd428ce3c 100644 --- a/seahub/base/accounts.py +++ b/seahub/base/accounts.py @@ -110,8 +110,11 @@ class UserPermissions(object): def can_add_group(self): return get_enabled_role_permissions_by_role(DEFAULT_USER)['can_add_group'] - def can_generate_shared_link(self): - return get_enabled_role_permissions_by_role(DEFAULT_USER)['can_generate_shared_link'] + def can_generate_share_link(self): + return get_enabled_role_permissions_by_role(DEFAULT_USER)['can_generate_share_link'] + + def can_generate_upload_link(self): + return get_enabled_role_permissions_by_role(DEFAULT_USER)['can_generate_upload_link'] def can_use_global_address_book(self): return get_enabled_role_permissions_by_role(DEFAULT_USER)['can_use_global_address_book'] diff --git a/seahub/role_permissions/settings.py b/seahub/role_permissions/settings.py index d3bb3bcf59..94219cae5f 100644 --- a/seahub/role_permissions/settings.py +++ b/seahub/role_permissions/settings.py @@ -14,7 +14,8 @@ DEFAULT_ENABLED_ROLE_PERMISSIONS = { 'can_add_group': True, 'can_view_org': True, 'can_use_global_address_book': True, - 'can_generate_shared_link': True, + 'can_generate_share_link': True, + 'can_generate_upload_link': True, 'can_invite_guest': False, # followings are not implemented yet 'can_drag_drop_folder_to_sync': True, diff --git a/seahub/settings.py b/seahub/settings.py index 26d2020efa..a8f98f033d 100644 --- a/seahub/settings.py +++ b/seahub/settings.py @@ -517,15 +517,6 @@ ENABLE_FOLDER_PERM = False #################### # Role permissions # #################### -# default permissions: -# 'default': { -# 'can_add_repo': True, -# 'can_add_group': True, -# 'can_view_org': True, -# 'can_user_global_address_book': True, -# 'can_generate_shared_link': True, -# 'can_invite_guest': False, -# } from seahub.constants import GUEST_USER ENABLED_ROLE_PERMISSIONS = { GUEST_USER: { @@ -533,8 +524,12 @@ ENABLED_ROLE_PERMISSIONS = { 'can_add_group': False, 'can_view_org': False, 'can_use_global_address_book': False, - 'can_generate_shared_link': False, + 'can_generate_share_link': False, + 'can_generate_upload_link': False, 'can_invite_guest': False, + 'can_connect_with_android_clients': False, + 'can_connect_with_ios_clients': False, + 'can_connect_with_desktop_clients': False, }, } diff --git a/seahub/templates/js/templates.html b/seahub/templates/js/templates.html index b75d423076..ae698ccddb 100644 --- a/seahub/templates/js/templates.html +++ b/seahub/templates/js/templates.html @@ -50,7 +50,7 @@ <% if (encrypted && enc_version == 2) { %>
  • {% trans "Change Password" %}
  • <% } %> - <% if (!encrypted) { %> + <% if (!encrypted && (can_generate_share_link || can_generate_upload_link)) { %>
  • {% trans "Share Links" %}
  • <% } %> <% if (app.pageOptions.folder_perm_enabled) { %> @@ -134,7 +134,7 @@ <% } %> - <% if (!encrypted && can_generate_shared_link) { %> + <% if (!encrypted) { %> <% } %> @@ -214,7 +214,7 @@ - <% if (!repo_encrypted && can_generate_shared_link) { %> + <% if (!repo_encrypted) { %> <% } %> <% if (dirent.perm == 'rw') { %> @@ -297,7 +297,7 @@
    - <% if (!repo_encrypted && can_generate_shared_link) { %> + <% if (!repo_encrypted && can_generate_share_link) { %> <% } %> <% if (dirent.perm == 'rw') { %> @@ -378,7 +378,7 @@ @@ -1586,9 +1600,11 @@
  • {% trans "Download Links" %}
  • + <% if (can_generate_upload_link) { %>
  • {% trans "Upload Links" %}
  • + <% } %>
    @@ -1616,9 +1632,11 @@