refactor: ConnectionToken 修改 Model 和序列类

pull/8997/head
Jiangjie.Bai 2022-10-28 15:58:05 +08:00
parent 2b5b4ad605
commit bcd1d5585b
2 changed files with 47 additions and 30 deletions

View File

@ -75,7 +75,7 @@ class ConnectionToken(OrgModelMixin, JMSBaseModel):
# actions 和 expired_at 在 check_valid() 中赋值 # actions 和 expired_at 在 check_valid() 中赋值
actions = expire_at = None actions = expire_at = None
def check_valid(self): def check_permission(self):
from perms.utils.account import PermAccountUtil from perms.utils.account import PermAccountUtil
if self.is_expired: if self.is_expired:
is_valid = False is_valid = False
@ -89,13 +89,15 @@ class ConnectionToken(OrgModelMixin, JMSBaseModel):
is_valid = False is_valid = False
error = _('No asset or inactive asset') error = _('No asset or inactive asset')
return is_valid, error return is_valid, error
if not self.account: if not self.account_username:
is_valid = False is_valid = False
error = _('No account') error = _('No account')
return is_valid, error return is_valid, error
account_util = PermAccountUtil() account_util = PermAccountUtil()
actions, expire_at = account_util.validate_permission(self.user, self.asset, self.account) actions, expire_at = account_util.validate_permission(
self.user, self.asset, self.account_username
)
if not actions or expire_at < time.time(): if not actions or expire_at < time.time():
is_valid = False is_valid = False
error = _('User has no permission to access asset or permission expired') error = _('User has no permission to access asset or permission expired')
@ -104,6 +106,13 @@ class ConnectionToken(OrgModelMixin, JMSBaseModel):
self.expire_at = expire_at self.expire_at = expire_at
return True, '' return True, ''
@lazyproperty
def account(self):
if not self.asset:
return None
account = self.asset.accounts.filter(username=self.account_username).first()
return account
@lazyproperty @lazyproperty
def domain(self): def domain(self):
domain = self.asset.domain if self.asset else None domain = self.asset.domain if self.asset else None

View File

