|
|
|
@ -12,6 +12,7 @@ from common.serializers.fields import (
|
|
|
|
|
)
|
|
|
|
|
from common.utils import pretty_string, get_logger
|
|
|
|
|
from common.validators import PhoneValidator
|
|
|
|
|
from orgs.utils import current_org
|
|
|
|
|
from rbac.builtin import BuiltinRole
|
|
|
|
|
from rbac.models import OrgRoleBinding, SystemRoleBinding, Role
|
|
|
|
|
from rbac.permissions import RBACPermission
|
|
|
|
@ -23,6 +24,7 @@ __all__ = [
|
|
|
|
|
"MiniUserSerializer",
|
|
|
|
|
"InviteSerializer",
|
|
|
|
|
"ServiceAccountSerializer",
|
|
|
|
|
"UserRetrieveSerializer",
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
logger = get_logger(__file__)
|
|
|
|
@ -46,6 +48,7 @@ class RolesSerializerMixin(serializers.Serializer):
|
|
|
|
|
label=_("Org roles"), many=True, required=False,
|
|
|
|
|
default=default_org_roles
|
|
|
|
|
)
|
|
|
|
|
orgs_roles = serializers.JSONField(read_only=True, label=_("Organization and roles relations"))
|
|
|
|
|
|
|
|
|
|
def pop_roles_if_need(self, fields):
|
|
|
|
|
request = self.context.get("request")
|
|
|
|
@ -58,7 +61,7 @@ class RolesSerializerMixin(serializers.Serializer):
|
|
|
|
|
|
|
|
|
|
model_cls_field_mapper = {
|
|
|
|
|
SystemRoleBinding: ["system_roles"],
|
|
|
|
|
OrgRoleBinding: ["org_roles"],
|
|
|
|
|
OrgRoleBinding: ["org_roles", "orgs_roles"],
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
update_actions = ("partial_bulk_update", "bulk_update", "partial_update", "update")
|
|
|
|
@ -156,6 +159,7 @@ class UserSerializer(RolesSerializerMixin, CommonBulkSerializerMixin, ResourceLa
|
|
|
|
|
"is_first_login", "wecom_id", "dingtalk_id",
|
|
|
|
|
"feishu_id", "lark_id", "date_api_key_last_used",
|
|
|
|
|
]
|
|
|
|
|
fields_only_root_org = ["orgs_roles"]
|
|
|
|
|
disallow_self_update_fields = ["is_active", "system_roles", "org_roles"]
|
|
|
|
|
extra_kwargs = {
|
|
|
|
|
"password": {
|
|
|
|
@ -177,7 +181,18 @@ class UserSerializer(RolesSerializerMixin, CommonBulkSerializerMixin, ResourceLa
|
|
|
|
|
"is_otp_secret_key_bound": {"label": _("Is OTP bound")},
|
|
|
|
|
'mfa_level': {'label': _("MFA level")},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def get_fields(self):
|
|
|
|
|
fields = super().get_fields()
|
|
|
|
|
self.pop_fields_if_need(fields)
|
|
|
|
|
return fields
|
|
|
|
|
|
|
|
|
|
def pop_fields_if_need(self, fields):
|
|
|
|
|
# pop only root org fields
|
|
|
|
|
if not current_org.is_root():
|
|
|
|
|
for f in self.Meta.fields_only_root_org:
|
|
|
|
|
fields.pop(f, None)
|
|
|
|
|
|
|
|
|
|
def validate_password(self, password):
|
|
|
|
|
password_strategy = self.initial_data.get("password_strategy")
|
|
|
|
|
if self.instance is None and password_strategy != PasswordStrategy.custom:
|
|
|
|
@ -273,7 +288,7 @@ class UserRetrieveSerializer(UserSerializer):
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
class Meta(UserSerializer.Meta):
|
|
|
|
|
fields = UserSerializer.Meta.fields + ["login_confirm_settings"]
|
|
|
|
|
fields = UserSerializer.Meta.fields + ["login_confirm_settings", "orgs_roles"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class MiniUserSerializer(serializers.ModelSerializer):
|
|
|
|
|