Files
jumpserver/apps/perms/utils/asset_perm.py
fit2bot 3f4141ca0b merge: with pam (#14911)
* perf: change i18n

* perf: pam

* perf: change translate

* perf: add check account

* perf: add date field

* perf: add account filter

* perf: remove some js

* perf: add account status action

* perf: update pam

* perf: 修改 discover account

* perf: update filter

* perf: update gathered account

* perf: 修改账号同步

* perf: squash migrations

* perf: update pam

* perf: change i18n

* perf: update account risk

* perf: 更新风险发现

* perf: remove css

* perf: Admin connection token

* perf: Add a switch to check connectivity after changing the password, and add a custom ssh command for push tasks

* perf: Modify account migration files

* perf: update pam

* perf: remove to check account dir

* perf: Admin connection token

* perf: update check account

* perf: 优化发送结果

* perf: update pam

* perf: update bulk update create

* perf: prepaire using thread timer for bulk_create_decorator

* perf: update bulk create decorator

* perf: 优化 playbook manager

* perf: 优化收集账号的报表

* perf: Update poetry

* perf: Update Dockerfile with new base image tag

* fix: Account migrate 0012 file

* perf: 修改备份

* perf: update pam

* fix: Expand resource_type filter to include raw type

* feat: PAM Service (#14552)

* feat: PAM Service

* perf: import package name

---------

Co-authored-by: jiangweidong <1053570670@qq.com>

* perf: Change secret dashboard (#14551)

Co-authored-by: feng <1304903146@qq.com>

* perf: update migrations

* perf: 修改支持 pam

* perf: Change secret record table dashboard

* perf: update status

* fix: Automation send report

* perf: Change secret report

* feat: windows accounts gather

* perf: update change status

* perf: Account backup

* perf: Account backup report

* perf: Account migrate

* perf: update service to application

* perf: update migrations

* perf: update logo

* feat: oracle accounts gather (#14571)

* feat: oracle accounts gather

* feat: sqlserver accounts gather

* feat: postgresql accounts gather

* feat: mysql accounts gather

---------

Co-authored-by: wangruidong <940853815@qq.com>

* feat: mongodb accounts gather

* perf: Change secret

* perf: Migrate

* perf: Merge conflicting migration files

* perf: Change secret

* perf: Automation filter org

* perf: Account push

* perf: Random secret string

* perf: Enhance SQL query and update risk handling in accounts

* perf: Ticket filter assignee_id

* perf: 修改 account remote

* perf: 修改一些 adhoc 任务

* perf: Change secret

* perf: Remove push account extra api

* perf: update status

* perf: The entire organization can view activity log

* fix: risk field check

* perf: add account details api

* perf: add demo mode

* perf: Delete gather_account

* perf: Perfect solution to account version problem

* perf: Update status action to handle multiple accounts

* perf: Add GatherAccountDetailField and update serializers

* perf: Display account history in combination with password change records

* perf: Lina translate

* fix: Update mysql_filter to handle nested user info

* perf: Admin connection token validate_permission account

* perf: copy move account

* perf: account filter risk

* perf: account risk filter

* perf: Copy move account failed message

* fix: gather account sync account to asset

* perf: Pam dashboard

* perf: Account dashboard total accounts

* perf: Pam dashboard

* perf: Change secret filter account secret_reset

* perf: 修改 risk filter

* perf: pam translate

* feat: Check for leaked duplicate passwords. (#14711)

* feat: Check for leaked duplicate passwords.

* perf: Use SQLite instead of txt as leak password database

---------

Co-authored-by: jiangweidong <1053570670@qq.com>
Co-authored-by: 老广 <ibuler@qq.com>

* perf: merge with remote

* perf: Add risk change_password_add handle

* perf: Pam dashboard

* perf: check account manager import

* perf: 重构扫描

* perf: 修改 db

* perf: Gather account manager

* perf: update change db lib

* perf: dashboard

* perf: Account gather

* perf: 修改 asset get queryset

* perf: automation report

* perf: Pam account

* perf: Pam dashboard api

* perf: risk add account

* perf: 修改 risk check

* perf: Risk account

* perf: update risk add reopen action

* perf: add pylintrc

* Revert "perf: automation report"

This reverts commit 22aee54207.

* perf: check account engine

* perf: Perf: Optimism Gather Report Style

* Perf: Remove unuser actions

* Perf: Perf push account

* perf: perf gather account

* perf: Automation report

* perf: Push account recorder

* perf: Push account record

* perf: Pam dashboard

* perf: perf

* perf: update intergration

* perf: integrations application detail add account tab page

* feat: Custom change password supports configuration of interactive items

* perf: Go and Python demo code

* perf: Custom secret change

* perf: add user filter

* perf: translate

* perf: Add demo code docs

* perf: update some i18n

* perf: update some i18n

* perf: Add Java, Node, Go, and cURL demo code

* perf: Translate

* perf: Change secret translate

* perf: Translate

* perf: update some i18n

* perf: translate

* perf: Ansible playbook

* perf: update some choice

* perf: update some choice

* perf: update account serializer remote unused code

* perf: conflict

* perf: update import

---------

Co-authored-by: ibuler <ibuler@qq.com>
Co-authored-by: feng <1304903146@qq.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: wangruidong <940853815@qq.com>
Co-authored-by: jiangweidong <1053570670@qq.com>
Co-authored-by: feng626 <57284900+feng626@users.noreply.github.com>
Co-authored-by: zhaojisen <1301338853@qq.com>
2025-02-21 16:39:57 +08:00

171 lines
6.7 KiB
Python

from collections import defaultdict
from django.utils import timezone
from accounts.const import AliasAccount
from accounts.models import VirtualAccount
from assets.models import Asset, MyAsset
from common.utils import lazyproperty
from orgs.utils import tmp_to_org, tmp_to_root_org
from perms.const import ActionChoices
from .permission import AssetPermissionUtil
__all__ = ['PermAssetDetailUtil']
class PermAssetDetailUtil:
""" 资产授权账号相关的工具 """
def __init__(self, user, asset_or_id):
self.user = user
if isinstance(asset_or_id, Asset):
self.asset_id = asset_or_id.id
self.asset = asset_or_id
else:
self.asset_id = asset_or_id
@lazyproperty
def asset(self):
if self.user_asset_perms:
asset = self._asset
MyAsset.set_asset_custom_value([asset], self.user)
return asset
raise Asset.DoesNotExist()
@lazyproperty
def _asset(self):
from assets.models import Asset
with tmp_to_root_org():
queryset = Asset.objects.filter(id=self.asset_id)
return queryset.get()
def validate_permission(self, account_name, protocol):
with tmp_to_org(self.asset.org):
if self.user.is_superuser:
account = self.asset.accounts.all().active().get(name=account_name)
account.actions = ActionChoices.all()
account.date_expired = timezone.now() + timezone.timedelta(days=365)
return account
protocols = self.get_permed_protocols_for_user(only_name=True)
if 'all' not in protocols and protocol not in protocols:
return None
permed_accounts = self.get_permed_accounts_for_user()
accounts_mapper = {account.alias: account for account in permed_accounts}
account = accounts_mapper.get(account_name)
return account
@lazyproperty
def user_asset_perms(self):
perm_util = AssetPermissionUtil()
perms = perm_util.get_permissions_for_user_asset(self.user, self.asset_id)
return perms
def get_permed_accounts_for_user(self):
""" 获取授权给用户某个资产的账号 """
perms = self.user_asset_perms
permed_accounts = self.get_permed_accounts_from_perms(perms, self.user, self.asset)
return permed_accounts
def get_permed_protocols_for_user(self, only_name=False):
""" 获取授权给用户某个资产的账号 """
perms = self.user_asset_perms
names = set()
for perm in perms:
names |= set(perm.protocols)
if only_name:
return names
protocols = self.asset.protocols.all()
if 'all' not in names:
protocols = protocols.filter(name__in=names)
return protocols
@staticmethod
def parse_alias_action_date_expire(perms, asset):
alias_action_bit_mapper = defaultdict(int)
alias_date_expired_mapper = defaultdict(list)
for perm in perms:
for alias in perm.accounts:
alias_action_bit_mapper[alias] |= perm.actions
alias_date_expired_mapper[alias].append(perm.date_expired)
# @ALL 账号先处理,后面的每个最多映射一个账号
all_action_bit = alias_action_bit_mapper.pop(AliasAccount.ALL, None)
if not all_action_bit:
return alias_action_bit_mapper, alias_date_expired_mapper
asset_account_usernames = asset.accounts.all().active().values_list('username', flat=True)
for username in asset_account_usernames:
alias_action_bit_mapper[username] |= all_action_bit
alias_date_expired_mapper[username].extend(
alias_date_expired_mapper[AliasAccount.ALL]
)
return alias_action_bit_mapper, alias_date_expired_mapper
@classmethod
def map_alias_to_accounts(cls, alias_action_bit_mapper, alias_date_expired_mapper, asset, user):
username_accounts_mapper = defaultdict(list)
cleaned_accounts_expired = defaultdict(list)
asset_accounts = asset.accounts.all().active()
# 用户名 -> 账号
for account in asset_accounts:
username_accounts_mapper[account.username].append(account)
cleaned_accounts_action_bit = defaultdict(int)
for alias, action_bit in alias_action_bit_mapper.items():
account = None
_accounts = []
if alias == AliasAccount.USER and user.username in username_accounts_mapper:
_accounts = username_accounts_mapper[user.username]
elif alias in username_accounts_mapper:
_accounts = username_accounts_mapper[alias]
elif alias in ['@INPUT', '@ANON', '@USER']:
account = VirtualAccount.get_special_account(alias, user, asset, from_permed=True)
elif alias.startswith('@'):
continue
if account:
_accounts += [account]
for account in _accounts:
cleaned_accounts_action_bit[account] |= action_bit
cleaned_accounts_expired[account].extend(alias_date_expired_mapper[alias])
return cleaned_accounts_action_bit, cleaned_accounts_expired
@classmethod
def get_permed_accounts_from_perms(cls, perms, user, asset):
# alias: is a collection of account usernames and special accounts [@ALL, @INPUT, @USER, @ANON]
alias_action_bit_mapper, alias_date_expired_mapper = cls.parse_alias_action_date_expire(perms, asset)
cleaned_accounts_action_bit, cleaned_accounts_expired = cls.map_alias_to_accounts(
alias_action_bit_mapper, alias_date_expired_mapper, asset, user
)
accounts = []
for account, action_bit in cleaned_accounts_action_bit.items():
account.actions = action_bit
account.date_expired = max(cleaned_accounts_expired[account])
accounts.append(account)
return accounts
def check_perm_protocols(self, protocols):
"""
检查用户是否有某些协议权限
:param protocols: set
"""
perms_protocols = self.get_permed_protocols_for_user(only_name=True)
if "all" in perms_protocols:
return True
return protocols.intersection(perms_protocols)
def check_perm_actions(self, account_name, actions):
"""
检查用户是否有某个账号的某个资产操作权限
:param account_name: str
:param actions: list
"""
perms = self.user_asset_perms
action_bit_mapper, __ = self.parse_alias_action_date_expire(perms, self.asset)
return ActionChoices.contains_all(action_bit_mapper.get(account_name, 0), actions)