mirror of https://github.com/jumpserver/jumpserver
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
190 lines
4.7 KiB
190 lines
4.7 KiB
# -*- coding: utf-8 -*- |
|
# |
|
import uuid |
|
from contextlib import contextmanager |
|
from functools import wraps |
|
from inspect import signature |
|
|
|
from werkzeug.local import LocalProxy |
|
from django.conf import settings |
|
|
|
from common.local import thread_local |
|
from .models import Organization |
|
|
|
|
|
def get_org_from_request(request): |
|
# query中优先级最高 |
|
oid = request.GET.get("oid") |
|
# 其次header |
|
if not oid: |
|
oid = request.META.get("HTTP_X_JMS_ORG") |
|
# 其次cookie |
|
if not oid: |
|
oid = request.COOKIES.get('X-JMS-ORG') |
|
# 其次session |
|
if not oid: |
|
oid = request.session.get("oid") |
|
|
|
if oid and oid.lower() == 'default': |
|
return Organization.default() |
|
|
|
if oid and oid.lower() == 'root': |
|
return Organization.root() |
|
|
|
if oid and oid.lower() == 'system': |
|
return Organization.system() |
|
|
|
org = Organization.get_instance(oid) |
|
|
|
if org and org.internal: |
|
# 内置组织直接返回 |
|
return org |
|
|
|
if not settings.XPACK_ENABLED: |
|
# 社区版用户只能使用默认组织 |
|
return Organization.default() |
|
|
|
if not org and request.user.is_authenticated: |
|
# 企业版用户优先从自己有权限的组织中获取 |
|
org = request.user.orgs.first() |
|
|
|
if not org: |
|
org = Organization.default() |
|
|
|
return org |
|
|
|
|
|
def set_current_org(org): |
|
if isinstance(org, (str, uuid.UUID)): |
|
org = Organization.get_instance(org) |
|
setattr(thread_local, 'current_org_id', org.id) |
|
|
|
|
|
def set_to_default_org(): |
|
set_current_org(Organization.default()) |
|
|
|
|
|
def set_to_root_org(): |
|
set_current_org(Organization.root()) |
|
|
|
|
|
def set_to_system_org(): |
|
set_current_org(Organization.system()) |
|
|
|
|
|
def _find(attr): |
|
return getattr(thread_local, attr, None) |
|
|
|
|
|
def get_current_org(): |
|
org_id = get_current_org_id() |
|
if not org_id or org_id == Organization.ROOT_ID: |
|
return Organization.root() |
|
org = Organization.get_instance(org_id, default=Organization.root()) |
|
return org |
|
|
|
|
|
def get_current_org_id(): |
|
org_id = _find('current_org_id') |
|
return org_id |
|
|
|
|
|
def get_current_org_id_for_serializer(): |
|
org_id = get_current_org_id() |
|
return org_id |
|
|
|
|
|
@contextmanager |
|
def tmp_to_root_org(): |
|
ori_org = get_current_org() |
|
set_to_root_org() |
|
yield |
|
if ori_org is not None: |
|
set_current_org(ori_org) |
|
|
|
|
|
@contextmanager |
|
def tmp_to_org(org): |
|
ori_org = get_current_org() |
|
if org: |
|
set_current_org(org) |
|
yield |
|
if ori_org is not None: |
|
set_current_org(ori_org) |
|
|
|
|
|
@contextmanager |
|
def tmp_to_builtin_org(system=0, default=0): |
|
if system: |
|
org_id = Organization.SYSTEM_ID |
|
elif default: |
|
org_id = Organization.DEFAULT_ID |
|
else: |
|
raise ValueError("Must set system or default") |
|
ori_org = get_current_org() |
|
set_current_org(org_id) |
|
yield |
|
if ori_org is not None: |
|
set_current_org(ori_org) |
|
|
|
|
|
def filter_org_queryset(queryset): |
|
locking_org = getattr(queryset.model, 'LOCKING_ORG', None) |
|
org = get_current_org() |
|
|
|
if locking_org: |
|
kwargs = {'org_id': locking_org} |
|
elif org is None or org.is_root(): |
|
kwargs = {} |
|
else: |
|
kwargs = {'org_id': org.id} |
|
|
|
# import traceback |
|
# lines = traceback.format_stack() |
|
# print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>") |
|
# for line in lines[-10:-1]: |
|
# print(line) |
|
# print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<") |
|
queryset = queryset.filter(**kwargs) |
|
return queryset |
|
|
|
|
|
def org_aware_func(org_arg_name): |
|
""" |
|
:param org_arg_name: 函数中包含org_id的对象是哪个参数 |
|
:return: |
|
""" |
|
|
|
def decorate(func): |
|
@wraps(func) |
|
def wrapper(*args, **kwargs): |
|
sig = signature(func) |
|
values = sig.bind(*args, **kwargs) |
|
org_aware_resource = values.arguments.get(org_arg_name) |
|
if not org_aware_resource: |
|
return func(*args, **kwargs) |
|
if hasattr(org_aware_resource, '__getitem__'): |
|
org_aware_resource = org_aware_resource[0] |
|
if not hasattr(org_aware_resource, "org_id"): |
|
print("Error: {} not has org_id attr".format(org_aware_resource)) |
|
return func(*args, **kwargs) |
|
with tmp_to_org(org_aware_resource.org_id): |
|
# print("Current org id: {}".format(org_aware_resource.org_id)) |
|
return func(*args, **kwargs) |
|
|
|
return wrapper |
|
|
|
return decorate |
|
|
|
|
|
current_org = LocalProxy(get_current_org) |
|
|
|
|
|
def ensure_in_real_or_default_org(func): |
|
@wraps(func) |
|
def wrapper(*args, **kwargs): |
|
if not current_org or current_org.is_root(): |
|
raise ValueError('You must in a real or default org!') |
|
return func(*args, **kwargs) |
|
|
|
return wrapper
|
|
|