保留钉钉用户人工指定角色
This commit is contained in:
parent
4a8f4e03d3
commit
e965aad724
@ -192,7 +192,7 @@ class DingTalkAuthService:
|
|||||||
|
|
||||||
async def _upsert_user(self, user_id: str, detail: dict) -> UserAccount:
|
async def _upsert_user(self, user_id: str, detail: dict) -> UserAccount:
|
||||||
user = await self.repo.get_by_dingtalk_id(user_id)
|
user = await self.repo.get_by_dingtalk_id(user_id)
|
||||||
role = self.map_role(
|
mapped_role = self.map_role(
|
||||||
str(detail.get("dept_name") or detail.get("deptName") or ""),
|
str(detail.get("dept_name") or detail.get("deptName") or ""),
|
||||||
str(detail.get("title") or detail.get("position") or ""),
|
str(detail.get("title") or detail.get("position") or ""),
|
||||||
self._is_dingtalk_manager(detail),
|
self._is_dingtalk_manager(detail),
|
||||||
@ -201,7 +201,7 @@ class DingTalkAuthService:
|
|||||||
user = UserAccount(
|
user = UserAccount(
|
||||||
emp_no=f"dt_{user_id}"[:20],
|
emp_no=f"dt_{user_id}"[:20],
|
||||||
name=self._display_name(detail, user_id),
|
name=self._display_name(detail, user_id),
|
||||||
role=role,
|
role=mapped_role,
|
||||||
status="启用",
|
status="启用",
|
||||||
dingtalk_id=user_id,
|
dingtalk_id=user_id,
|
||||||
)
|
)
|
||||||
@ -209,7 +209,7 @@ class DingTalkAuthService:
|
|||||||
user.name = self._display_name(detail, user.name or user_id)
|
user.name = self._display_name(detail, user.name or user_id)
|
||||||
user.dept = (self._department_name(detail) or user.dept or "")[:50] or None
|
user.dept = (self._department_name(detail) or user.dept or "")[:50] or None
|
||||||
user.position = str(detail.get("title") or detail.get("position") or detail.get("job_title") or user.position or "")[:50] or None
|
user.position = str(detail.get("title") or detail.get("position") or detail.get("job_title") or user.position or "")[:50] or None
|
||||||
user.role = role
|
user.role = self.resolve_synced_role(user.role, mapped_role)
|
||||||
user.dingtalk_union_id = str(detail.get("unionid") or user.dingtalk_union_id or "")[:64] or None
|
user.dingtalk_union_id = str(detail.get("unionid") or user.dingtalk_union_id or "")[:64] or None
|
||||||
user.dingtalk_avatar = str(detail.get("avatar") or user.dingtalk_avatar or "")[:512] or None
|
user.dingtalk_avatar = str(detail.get("avatar") or user.dingtalk_avatar or "")[:512] or None
|
||||||
user.dingtalk_job_number = str(detail.get("job_number") or user.dingtalk_job_number or "")[:64] or None
|
user.dingtalk_job_number = str(detail.get("job_number") or user.dingtalk_job_number or "")[:64] or None
|
||||||
@ -237,6 +237,19 @@ class DingTalkAuthService:
|
|||||||
|
|
||||||
return "admin" if is_admin else "user"
|
return "admin" if is_admin else "user"
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def resolve_synced_role(current_role: str, mapped_role: str) -> str:
|
||||||
|
"""Apply DingTalk role mapping without downgrading assigned roles.
|
||||||
|
|
||||||
|
Existing roles are treated as administrator-managed data. DingTalk may
|
||||||
|
promote a regular user when it reports a manager flag, but a missing
|
||||||
|
flag must never downgrade an existing admin (or another assigned role).
|
||||||
|
"""
|
||||||
|
|
||||||
|
if current_role == "user" and mapped_role == "admin":
|
||||||
|
return "admin"
|
||||||
|
return current_role
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _is_dingtalk_manager(detail: dict) -> bool:
|
def _is_dingtalk_manager(detail: dict) -> bool:
|
||||||
"""Read administrator/department-leader flags from DingTalk API variants."""
|
"""Read administrator/department-leader flags from DingTalk API variants."""
|
||||||
|
|||||||
@ -10,6 +10,14 @@ def test_dingtalk_role_mapping() -> None:
|
|||||||
assert DingTalkAuthService.map_role("未知部门", "普通员工") == "user"
|
assert DingTalkAuthService.map_role("未知部门", "普通员工") == "user"
|
||||||
|
|
||||||
|
|
||||||
|
def test_dingtalk_sync_only_promotes_user_and_never_downgrades_admin() -> None:
|
||||||
|
assert DingTalkAuthService.resolve_synced_role("user", "admin") == "admin"
|
||||||
|
assert DingTalkAuthService.resolve_synced_role("user", "user") == "user"
|
||||||
|
assert DingTalkAuthService.resolve_synced_role("admin", "user") == "admin"
|
||||||
|
assert DingTalkAuthService.resolve_synced_role("admin", "admin") == "admin"
|
||||||
|
assert DingTalkAuthService.resolve_synced_role("reviewer", "admin") == "reviewer"
|
||||||
|
|
||||||
|
|
||||||
def test_dingtalk_manager_flag_variants() -> None:
|
def test_dingtalk_manager_flag_variants() -> None:
|
||||||
assert DingTalkAuthService._is_dingtalk_manager({"admin": True})
|
assert DingTalkAuthService._is_dingtalk_manager({"admin": True})
|
||||||
assert DingTalkAuthService._is_dingtalk_manager({"leader_in_dept": [{"leader": True}]})
|
assert DingTalkAuthService._is_dingtalk_manager({"leader_in_dept": [{"leader": True}]})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user