jumpserver/apps/assets/backends/db.py

318 lines
11 KiB
Python
Raw Normal View History

[Feature] 添加资产用户管理器 (#2489) * [Feature] 1. 资产用户管理器 * [Feature] 2. 资产用户管理器: 更新AuthBook * [Feature] 3. 资产用户管理器: 添加 AssetUser API * [Feature] 4. AssetUser Model: 添加方法 load_related_asset_auth * [Feature] 5. AdminUser: 更新管理用户获取认证信息时,先加载相关资产的认证 * [Feature] 6. SystemUser: 更新系统用户获取认证信息时,先加载相关资产的认证 * [Feature] 前端页面: 添加资产用户列表页面 * [Feature] 前端页面: 管理用户的资产管理页面添加按钮: 修改资产用户认证信息 * [Feature] 前端页面: 系统用户的资产管理页面添加按钮: 修改资产用户认证信息 * [Feature] 优化: 从管理用户和系统用户的backend中获取相关资产用户的逻辑 * [Update] Fix 1 * [Feature] 优化: SystemUserBackend之filter功能 * [Feature] 优化: AdminUserBackend之filter功能 * [Feature] 优化: AdminUserBackend和SystemUserBackend功能 * [Feature] 更新翻译: 资产用户管理器 * [Update] 更新资产用户列表页名称为: asset_asset_user_list.html * [Bugfix] 修改bug: SystemUserBackend 根据用户名过滤系统用户 * [Feature] 添加: 资产用户列表中可测试资产用户的连接性 * [Update] 修改: AdHoc model的run_as字段从SystemUser外键修改为username字符串 * [Feature] 添加: 获取系统用户认证信息(对应某个资产)API * [Update] 更新: API获取asset user时进行排序 * [Bugfix] 修改: 资产用户可连接性CACHE_KEY * [Update] 更新翻译信息 * [Update] 修改获取资产用户认证信息API的返回响应(200/400) * [Update] 修改BaseUser获取特定资产的方法名 * [Update] 修改logger输出,AuthBook set_version_and_latest * [Update] 修改日志输出添加exc_info参数 * [Update] 移除AuthBook迁移文件0026 * [Bugfix] 修复AdminUserBackend获取instances为空的bug
2019-03-18 02:15:33 +00:00
# -*- coding: utf-8 -*-
#
1.5.7 Merge to dev (#3766) * [Update] 暂存,优化解决不了问题 * [Update] 待续(小白) * [Update] 修改asset user * [Update] 计划再次更改 * [Update] 修改asset user * [Update] 暂存与喜爱 * [Update] Add id in * [Update] 阶段性完成ops task该做 * [Update] 修改asset user api * [Update] 修改asset user 任务,查看认证等 * [Update] 基本完成asset user改造 * [Update] dynamic user only allow 1 * [Update] 修改asset user task * [Update] 修改node admin user task api * [Update] remove file header license * [Update] 添加sftp root * [Update] 暂存 * [Update] 暂存 * [Update] 修改翻译 * [Update] 修改系统用户改为同名后,用户名改为空 * [Update] 基本完成CAS调研 * [Update] 支持cas server * [Update] 支持cas server * [Update] 添加requirements * [Update] 为方便调试添加mysql ipython到包中 * [Update] 添加huaweiyun翻译 * [Update] 增加下载session 录像 * [Update] 只有第一次通知replay离线的使用方法 * [Update] 暂存一下 * [Bugfix] 获取系统用户信息报错 * [Bugfix] 修改system user info * [Update] 改成清理10天git status * [Update] 修改celery日志保留时间 * [Update]修复部分pip包依赖的版本不兼容问题 (#3672) * [Update] 修复用户更新页面会清空用户public_key的问题 * Fix broken dependencies Co-authored-by: BaiJiangJie <32935519+BaiJiangJie@users.noreply.github.com> * [Update] 修改获取系统用户auth info * [Update] Remove log * [Bugfix] 修复sftp home设置的bug * [Update] 授权的系统用户添加sftp root * [Update] 修改系统用户关联的用户 * [Update] 修改placeholder * [Update] 优化获取授权的系统用户 * [Update] 修改tasks * [Update] tree service update * [Update] 暂存 * [Update] 基本完成用户授权树和资产树改造 * [Update] Dashbaord perf * [update] Add huawei cloud sdk requirements * [Updte] 优化dashboard页面 * [Update] system user auth info 添加id * [Update] 修改系统用户serializer * [Update] 优化api * [Update] LDAP Test Util (#3720) * [Update] LDAPTestUtil 1 * [Update] LDAPTestUtil 2 * [Update] LDAPTestUtil 3 * [Update] LDAPTestUtil 4 * [Update] LDAPTestUtil 5 * [Update] LDAPTestUtil 6 * [Update] LDAPTestUtil 7 * [Update] session 已添加is success,并且添加display serializer * [Bugfix] 修复无法删除空节点的bug * [Update] 命令记录分组织显示 * [Update] Session is_success 添加迁移文件 * [Update] 批量命令添加org_id * [Update] 修复一些文案,修改不绑定MFA,不能ssh登录 * [Update] 修改replay api, 返回session信息 * [Update] 解决无效es导致访问命令记录页面失败的问题 * [Update] 拆分profile view * [Update] 修改一个翻译 * [Update] 修改aysnc api框架 * [Update] 命令列表添加risk level * [Update] 完成录像打包下载 * [Update] 更改登陆otp页面 * [Update] 修改command 存储redis_level * [Update] 修改翻译 * [Update] 修改系统用户的用户列表字段 * [Update] 使用新logo和统一Jumpserver为JumpServer * [Update] 优化cloud task * [Update] 统一period task * [Update] 统一period form serializer字段 * [Update] 修改period task * [Update] 修改资产网关信息 * [Update] 用户授权资产树资产信息添加domain * [Update] 修改翻译 * [Update] 测试可连接性 * 1.5.7 bai (#3764) * [Update] 修复index页面Bug;修复测试资产用户可连接性问题; * [Update] 修改测试资产用户可连接 * [Bugfix] 修复backends问题 * [Update] 修改marksafe依赖版本 * [Update] 修改测试资产用户可连接性 * [Update] 修改检测服务器性能时获取percent值 * [Update] 更新依赖boto3=1.12.14 Co-authored-by: Yanzhe Lee <lee.yanzhe@yanzhe.org> Co-authored-by: BaiJiangJie <32935519+BaiJiangJie@users.noreply.github.com> Co-authored-by: Bai <bugatti_it@163.com>
2020-03-12 08:24:38 +00:00
from functools import reduce
from django.db.models import F, CharField, Value, IntegerField, Q, Count
from django.db.models.functions import Concat
[Feature] 添加资产用户管理器 (#2489) * [Feature] 1. 资产用户管理器 * [Feature] 2. 资产用户管理器: 更新AuthBook * [Feature] 3. 资产用户管理器: 添加 AssetUser API * [Feature] 4. AssetUser Model: 添加方法 load_related_asset_auth * [Feature] 5. AdminUser: 更新管理用户获取认证信息时,先加载相关资产的认证 * [Feature] 6. SystemUser: 更新系统用户获取认证信息时,先加载相关资产的认证 * [Feature] 前端页面: 添加资产用户列表页面 * [Feature] 前端页面: 管理用户的资产管理页面添加按钮: 修改资产用户认证信息 * [Feature] 前端页面: 系统用户的资产管理页面添加按钮: 修改资产用户认证信息 * [Feature] 优化: 从管理用户和系统用户的backend中获取相关资产用户的逻辑 * [Update] Fix 1 * [Feature] 优化: SystemUserBackend之filter功能 * [Feature] 优化: AdminUserBackend之filter功能 * [Feature] 优化: AdminUserBackend和SystemUserBackend功能 * [Feature] 更新翻译: 资产用户管理器 * [Update] 更新资产用户列表页名称为: asset_asset_user_list.html * [Bugfix] 修改bug: SystemUserBackend 根据用户名过滤系统用户 * [Feature] 添加: 资产用户列表中可测试资产用户的连接性 * [Update] 修改: AdHoc model的run_as字段从SystemUser外键修改为username字符串 * [Feature] 添加: 获取系统用户认证信息(对应某个资产)API * [Update] 更新: API获取asset user时进行排序 * [Bugfix] 修改: 资产用户可连接性CACHE_KEY * [Update] 更新翻译信息 * [Update] 修改获取资产用户认证信息API的返回响应(200/400) * [Update] 修改BaseUser获取特定资产的方法名 * [Update] 修改logger输出,AuthBook set_version_and_latest * [Update] 修改日志输出添加exc_info参数 * [Update] 移除AuthBook迁移文件0026 * [Bugfix] 修复AdminUserBackend获取instances为空的bug
2019-03-18 02:15:33 +00:00
1.5.7 Merge to dev (#3766) * [Update] 暂存,优化解决不了问题 * [Update] 待续(小白) * [Update] 修改asset user * [Update] 计划再次更改 * [Update] 修改asset user * [Update] 暂存与喜爱 * [Update] Add id in * [Update] 阶段性完成ops task该做 * [Update] 修改asset user api * [Update] 修改asset user 任务,查看认证等 * [Update] 基本完成asset user改造 * [Update] dynamic user only allow 1 * [Update] 修改asset user task * [Update] 修改node admin user task api * [Update] remove file header license * [Update] 添加sftp root * [Update] 暂存 * [Update] 暂存 * [Update] 修改翻译 * [Update] 修改系统用户改为同名后,用户名改为空 * [Update] 基本完成CAS调研 * [Update] 支持cas server * [Update] 支持cas server * [Update] 添加requirements * [Update] 为方便调试添加mysql ipython到包中 * [Update] 添加huaweiyun翻译 * [Update] 增加下载session 录像 * [Update] 只有第一次通知replay离线的使用方法 * [Update] 暂存一下 * [Bugfix] 获取系统用户信息报错 * [Bugfix] 修改system user info * [Update] 改成清理10天git status * [Update] 修改celery日志保留时间 * [Update]修复部分pip包依赖的版本不兼容问题 (#3672) * [Update] 修复用户更新页面会清空用户public_key的问题 * Fix broken dependencies Co-authored-by: BaiJiangJie <32935519+BaiJiangJie@users.noreply.github.com> * [Update] 修改获取系统用户auth info * [Update] Remove log * [Bugfix] 修复sftp home设置的bug * [Update] 授权的系统用户添加sftp root * [Update] 修改系统用户关联的用户 * [Update] 修改placeholder * [Update] 优化获取授权的系统用户 * [Update] 修改tasks * [Update] tree service update * [Update] 暂存 * [Update] 基本完成用户授权树和资产树改造 * [Update] Dashbaord perf * [update] Add huawei cloud sdk requirements * [Updte] 优化dashboard页面 * [Update] system user auth info 添加id * [Update] 修改系统用户serializer * [Update] 优化api * [Update] LDAP Test Util (#3720) * [Update] LDAPTestUtil 1 * [Update] LDAPTestUtil 2 * [Update] LDAPTestUtil 3 * [Update] LDAPTestUtil 4 * [Update] LDAPTestUtil 5 * [Update] LDAPTestUtil 6 * [Update] LDAPTestUtil 7 * [Update] session 已添加is success,并且添加display serializer * [Bugfix] 修复无法删除空节点的bug * [Update] 命令记录分组织显示 * [Update] Session is_success 添加迁移文件 * [Update] 批量命令添加org_id * [Update] 修复一些文案,修改不绑定MFA,不能ssh登录 * [Update] 修改replay api, 返回session信息 * [Update] 解决无效es导致访问命令记录页面失败的问题 * [Update] 拆分profile view * [Update] 修改一个翻译 * [Update] 修改aysnc api框架 * [Update] 命令列表添加risk level * [Update] 完成录像打包下载 * [Update] 更改登陆otp页面 * [Update] 修改command 存储redis_level * [Update] 修改翻译 * [Update] 修改系统用户的用户列表字段 * [Update] 使用新logo和统一Jumpserver为JumpServer * [Update] 优化cloud task * [Update] 统一period task * [Update] 统一period form serializer字段 * [Update] 修改period task * [Update] 修改资产网关信息 * [Update] 用户授权资产树资产信息添加domain * [Update] 修改翻译 * [Update] 测试可连接性 * 1.5.7 bai (#3764) * [Update] 修复index页面Bug;修复测试资产用户可连接性问题; * [Update] 修改测试资产用户可连接 * [Bugfix] 修复backends问题 * [Update] 修改marksafe依赖版本 * [Update] 修改测试资产用户可连接性 * [Update] 修改检测服务器性能时获取percent值 * [Update] 更新依赖boto3=1.12.14 Co-authored-by: Yanzhe Lee <lee.yanzhe@yanzhe.org> Co-authored-by: BaiJiangJie <32935519+BaiJiangJie@users.noreply.github.com> Co-authored-by: Bai <bugatti_it@163.com>
2020-03-12 08:24:38 +00:00
from common.utils import get_object_or_none
from orgs.utils import current_org
from ..models import AuthBook, SystemUser, Asset, AdminUser
from .base import BaseBackend
[Feature] 添加资产用户管理器 (#2489) * [Feature] 1. 资产用户管理器 * [Feature] 2. 资产用户管理器: 更新AuthBook * [Feature] 3. 资产用户管理器: 添加 AssetUser API * [Feature] 4. AssetUser Model: 添加方法 load_related_asset_auth * [Feature] 5. AdminUser: 更新管理用户获取认证信息时,先加载相关资产的认证 * [Feature] 6. SystemUser: 更新系统用户获取认证信息时,先加载相关资产的认证 * [Feature] 前端页面: 添加资产用户列表页面 * [Feature] 前端页面: 管理用户的资产管理页面添加按钮: 修改资产用户认证信息 * [Feature] 前端页面: 系统用户的资产管理页面添加按钮: 修改资产用户认证信息 * [Feature] 优化: 从管理用户和系统用户的backend中获取相关资产用户的逻辑 * [Update] Fix 1 * [Feature] 优化: SystemUserBackend之filter功能 * [Feature] 优化: AdminUserBackend之filter功能 * [Feature] 优化: AdminUserBackend和SystemUserBackend功能 * [Feature] 更新翻译: 资产用户管理器 * [Update] 更新资产用户列表页名称为: asset_asset_user_list.html * [Bugfix] 修改bug: SystemUserBackend 根据用户名过滤系统用户 * [Feature] 添加: 资产用户列表中可测试资产用户的连接性 * [Update] 修改: AdHoc model的run_as字段从SystemUser外键修改为username字符串 * [Feature] 添加: 获取系统用户认证信息(对应某个资产)API * [Update] 更新: API获取asset user时进行排序 * [Bugfix] 修改: 资产用户可连接性CACHE_KEY * [Update] 更新翻译信息 * [Update] 修改获取资产用户认证信息API的返回响应(200/400) * [Update] 修改BaseUser获取特定资产的方法名 * [Update] 修改logger输出,AuthBook set_version_and_latest * [Update] 修改日志输出添加exc_info参数 * [Update] 移除AuthBook迁移文件0026 * [Bugfix] 修复AdminUserBackend获取instances为空的bug
2019-03-18 02:15:33 +00:00
1.5.7 Merge to dev (#3766) * [Update] 暂存,优化解决不了问题 * [Update] 待续(小白) * [Update] 修改asset user * [Update] 计划再次更改 * [Update] 修改asset user * [Update] 暂存与喜爱 * [Update] Add id in * [Update] 阶段性完成ops task该做 * [Update] 修改asset user api * [Update] 修改asset user 任务,查看认证等 * [Update] 基本完成asset user改造 * [Update] dynamic user only allow 1 * [Update] 修改asset user task * [Update] 修改node admin user task api * [Update] remove file header license * [Update] 添加sftp root * [Update] 暂存 * [Update] 暂存 * [Update] 修改翻译 * [Update] 修改系统用户改为同名后,用户名改为空 * [Update] 基本完成CAS调研 * [Update] 支持cas server * [Update] 支持cas server * [Update] 添加requirements * [Update] 为方便调试添加mysql ipython到包中 * [Update] 添加huaweiyun翻译 * [Update] 增加下载session 录像 * [Update] 只有第一次通知replay离线的使用方法 * [Update] 暂存一下 * [Bugfix] 获取系统用户信息报错 * [Bugfix] 修改system user info * [Update] 改成清理10天git status * [Update] 修改celery日志保留时间 * [Update]修复部分pip包依赖的版本不兼容问题 (#3672) * [Update] 修复用户更新页面会清空用户public_key的问题 * Fix broken dependencies Co-authored-by: BaiJiangJie <32935519+BaiJiangJie@users.noreply.github.com> * [Update] 修改获取系统用户auth info * [Update] Remove log * [Bugfix] 修复sftp home设置的bug * [Update] 授权的系统用户添加sftp root * [Update] 修改系统用户关联的用户 * [Update] 修改placeholder * [Update] 优化获取授权的系统用户 * [Update] 修改tasks * [Update] tree service update * [Update] 暂存 * [Update] 基本完成用户授权树和资产树改造 * [Update] Dashbaord perf * [update] Add huawei cloud sdk requirements * [Updte] 优化dashboard页面 * [Update] system user auth info 添加id * [Update] 修改系统用户serializer * [Update] 优化api * [Update] LDAP Test Util (#3720) * [Update] LDAPTestUtil 1 * [Update] LDAPTestUtil 2 * [Update] LDAPTestUtil 3 * [Update] LDAPTestUtil 4 * [Update] LDAPTestUtil 5 * [Update] LDAPTestUtil 6 * [Update] LDAPTestUtil 7 * [Update] session 已添加is success,并且添加display serializer * [Bugfix] 修复无法删除空节点的bug * [Update] 命令记录分组织显示 * [Update] Session is_success 添加迁移文件 * [Update] 批量命令添加org_id * [Update] 修复一些文案,修改不绑定MFA,不能ssh登录 * [Update] 修改replay api, 返回session信息 * [Update] 解决无效es导致访问命令记录页面失败的问题 * [Update] 拆分profile view * [Update] 修改一个翻译 * [Update] 修改aysnc api框架 * [Update] 命令列表添加risk level * [Update] 完成录像打包下载 * [Update] 更改登陆otp页面 * [Update] 修改command 存储redis_level * [Update] 修改翻译 * [Update] 修改系统用户的用户列表字段 * [Update] 使用新logo和统一Jumpserver为JumpServer * [Update] 优化cloud task * [Update] 统一period task * [Update] 统一period form serializer字段 * [Update] 修改period task * [Update] 修改资产网关信息 * [Update] 用户授权资产树资产信息添加domain * [Update] 修改翻译 * [Update] 测试可连接性 * 1.5.7 bai (#3764) * [Update] 修复index页面Bug;修复测试资产用户可连接性问题; * [Update] 修改测试资产用户可连接 * [Bugfix] 修复backends问题 * [Update] 修改marksafe依赖版本 * [Update] 修改测试资产用户可连接性 * [Update] 修改检测服务器性能时获取percent值 * [Update] 更新依赖boto3=1.12.14 Co-authored-by: Yanzhe Lee <lee.yanzhe@yanzhe.org> Co-authored-by: BaiJiangJie <32935519+BaiJiangJie@users.noreply.github.com> Co-authored-by: Bai <bugatti_it@163.com>
2020-03-12 08:24:38 +00:00
class DBBackend(BaseBackend):
union_id_length = 2
def __init__(self, queryset=None):
if queryset is None:
queryset = self.all()
self.queryset = queryset
def _clone(self):
return self.__class__(self.queryset)
def all(self):
return AuthBook.objects.none()
def count(self):
return self.queryset.count()
def get_queryset(self):
return self.queryset
def delete(self, union_id):
cleaned_union_id = union_id.split('_')
# 如果union_id通不过本检查代表可能不是本backend, 应该返回空
if not self._check_union_id(union_id, cleaned_union_id):
return
return self._perform_delete_by_union_id(cleaned_union_id)
def _perform_delete_by_union_id(self, union_id_cleaned):
pass
def filter(self, assets=None, node=None, prefer=None, prefer_id=None,
union_id=None, id__in=None, **kwargs):
clone = self._clone()
clone._filter_union_id(union_id)
clone._filter_prefer(prefer, prefer_id)
clone._filter_node(node)
clone._filter_assets(assets)
clone._filter_other(kwargs)
clone._filter_id_in(id__in)
return clone
def _filter_union_id(self, union_id):
if not union_id:
return
cleaned_union_id = union_id.split('_')
# 如果union_id通不过本检查代表可能不是本backend, 应该返回空
if not self._check_union_id(union_id, cleaned_union_id):
self.queryset = self.queryset.none()
return
return self._perform_filter_union_id(union_id, cleaned_union_id)
def _check_union_id(self, union_id, cleaned_union_id):
return union_id and len(cleaned_union_id) == self.union_id_length
def _perform_filter_union_id(self, union_id, union_id_cleaned):
self.queryset = self.queryset.filter(union_id=union_id)
def _filter_assets(self, assets):
assets_id = self.make_assets_as_id(assets)
if assets_id:
self.queryset = self.queryset.filter(asset_id__in=assets_id)
def _filter_node(self, node):
pass
def _filter_id_in(self, ids):
if ids and isinstance(ids, list):
self.queryset = self.queryset.filter(union_id__in=ids)
@staticmethod
def clean_kwargs(kwargs):
return {k: v for k, v in kwargs.items() if v}
def _filter_other(self, kwargs):
kwargs = self.clean_kwargs(kwargs)
if kwargs:
self.queryset = self.queryset.filter(**kwargs)
def _filter_prefer(self, prefer, prefer_id):
pass
def search(self, item):
qs = []
for i in ['hostname', 'ip', 'username']:
kwargs = {i + '__startswith': item}
qs.append(Q(**kwargs))
q = reduce(lambda x, y: x | y, qs)
clone = self._clone()
clone.queryset = clone.queryset.filter(q).distinct()
return clone
class SystemUserBackend(DBBackend):
model = SystemUser.assets.through
backend = 'system_user'
prefer = backend
base_score = 0
union_id_length = 2
def _filter_prefer(self, prefer, prefer_id):
if prefer and prefer != self.prefer:
self.queryset = self.queryset.none()
if prefer_id:
self.queryset = self.queryset.filter(systemuser__id=prefer_id)
def _perform_filter_union_id(self, union_id, union_id_cleaned):
system_user_id, asset_id = union_id_cleaned
self.queryset = self.queryset.filter(
asset_id=asset_id, systemuser__id=system_user_id,
)
def _perform_delete_by_union_id(self, union_id_cleaned):
system_user_id, asset_id = union_id_cleaned
system_user = get_object_or_none(SystemUser, pk=system_user_id)
asset = get_object_or_none(Asset, pk=asset_id)
if all((system_user, asset)):
system_user.assets.remove(asset)
def _filter_node(self, node):
if node:
self.queryset = self.queryset.filter(asset__nodes__id=node.id)
def get_annotate(self):
kwargs = dict(
hostname=F("asset__hostname"),
ip=F("asset__ip"),
username=F("systemuser__username"),
password=F("systemuser__password"),
private_key=F("systemuser__private_key"),
public_key=F("systemuser__public_key"),
score=F("systemuser__priority") + self.base_score,
version=Value(0, IntegerField()),
date_created=F("systemuser__date_created"),
date_updated=F("systemuser__date_updated"),
asset_username=Concat(F("asset__id"), Value("_"),
F("systemuser__username"),
output_field=CharField()),
union_id=Concat(F("systemuser_id"), Value("_"), F("asset_id"),
output_field=CharField()),
org_id=F("asset__org_id"),
backend=Value(self.backend, CharField())
)
return kwargs
def get_filter(self):
return dict(
systemuser__username_same_with_user=False,
)
def all(self):
kwargs = self.get_annotate()
filters = self.get_filter()
qs = self.model.objects.all().annotate(**kwargs)
if current_org.org_id() is not None:
filters['org_id'] = current_org.org_id()
qs = qs.filter(**filters)
qs = self.qs_to_values(qs)
return qs
class DynamicSystemUserBackend(SystemUserBackend):
backend = 'system_user_dynamic'
prefer = 'system_user'
union_id_length = 3
def get_annotate(self):
kwargs = super().get_annotate()
kwargs.update(dict(
username=F("systemuser__users__username"),
asset_username=Concat(
F("asset__id"), Value("_"),
F("systemuser__users__username"),
output_field=CharField()
),
union_id=Concat(
F("systemuser_id"), Value("_"), F("asset_id"),
Value("_"), F("systemuser__users__id"),
output_field=CharField()
),
users_count=Count('systemuser__users'),
))
return kwargs
def _perform_filter_union_id(self, union_id, union_id_cleaned):
system_user_id, asset_id, user_id = union_id_cleaned
self.queryset = self.queryset.filter(
asset_id=asset_id, systemuser_id=system_user_id,
union_id=union_id,
)
def _perform_delete_by_union_id(self, union_id_cleaned):
system_user_id, asset_id, user_id = union_id_cleaned
system_user = get_object_or_none(SystemUser, pk=system_user_id)
if not system_user:
return
system_user.users.remove(user_id)
if system_user.users.count() == 0:
system_user.assets.remove(asset_id)
def get_filter(self):
return dict(
users_count__gt=0,
systemuser__username_same_with_user=True
)
class AdminUserBackend(DBBackend):
model = Asset
backend = 'admin_user'
prefer = backend
base_score = 200
def _filter_prefer(self, prefer, prefer_id):
if prefer and prefer != self.backend:
self.queryset = self.queryset.none()
if prefer_id:
self.queryset = self.queryset.filter(admin_user__id=prefer_id)
def _filter_node(self, node):
if node:
self.queryset = self.queryset.filter(nodes__id=node.id)
def _perform_filter_union_id(self, union_id, union_id_cleaned):
admin_user_id, asset_id = union_id_cleaned
self.queryset = self.queryset.filter(
id=asset_id, admin_user_id=admin_user_id,
)
def _perform_delete_by_union_id(self, union_id_cleaned):
raise PermissionError("Could remove asset admin user")
def all(self):
qs = self.model.objects.all().annotate(
asset_id=F("id"),
username=F("admin_user__username"),
password=F("admin_user__password"),
private_key=F("admin_user__private_key"),
public_key=F("admin_user__public_key"),
score=Value(self.base_score, IntegerField()),
version=Value(0, IntegerField()),
date_updated=F("admin_user__date_updated"),
asset_username=Concat(F("id"), Value("_"), F("admin_user__username"), output_field=CharField()),
union_id=Concat(F("admin_user_id"), Value("_"), F("id"), output_field=CharField()),
backend=Value(self.backend, CharField()),
)
qs = self.qs_to_values(qs)
return qs
class AuthbookBackend(DBBackend):
model = AuthBook
backend = 'db'
prefer = backend
base_score = 400
def _filter_node(self, node):
if node:
self.queryset = self.queryset.filter(asset__nodes__id=node.id)
def _filter_prefer(self, prefer, prefer_id):
if not prefer or not prefer_id:
return
if prefer.lower() == "admin_user":
model = AdminUser
elif prefer.lower() == "system_user":
model = SystemUser
else:
self.queryset = self.queryset.none()
return
obj = get_object_or_none(model, pk=prefer_id)
if obj is None:
self.queryset = self.queryset.none()
return
username = obj.get_username()
if isinstance(username, str):
self.queryset = self.queryset.filter(username=username)
# dynamic system user return more username
else:
self.queryset = self.queryset.filter(username__in=username)
def _perform_filter_union_id(self, union_id, union_id_cleaned):
authbook_id, asset_id = union_id_cleaned
self.queryset = self.queryset.filter(
id=authbook_id, asset_id=asset_id,
)
def _perform_delete_by_union_id(self, union_id_cleaned):
authbook_id, asset_id = union_id_cleaned
authbook = get_object_or_none(AuthBook, pk=authbook_id)
if authbook.is_latest:
raise PermissionError("Latest version could be delete")
AuthBook.objects.filter(id=authbook_id).delete()
def all(self):
qs = self.model.objects.all().annotate(
hostname=F("asset__hostname"),
ip=F("asset__ip"),
score=F('version') + self.base_score,
asset_username=Concat(F("asset__id"), Value("_"), F("username"), output_field=CharField()),
union_id=Concat(F("id"), Value("_"), F("asset_id"), output_field=CharField()),
backend=Value(self.backend, CharField()),
)
qs = self.qs_to_values(qs)
return qs