@ -5,7 +5,7 @@ from orgs.mixins.serializers import OrgResourceModelSerializerMixin
from authentication.models import ConnectionToken from authentication.models import ConnectionToken
from common.utils import pretty_string from common.utils import pretty_string
from common.utils.random import random_string from common.utils.random import random_string
from assets.models import Asset, Gateway, Domain, CommandFilterRule from assets.models import Asset, Gateway, Domain, CommandFilterRule, Account
from users.models import User from users.models import User
from perms.serializers.permission import ActionsField from perms.serializers.permission import ActionsField
@ -24,34 +24,33 @@ class ConnectionTokenSerializer(OrgResourceModelSerializerMixin):
model = ConnectionToken model = ConnectionToken
fields_mini = ['id'] fields_mini = ['id']
fields_small = fields_mini + [ fields_small = fields_mini + [
'secret', 'date_expired', 'date_created', 'date_updated', 'secret', 'account_username', 'date_expired',
'date_created', 'date_updated',
'created_by', 'updated_by', 'org_id', 'org_name', 'created_by', 'updated_by', 'org_id', 'org_name',
] ]
fields_fk = [ fields_fk = [
'user', 'system_user', 'asset', 'user', 'asset',
] ]
read_only_fields = [ read_only_fields = [
# 普通 Token 不支持指定 user # 普通 Token 不支持指定 user
'user', 'is_valid', 'expire_time', 'user', 'is_valid', 'expire_time',
'user_display', 'system_user_display', 'user_display', 'asset_display',
'asset_display',
] ]
fields = fields_small + fields_fk + read_only_fields fields = fields_small + fields_fk + read_only_fields
def get_request_user(self):
request = self.context.get('request')
user = request.user if request else None
return user
def get_user(self, attrs):
return self.get_request_user()
def validate(self, attrs): def validate(self, attrs):
fields_attrs = self.construct_internal_fields_attrs(attrs) fields_attrs = self.construct_internal_fields_attrs(attrs)
attrs.update(fields_attrs) attrs.update(fields_attrs)
return attrs return attrs
@property
def request_user(self):
request = self.context.get('request')
if request:
return request.user
def get_user(self, attrs):
return self.request_user
def construct_internal_fields_attrs(self, attrs): def construct_internal_fields_attrs(self, attrs):
asset = attrs.get('asset') or '' asset = attrs.get('asset') or ''
asset_display = pretty_string(str(asset), max_length=128) asset_display = pretty_string(str(asset), max_length=128)
@ -63,8 +62,7 @@ class ConnectionTokenSerializer(OrgResourceModelSerializerMixin):
if not isinstance(asset, Asset): if not isinstance(asset, Asset):
error = '' error = ''
raise serializers.ValidationError(error) raise serializers.ValidationError(error)
attrs = {
return {
'user': user, 'user': user,
'secret': secret, 'secret': secret,
'user_display': user_display, 'user_display': user_display,
@ -72,6 +70,7 @@ class ConnectionTokenSerializer(OrgResourceModelSerializerMixin):
'date_expired': date_expired, 'date_expired': date_expired,
'org_id': org_id, 'org_id': org_id,
} }
return attrs
class ConnectionTokenDisplaySerializer(ConnectionTokenSerializer): class ConnectionTokenDisplaySerializer(ConnectionTokenSerializer):
@ -95,7 +94,7 @@ class SuperConnectionTokenSerializer(ConnectionTokenSerializer):
] ]
def get_user(self, attrs): def get_user(self, attrs):
return attrs.get('user') or self.request_user return attrs.get('user') or self.get_request_user()
# #
@ -104,31 +103,37 @@ class SuperConnectionTokenSerializer(ConnectionTokenSerializer):
class ConnectionTokenUserSerializer(serializers.ModelSerializer): class ConnectionTokenUserSerializer(serializers.ModelSerializer):
""" User """
class Meta: class Meta:
model = User model = User
fields = ['id', 'name', 'username', 'email'] fields = ['id', 'name', 'username', 'email']
class ConnectionTokenAssetSerializer(serializers.ModelSerializer): class ConnectionTokenAssetSerializer(serializers.ModelSerializer):
""" Asset """
class Meta: class Meta:
model = Asset model = Asset
fields = ['id', 'name', 'ip', 'protocols', 'org_id'] fields = ['id', 'name', 'ip', 'protocols', 'org_id']
class ConnectionTokenAccountSerializer(serializers.ModelSerializer):
""" Account """
class Meta:
model = Account
fields = [
'id', 'name', 'username', 'secret_type', 'secret', 'version'
]
class ConnectionTokenGatewaySerializer(serializers.ModelSerializer): class ConnectionTokenGatewaySerializer(serializers.ModelSerializer):
""" Gateway """
class Meta: class Meta:
model = Gateway model = Gateway
fields = ['id', 'ip', 'port', 'username', 'password', 'private_key'] fields = ['id', 'ip', 'port', 'username', 'password', 'private_key']
class ConnectionTokenRemoteAppSerializer(serializers.Serializer):
program = serializers.CharField(allow_null=True, allow_blank=True)
working_directory = serializers.CharField(allow_null=True, allow_blank=True)
parameters = serializers.CharField(allow_null=True, allow_blank=True)
class ConnectionTokenDomainSerializer(serializers.ModelSerializer): class ConnectionTokenDomainSerializer(serializers.ModelSerializer):
""" Domain """
gateways = ConnectionTokenGatewaySerializer(many=True, read_only=True) gateways = ConnectionTokenGatewaySerializer(many=True, read_only=True)
class Meta: class Meta:
@ -137,6 +142,7 @@ class ConnectionTokenDomainSerializer(serializers.ModelSerializer):
class ConnectionTokenCmdFilterRuleSerializer(serializers.ModelSerializer): class ConnectionTokenCmdFilterRuleSerializer(serializers.ModelSerializer):
""" Command filter rule """
class Meta: class Meta:
model = CommandFilterRule model = CommandFilterRule
fields = [ fields = [
@ -148,7 +154,7 @@ class ConnectionTokenCmdFilterRuleSerializer(serializers.ModelSerializer):
class ConnectionTokenSecretSerializer(OrgResourceModelSerializerMixin): class ConnectionTokenSecretSerializer(OrgResourceModelSerializerMixin):
user = ConnectionTokenUserSerializer(read_only=True) user = ConnectionTokenUserSerializer(read_only=True)
asset = ConnectionTokenAssetSerializer(read_only=True) asset = ConnectionTokenAssetSerializer(read_only=True)
remote_app = ConnectionTokenRemoteAppSerializer(read_only=True) account = ConnectionTokenAccountSerializer(read_only=True)
gateway = ConnectionTokenGatewaySerializer(read_only=True) gateway = ConnectionTokenGatewaySerializer(read_only=True)
domain = ConnectionTokenDomainSerializer(read_only=True) domain = ConnectionTokenDomainSerializer(read_only=True)
cmd_filter_rules = ConnectionTokenCmdFilterRuleSerializer(many=True) cmd_filter_rules = ConnectionTokenCmdFilterRuleSerializer(many=True)
@ -158,6 +164,8 @@ class ConnectionTokenSecretSerializer(OrgResourceModelSerializerMixin):
class Meta: class Meta:
model = ConnectionToken model = ConnectionToken
fields = [ fields = [
'id', 'secret', 'type', 'user', 'asset', 'account', 'protocol', 'id', 'secret',
'cmd_filter_rules', 'domain', 'gateway', 'actions', 'expired_at', 'user', 'asset', 'account_username', 'account', 'protocol',
'domain', 'gateway', 'cmd_filter_rules',
'actions', 'expired_at',
] ]