diff --git a/apps/assets/models/node.py b/apps/assets/models/node.py index 7f7487f06..082273165 100644 --- a/apps/assets/models/node.py +++ b/apps/assets/models/node.py @@ -206,7 +206,7 @@ class Node(OrgModelMixin): return self.get_all_assets().valid() def is_default_node(self): - return self.is_root() and self.key == '0' + return self.is_root() and self.key == '1' def is_root(self): if self.key.isdigit(): diff --git a/apps/assets/serializers/admin_user.py b/apps/assets/serializers/admin_user.py index dbbb16406..d62314858 100644 --- a/apps/assets/serializers/admin_user.py +++ b/apps/assets/serializers/admin_user.py @@ -17,7 +17,7 @@ class AdminUserSerializer(BulkOrgResourceModelSerializer): """ class Meta: - list_serializer_class = AdaptedBulkListSerializer + # list_serializer_class = AdaptedBulkListSerializer model = AdminUser fields = [ 'id', 'name', 'username', 'password', 'private_key', 'public_key', diff --git a/apps/common/templatetags/common_tags.py b/apps/common/templatetags/common_tags.py index 790759f0a..ede2ab9e0 100644 --- a/apps/common/templatetags/common_tags.py +++ b/apps/common/templatetags/common_tags.py @@ -112,7 +112,6 @@ def to_dict(data): @register.filter def sort(data): - print(data) return sorted(data) diff --git a/apps/orgs/mixins.py b/apps/orgs/mixins.py index c6bf4e9a2..ad15977a1 100644 --- a/apps/orgs/mixins.py +++ b/apps/orgs/mixins.py @@ -1,14 +1,11 @@ # -*- coding: utf-8 -*- # -from werkzeug.local import Local from django.db import models -from django.conf import settings from django.utils.translation import ugettext_lazy as _ from django.shortcuts import redirect, get_object_or_404 from django.forms import ModelForm from django.http.response import HttpResponseForbidden -from django.core.exceptions import ValidationError from rest_framework import serializers from rest_framework.validators import UniqueTogetherValidator @@ -16,12 +13,12 @@ from common.utils import get_logger from common.validators import ProjectUniqueValidator from common.mixins import BulkSerializerMixin from .utils import ( - current_org, set_current_org, set_to_root_org, get_current_org_id + set_current_org, set_to_root_org, get_current_org, current_org, + get_current_org_id_for_serializer, ) from .models import Organization logger = get_logger(__file__) -local = Local() __all__ = [ 'OrgManager', 'OrgViewGenericMixin', 'OrgModelMixin', 'OrgModelForm', @@ -29,43 +26,28 @@ __all__ = [ 'OrgMembershipModelViewSetMixin', 'OrgResourceSerializerMixin', 'BulkOrgResourceSerializerMixin', 'BulkOrgResourceModelSerializer', ] -debug = settings.DEBUG class OrgManager(models.Manager): + def get_queryset(self): queryset = super(OrgManager, self).get_queryset() kwargs = {} - if not current_org: + _current_org = get_current_org() + + if _current_org is None: kwargs['id'] = None - elif current_org.is_real(): - kwargs['org_id'] = current_org.id - elif current_org.is_default(): + elif _current_org.is_real(): + kwargs['org_id'] = _current_org.id + elif _current_org.is_default(): queryset = queryset.filter(org_id="") + queryset = queryset.filter(**kwargs) return queryset - def filter_by_fullname(self, fullname, field=None): - ori_org = current_org - value, org = self.model.split_fullname(fullname) - set_current_org(org) - if not field: - if hasattr(self.model, 'name'): - field = 'name' - elif hasattr(self.model, 'hostname'): - field = 'hostname' - queryset = self.get_queryset().filter(**{field: value}) - set_current_org(ori_org) - return queryset - - def get_object_by_fullname(self, fullname, field=None): - queryset = self.filter_by_fullname(fullname, field=field) - if len(queryset) == 1: - return queryset[0] - return None - def all(self): - if not current_org: + _current_org = get_current_org() + if _current_org is None: msg = 'You can `objects.set_current_org(org).all()` then run it' return self else: @@ -73,35 +55,23 @@ class OrgManager(models.Manager): def set_current_org(self, org): if isinstance(org, str): - org = Organization.objects.get(name=org) + org = Organization.get_instance(org) set_current_org(org) return self class OrgModelMixin(models.Model): - org_id = models.CharField(max_length=36, blank=True, default='', verbose_name=_("Organization"), db_index=True) + org_id = models.CharField(max_length=36, blank=True, default='', + verbose_name=_("Organization"), db_index=True) objects = OrgManager() sep = '@' def save(self, *args, **kwargs): - if current_org and current_org.is_real(): + if current_org is not None and current_org.is_real(): self.org_id = current_org.id return super().save(*args, **kwargs) - @classmethod - def split_fullname(cls, fullname, sep=None): - if not sep: - sep = cls.sep - index = fullname.rfind(sep) - if index == -1: - value = fullname - org = Organization.default() - else: - value = fullname[:index] - org = Organization.get_instance(fullname[index + 1:]) - return value, org - @property def org(self): from orgs.models import Organization @@ -126,41 +96,19 @@ class OrgModelMixin(models.Model): else: return name - def validate_unique(self, exclude=None): - """ - Check unique constraints on the model and raise ValidationError if any - failed. - """ - self.org_id = current_org.id if current_org.is_real() else '' - if exclude and 'org_id' in exclude: - exclude.remove('org_id') - unique_checks, date_checks = self._get_unique_checks(exclude=exclude) - - errors = self._perform_unique_checks(unique_checks) - date_errors = self._perform_date_checks(date_checks) - - for k, v in date_errors.items(): - errors.setdefault(k, []).extend(v) - - if errors: - raise ValidationError(errors) - class Meta: abstract = True class OrgViewGenericMixin: def dispatch(self, request, *args, **kwargs): - if not current_org: + if current_org is None: return redirect('orgs:switch-a-org') if not current_org.can_admin_by(request.user): - print("{} cannot admin {}".format(request.user, current_org)) if request.user.is_org_admin: return redirect('orgs:switch-a-org') return HttpResponseForbidden() - else: - print(current_org.can_admin_by(request.user)) return super().dispatch(request, *args, **kwargs) @@ -216,7 +164,7 @@ class OrgResourceSerializerMixin(serializers.Serializer): 由于HiddenField字段不可读,API获取资产信息时获取不到org_id, 但是coco需要资产的org_id字段,所以修改为CharField类型 """ - org_id = serializers.ReadOnlyField(default=get_current_org_id, label=_("Organization")) + org_id = serializers.ReadOnlyField(default=get_current_org_id_for_serializer, label=_("Organization")) org_name = serializers.ReadOnlyField(label=_("Org name")) def get_validators(self): @@ -236,7 +184,7 @@ class OrgResourceSerializerMixin(serializers.Serializer): return fields -class BulkOrgResourceSerializerMixin(BulkSerializerMixin, OrgResourceSerializerMixin): +class BulkOrgResourceSerializerMixin(OrgResourceSerializerMixin, BulkSerializerMixin): pass diff --git a/apps/orgs/models.py b/apps/orgs/models.py index e00270f72..2547e373c 100644 --- a/apps/orgs/models.py +++ b/apps/orgs/models.py @@ -1,7 +1,6 @@ import uuid from django.db import models -from django.core.cache import cache from django.utils.translation import ugettext_lazy as _ from common.utils import is_uuid @@ -16,9 +15,12 @@ class Organization(models.Model): date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name=_('Date created')) comment = models.TextField(max_length=128, default='', blank=True, verbose_name=_('Comment')) + orgs = None CACHE_PREFIX = 'JMS_ORG_{}' - ROOT_ID_NAME = 'ROOT' - DEFAULT_ID_NAME = 'DEFAULT' + ROOT_ID = '00000000-0000-0000-0000-000000000000' + ROOT_NAME = 'ROOT' + DEFAULT_ID = 'DEFAULT' + DEFAULT_NAME = 'DEFAULT' class Meta: verbose_name = _("Organization") @@ -27,33 +29,30 @@ class Organization(models.Model): return self.name def set_to_cache(self): - key_id = self.CACHE_PREFIX.format(self.id) - key_name = self.CACHE_PREFIX.format(self.name) - cache.set(key_id, self, 3600) - cache.set(key_name, self, 3600) + if self.__class__.orgs is None: + self.__class__.orgs = {} + self.__class__.orgs[str(self.id)] = self def expire_cache(self): - key_id = self.CACHE_PREFIX.format(self.id) - key_name = self.CACHE_PREFIX.format(self.name) - cache.delete(key_id) - cache.delete(key_name) + self.__class__.orgs.pop(str(self.id), None) @classmethod def get_instance_from_cache(cls, oid): - key = cls.CACHE_PREFIX.format(oid) - return cache.get(key, None) + if not cls.orgs or not isinstance(cls.orgs, dict): + return None + return cls.orgs.get(str(oid)) @classmethod - def get_instance(cls, id_or_name, default=True): + def get_instance(cls, id_or_name, default=False): cached = cls.get_instance_from_cache(id_or_name) if cached: return cached - if not id_or_name: + if id_or_name is None: return cls.default() if default else None - elif id_or_name == cls.DEFAULT_ID_NAME: + elif id_or_name in [cls.DEFAULT_ID, cls.DEFAULT_NAME, '']: return cls.default() - elif id_or_name == cls.ROOT_ID_NAME: + elif id_or_name in [cls.ROOT_ID, cls.ROOT_NAME]: return cls.root() try: @@ -89,7 +88,7 @@ class Organization(models.Model): return False def is_real(self): - return len(str(self.id)) == 36 + return self.id not in (self.DEFAULT_NAME, self.ROOT_ID) @classmethod def get_user_admin_orgs(cls, user): @@ -105,20 +104,20 @@ class Organization(models.Model): @classmethod def default(cls): - return cls(id=cls.DEFAULT_ID_NAME, name=cls.DEFAULT_ID_NAME) + return cls(id=cls.DEFAULT_ID, name=cls.DEFAULT_NAME) @classmethod def root(cls): - return cls(id=cls.ROOT_ID_NAME, name=cls.ROOT_ID_NAME) + return cls(id=cls.ROOT_ID, name=cls.ROOT_NAME) def is_root(self): - if self.id is self.ROOT_ID_NAME: + if self.id is self.ROOT_ID: return True else: return False def is_default(self): - if self.id is self.DEFAULT_ID_NAME: + if self.id is self.DEFAULT_ID: return True else: return False diff --git a/apps/orgs/utils.py b/apps/orgs/utils.py index 09bf081ae..8f380b169 100644 --- a/apps/orgs/utils.py +++ b/apps/orgs/utils.py @@ -10,12 +10,14 @@ def get_org_from_request(request): oid = request.session.get("oid") if not oid: oid = request.META.get("HTTP_X_JMS_ORG") + if not oid: + oid = Organization.DEFAULT_ID org = Organization.get_instance(oid) return org def set_current_org(org): - setattr(thread_local, 'current_org', org.id) + setattr(thread_local, 'current_org_id', org.id) def set_to_default_org(): @@ -31,13 +33,22 @@ def _find(attr): def get_current_org(): - org_id = _find('current_org') + org_id = get_current_org_id() + if org_id is None: + return None org = Organization.get_instance(org_id) return org def get_current_org_id(): - org_id = _find('current_org') + org_id = _find('current_org_id') + return org_id + + +def get_current_org_id_for_serializer(): + org_id = get_current_org_id() + if org_id == Organization.DEFAULT_ID: + org_id = '' return org_id diff --git a/apps/orgs/views.py b/apps/orgs/views.py index 29bd231a7..e7bf9fc62 100644 --- a/apps/orgs/views.py +++ b/apps/orgs/views.py @@ -13,7 +13,8 @@ class SwitchOrgView(DetailView): def get(self, request, *args, **kwargs): pk = kwargs.get('pk') self.object = Organization.get_instance(pk) - request.session['oid'] = self.object.id.__str__() + oid = str(self.object.id) + request.session['oid'] = oid host = request.get_host() referer = request.META.get('HTTP_REFERER') if referer.find(host) != -1: