mirror of https://github.com/jumpserver/jumpserver
fix: Authbook 取认证信息bug
parent
67a49dc5e9
commit
333bb64b8b
|
@ -150,17 +150,37 @@ class AuthMixin:
|
|||
|
||||
def load_asset_special_auth(self, asset, username=''):
|
||||
"""
|
||||
AuthBook 的数据状态
|
||||
| asset | systemuser | username |
|
||||
1 | * | * | x |
|
||||
2 | * | x | * |
|
||||
|
||||
当前 AuthBook 只有以上两种状态,systemuser 与 username 不会并存。
|
||||
正常的资产与系统用户关联产生的是第1种状态,改密则产生第2种状态。改密之后
|
||||
只有 username 而没有 systemuser 。
|
||||
|
||||
Freq: 关联同一资产的多个系统用户指定同一用户名时,修改用户密码会影响所有系统用户
|
||||
|
||||
这里有一个不对称的行为,同名系统用户密码覆盖
|
||||
当有相同 username 的多个系统用户时,有改密动作之后,所有的同名系统用户都使用最后
|
||||
一次改动,但如果没有发生过改密,同名系统用户使用的密码还是各自的。
|
||||
|
||||
"""
|
||||
authbooks = list(AuthBook.objects.filter(asset=asset).filter(
|
||||
Q(username=username) | Q(systemuser=self)
|
||||
))
|
||||
if len(authbooks) == 0:
|
||||
if username == '':
|
||||
username = self.username
|
||||
|
||||
authbook = AuthBook.objects.filter(
|
||||
asset=asset, username=username, systemuser__isnull=True
|
||||
).order_by('-date_created').first()
|
||||
|
||||
if not authbook:
|
||||
authbook = AuthBook.objects.filter(
|
||||
asset=asset, systemuser=self
|
||||
).order_by('-date_created').first()
|
||||
|
||||
if not authbook:
|
||||
return None
|
||||
elif len(authbooks) == 1:
|
||||
authbook = authbooks[0]
|
||||
else:
|
||||
authbooks.sort(key=lambda x: 1 if x.username == username else 0, reverse=True)
|
||||
authbook = authbooks[0]
|
||||
|
||||
authbook.load_auth()
|
||||
self.password = authbook.password
|
||||
self.private_key = authbook.private_key
|
||||
|
|
|
@ -4,10 +4,10 @@ from itertools import groupby
|
|||
from celery import shared_task
|
||||
from common.db.utils import get_object_if_need, get_objects
|
||||
from django.utils.translation import ugettext as _, gettext_noop
|
||||
from django.db.models import Empty, Q
|
||||
from django.db.models import Empty
|
||||
|
||||
from common.utils import encrypt_password, get_logger
|
||||
from assets.models import SystemUser, Asset, AuthBook
|
||||
from assets.models import SystemUser, Asset
|
||||
from orgs.utils import org_aware_func, tmp_to_root_org
|
||||
from . import const
|
||||
from .utils import clean_ansible_task_hosts, group_asset_by_platform
|
||||
|
@ -178,6 +178,7 @@ def get_push_windows_system_user_tasks(system_user: SystemUser, username=None):
|
|||
|
||||
def get_push_system_user_tasks(system_user, platform="unixlike", username=None):
|
||||
"""
|
||||
获取推送系统用户的 ansible 命令,跟资产无关
|
||||
:param system_user:
|
||||
:param platform:
|
||||
:param username: 当动态时,近推送某个
|
||||
|
@ -209,18 +210,10 @@ def push_system_user_util(system_user, assets, task_name, username=None):
|
|||
if not assets:
|
||||
return {}
|
||||
|
||||
# 资产按平台分类
|
||||
assets_sorted = sorted(assets, key=group_asset_by_platform)
|
||||
platform_hosts = groupby(assets_sorted, key=group_asset_by_platform)
|
||||
|
||||
def run_task(_tasks, _hosts):
|
||||
if not _tasks:
|
||||
return
|
||||
task, created = update_or_create_ansible_task(
|
||||
task_name=task_name, hosts=_hosts, tasks=_tasks, pattern='all',
|
||||
options=const.TASK_OPTIONS, run_as_admin=True,
|
||||
)
|
||||
task.run()
|
||||
|
||||
if system_user.username_same_with_user:
|
||||
if username is None:
|
||||
# 动态系统用户,但是没有指定 username
|
||||
|
@ -232,6 +225,15 @@ def push_system_user_util(system_user, assets, task_name, username=None):
|
|||
assert username is None, 'Only Dynamic user can assign `username`'
|
||||
usernames = [system_user.username]
|
||||
|
||||
def run_task(_tasks, _hosts):
|
||||
if not _tasks:
|
||||
return
|
||||
task, created = update_or_create_ansible_task(
|
||||
task_name=task_name, hosts=_hosts, tasks=_tasks, pattern='all',
|
||||
options=const.TASK_OPTIONS, run_as_admin=True,
|
||||
)
|
||||
task.run()
|
||||
|
||||
for platform, _assets in platform_hosts:
|
||||
_assets = list(_assets)
|
||||
if not _assets:
|
||||
|
@ -239,36 +241,11 @@ def push_system_user_util(system_user, assets, task_name, username=None):
|
|||
print(_("Start push system user for platform: [{}]").format(platform))
|
||||
print(_("Hosts count: {}").format(len(_assets)))
|
||||
|
||||
id_asset_map = {_asset.id: _asset for _asset in _assets}
|
||||
asset_ids = id_asset_map.keys()
|
||||
no_special_auth = []
|
||||
special_auth_set = set()
|
||||
|
||||
auth_books = AuthBook.objects.filter(asset_id__in=asset_ids).filter(
|
||||
Q(username__in=usernames) | Q(systemuser=system_user)
|
||||
).prefetch_related('systemuser')
|
||||
|
||||
for auth_book in auth_books:
|
||||
auth_book.load_auth()
|
||||
special_auth_set.add((auth_book.username, auth_book.asset_id))
|
||||
|
||||
for _username in usernames:
|
||||
no_special_assets = []
|
||||
for asset_id in asset_ids:
|
||||
if (_username, asset_id) not in special_auth_set:
|
||||
no_special_assets.append(id_asset_map[asset_id])
|
||||
if no_special_assets:
|
||||
no_special_auth.append((_username, no_special_assets))
|
||||
|
||||
for _username, no_special_assets in no_special_auth:
|
||||
tasks = get_push_system_user_tasks(system_user, platform, username=_username)
|
||||
run_task(tasks, no_special_assets)
|
||||
|
||||
for auth_book in auth_books:
|
||||
system_user._merge_auth(auth_book)
|
||||
tasks = get_push_system_user_tasks(system_user, platform, username=auth_book.username)
|
||||
asset = id_asset_map[auth_book.asset_id]
|
||||
run_task(tasks, [asset])
|
||||
for u in usernames:
|
||||
for a in _assets:
|
||||
system_user.load_asset_special_auth(a, u)
|
||||
tasks = get_push_system_user_tasks(system_user, platform, username=u)
|
||||
run_task(tasks, [a])
|
||||
|
||||
|
||||
@shared_task(queue="ansible")
|
||||
|
|
Loading…
Reference in New Issue