diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py index 60b91e4db..c0f85757d 100644 --- a/apps/authentication/api/connection_token.py +++ b/apps/authentication/api/connection_token.py @@ -231,7 +231,9 @@ class ConnectionTokenViewSet(ConnectionTokenMixin, RootOrgViewMixin, JMSModelVie 'get_rdp_file': 'authentication.add_connectiontoken', 'get_client_protocol_url': 'authentication.add_connectiontoken', } - queryset = ConnectionToken.objects.all() + + def get_queryset(self): + return ConnectionToken.objects.filter(user=self.request.user) def create_connection_token(self): data = self.request.query_params if self.request.method == 'GET' else self.request.data diff --git a/apps/authentication/models.py b/apps/authentication/models.py index d04a3fa4e..518db566c 100644 --- a/apps/authentication/models.py +++ b/apps/authentication/models.py @@ -228,6 +228,13 @@ class ConnectionToken(OrgModelMixin, models.JMSModel): return {} return self.application.get_rdp_remote_app_setting() + @lazyproperty + def asset_or_remote_app_asset(self): + if self.asset: + return self.asset + if self.application and self.application.category_remote_app: + return self.application.get_remote_app_asset() + @lazyproperty def cmd_filter_rules(self): from assets.models import CommandFilterRule diff --git a/apps/authentication/serializers/connection_token.py b/apps/authentication/serializers/connection_token.py index 0e811cbaa..5c3bef5a2 100644 --- a/apps/authentication/serializers/connection_token.py +++ b/apps/authentication/serializers/connection_token.py @@ -177,7 +177,7 @@ class ConnectionTokenCmdFilterRuleSerializer(serializers.ModelSerializer): class ConnectionTokenSecretSerializer(OrgResourceModelSerializerMixin): user = ConnectionTokenUserSerializer(read_only=True) - asset = ConnectionTokenAssetSerializer(read_only=True) + asset = ConnectionTokenAssetSerializer(read_only=True, source='asset_or_remote_app_asset') application = ConnectionTokenApplicationSerializer(read_only=True) remote_app = ConnectionTokenRemoteAppSerializer(read_only=True) system_user = ConnectionTokenSystemUserSerializer(read_only=True) diff --git a/apps/rbac/builtin.py b/apps/rbac/builtin.py index 93b058504..c56326601 100644 --- a/apps/rbac/builtin.py +++ b/apps/rbac/builtin.py @@ -23,7 +23,7 @@ user_perms = ( ) system_user_perms = ( - ('authentication', 'connectiontoken', 'add', 'connectiontoken'), + ('authentication', 'connectiontoken', 'add,view', 'connectiontoken'), ('authentication', 'temptoken', 'add,change,view', 'temptoken'), ('authentication', 'accesskey', '*', '*'), ('tickets', 'ticket', 'view', 'ticket'), diff --git a/apps/rbac/models/permission.py b/apps/rbac/models/permission.py index bc8fa6231..5b98b6045 100644 --- a/apps/rbac/models/permission.py +++ b/apps/rbac/models/permission.py @@ -60,11 +60,11 @@ class Permission(DjangoPermission): if actions == '*' and resource == '*': pass elif actions == '*' and resource != '*': - kwargs['codename__iregex'] = r'[a-z]+_{}'.format(resource) + kwargs['codename__iregex'] = r'[a-z]+_{}$'.format(resource) elif actions != '*' and resource == '*': kwargs['codename__iregex'] = r'({})_[a-z]+'.format(actions_regex) else: - kwargs['codename__iregex'] = r'({})_{}'.format(actions_regex, resource) + kwargs['codename__iregex'] = r'({})_{}$'.format(actions_regex, resource) q |= Q(**kwargs) return q diff --git a/apps/users/api/profile.py b/apps/users/api/profile.py index 3f5605144..b916c47a9 100644 --- a/apps/users/api/profile.py +++ b/apps/users/api/profile.py @@ -3,6 +3,10 @@ import uuid from rest_framework import generics from rest_framework.permissions import IsAuthenticated +from common.permissions import IsValidUserOrConnectionToken +from common.utils import get_object_or_none +from orgs.utils import tmp_to_root_org +from authentication.models import ConnectionToken from users.notifications import ( ResetPasswordMsg, ResetPasswordSuccessMsg, ResetSSHKeyMsg, @@ -44,12 +48,26 @@ class UserResetPKApi(UserQuerysetMixin, generics.UpdateAPIView): class UserProfileApi(generics.RetrieveUpdateAPIView): - permission_classes = (IsAuthenticated,) + permission_classes = (IsValidUserOrConnectionToken,) serializer_class = serializers.UserProfileSerializer def get_object(self): + if self.request.user.is_anonymous: + user = self.get_connection_token_user() + if user: + return user return self.request.user + def get_connection_token_user(self): + token_id = self.request.query_params.get('token') + if not token_id: + return + with tmp_to_root_org(): + token = get_object_or_none(ConnectionToken, id=token_id) + if not token: + return + return token.user + class UserPasswordApi(generics.RetrieveUpdateAPIView): permission_classes = (IsAuthenticated,)