From 8e1312e8ce13dbd04cb6cd8c7536fd18f4de0ca5 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 14 Nov 2022 14:44:18 +0800 Subject: [PATCH] =?UTF-8?q?pref:=20=E4=BF=AE=E6=94=B9=20perm=20token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/authentication/api/connection_token.py | 3 --- .../serializers/connection_token.py | 23 +++++++++++++------ apps/perms/const.py | 5 ++++ apps/perms/models/perm_token.py | 7 ++++++ apps/perms/utils/account.py | 6 +++-- 5 files changed, 32 insertions(+), 12 deletions(-) diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py index c214f93ab..b531c6560 100644 --- a/apps/authentication/api/connection_token.py +++ b/apps/authentication/api/connection_token.py @@ -282,9 +282,6 @@ class ConnectionTokenViewSet(ExtraActionApiMixin, RootOrgViewMixin, JMSModelView raise PermissionDenied(error) -# SuperConnectionToken - - class SuperConnectionTokenViewSet(ConnectionTokenViewSet): serializer_classes = { 'default': SuperConnectionTokenSerializer, diff --git a/apps/authentication/serializers/connection_token.py b/apps/authentication/serializers/connection_token.py index 256661882..5011d73a6 100644 --- a/apps/authentication/serializers/connection_token.py +++ b/apps/authentication/serializers/connection_token.py @@ -1,14 +1,13 @@ +from django.utils.translation import ugettext_lazy as _ from rest_framework import serializers -from django.utils.translation import ugettext_lazy as _ -from orgs.mixins.serializers import OrgResourceModelSerializerMixin +from assets.models import Asset, Gateway, Domain, CommandFilterRule, Account, Platform from authentication.models import ConnectionToken from common.utils import pretty_string from common.utils.random import random_string -from assets.models import Asset, Gateway, Domain, CommandFilterRule, Account -from users.models import User +from orgs.mixins.serializers import OrgResourceModelSerializerMixin from perms.serializers.permission import ActionChoicesField - +from users.models import User __all__ = [ 'ConnectionTokenSerializer', 'ConnectionTokenSecretSerializer', @@ -86,7 +85,6 @@ class ConnectionTokenDisplaySerializer(ConnectionTokenSerializer): class SuperConnectionTokenSerializer(ConnectionTokenSerializer): - class Meta(ConnectionTokenSerializer.Meta): read_only_fields = [ 'validity', 'user_display', 'system_user_display', @@ -104,6 +102,7 @@ class SuperConnectionTokenSerializer(ConnectionTokenSerializer): class ConnectionTokenUserSerializer(serializers.ModelSerializer): """ User """ + class Meta: model = User fields = ['id', 'name', 'username', 'email'] @@ -111,6 +110,7 @@ class ConnectionTokenUserSerializer(serializers.ModelSerializer): class ConnectionTokenAssetSerializer(serializers.ModelSerializer): """ Asset """ + class Meta: model = Asset fields = ['id', 'name', 'address', 'protocols', 'org_id'] @@ -118,6 +118,7 @@ class ConnectionTokenAssetSerializer(serializers.ModelSerializer): class ConnectionTokenAccountSerializer(serializers.ModelSerializer): """ Account """ + class Meta: model = Account fields = [ @@ -127,6 +128,7 @@ class ConnectionTokenAccountSerializer(serializers.ModelSerializer): class ConnectionTokenGatewaySerializer(serializers.ModelSerializer): """ Gateway """ + class Meta: model = Gateway fields = ['id', 'ip', 'port', 'username', 'password', 'private_key'] @@ -143,6 +145,7 @@ class ConnectionTokenDomainSerializer(serializers.ModelSerializer): class ConnectionTokenCmdFilterRuleSerializer(serializers.ModelSerializer): """ Command filter rule """ + class Meta: model = CommandFilterRule fields = [ @@ -151,12 +154,18 @@ class ConnectionTokenCmdFilterRuleSerializer(serializers.ModelSerializer): ] +class ConnectionTokenPlatform(serializers.ModelSerializer): + class Meta: + model = Platform + fields = ['id', 'name', 'org_id'] + + class ConnectionTokenSecretSerializer(OrgResourceModelSerializerMixin): user = ConnectionTokenUserSerializer(read_only=True) asset = ConnectionTokenAssetSerializer(read_only=True) + platform = ConnectionTokenPlatform(read_only=True) account = ConnectionTokenAccountSerializer(read_only=True) gateway = ConnectionTokenGatewaySerializer(read_only=True) - domain = ConnectionTokenDomainSerializer(read_only=True) cmd_filter_rules = ConnectionTokenCmdFilterRuleSerializer(many=True) actions = ActionChoicesField() expire_at = serializers.IntegerField() diff --git a/apps/perms/const.py b/apps/perms/const.py index b78d6b48b..769ce70eb 100644 --- a/apps/perms/const.py +++ b/apps/perms/const.py @@ -27,6 +27,11 @@ class ActionChoices(BitChoices): (_("Clipboard"), [cls.copy, cls.paste]), ) + @classmethod + def has_perm(cls, action_name, total): + action_value = getattr(cls, action_name) + return action_value & total == action_value + class SpecialAccount(models.TextChoices): ALL = "@ALL", "All" diff --git a/apps/perms/models/perm_token.py b/apps/perms/models/perm_token.py index 857cb9dd7..368750c63 100644 --- a/apps/perms/models/perm_token.py +++ b/apps/perms/models/perm_token.py @@ -3,12 +3,19 @@ from django.utils.translation import gettext_lazy as _ class PermToken(models.Model): + """ + 1. 用完失效 + 2. 仅用于授权,不用于认证 + 3. 存 redis 就行 + 4. 有效期 5 分钟 + """ user = models.ForeignKey('users.User', on_delete=models.CASCADE, verbose_name=_('User')) asset = models.ForeignKey('assets.Asset', on_delete=models.CASCADE, verbose_name=_('Asset')) account = models.CharField(max_length=128, verbose_name=_('Account')) secret = models.CharField(max_length=1024, verbose_name=_('Secret')) protocol = models.CharField(max_length=32, verbose_name=_('Protocol')) connect_method = models.CharField(max_length=32, verbose_name=_('Connect method')) + actions = models.IntegerField(verbose_name=_('Actions')) class Meta: abstract = True diff --git a/apps/perms/utils/account.py b/apps/perms/utils/account.py index 167a3060b..baaedb8fc 100644 --- a/apps/perms/utils/account.py +++ b/apps/perms/utils/account.py @@ -1,4 +1,3 @@ -import time from collections import defaultdict from assets.models import Account @@ -9,6 +8,7 @@ __all__ = ['PermAccountUtil'] class PermAccountUtil(AssetPermissionUtil): """ 资产授权账号相关的工具 """ + @staticmethod def get_permed_accounts_from_perms(perms, user, asset): alias_action_bit_mapper = defaultdict(int) @@ -75,7 +75,9 @@ class PermAccountUtil(AssetPermissionUtil): return accounts def validate_permission(self, user, asset, account_username): - """ 校验用户有某个资产下某个账号名的权限 """ + """ 校验用户有某个资产下某个账号名的权限 + :param account_username: 可能是 @USER @INPUT 的 + """ permed_accounts = self.get_permed_accounts_for_user(user, asset) accounts_mapper = {account.username: account for account in permed_accounts}