diff --git a/apps/common/sdk/im/feishu/__init__.py b/apps/common/sdk/im/feishu/__init__.py index c7bf03a06..199658c6b 100644 --- a/apps/common/sdk/im/feishu/__init__.py +++ b/apps/common/sdk/im/feishu/__init__.py @@ -1,5 +1,6 @@ import json +from django.conf import settings from rest_framework.exceptions import APIException from common.sdk.im.mixin import RequestMixin, BaseRequest @@ -53,6 +54,7 @@ class FeishuRequests(BaseRequest): ) code_key = 'code' msg_key = 'msg' + url_instance = URL() def __init__(self, app_id, app_secret, timeout=None): self._app_id = app_id @@ -65,7 +67,7 @@ class FeishuRequests(BaseRequest): def request_access_token(self): data = {'app_id': self._app_id, 'app_secret': self._app_secret} - response = self.raw_request('post', url=URL().get_token, data=data) + response = self.raw_request('post', url=self.url_instance.get_token, data=data) self.check_errcode_is_0(response) access_token = response['tenant_access_token'] @@ -82,6 +84,7 @@ class FeiShu(RequestMixin): 非业务数据导致的错误直接抛异常,说明是系统配置错误,业务代码不用理会 """ requests_cls = FeishuRequests + attributes = settings.LARK_RENAME_ATTRIBUTES def __init__(self, app_id, app_secret, timeout=None): self._app_id = app_id or '' @@ -92,6 +95,7 @@ class FeiShu(RequestMixin): app_secret=app_secret, timeout=timeout ) + self.url_instance = self._requests.url_instance def get_user_id_by_code(self, code): # https://open.feishu.cn/document/ukTMukTMukTM/uEDO4UjLxgDO14SM4gTN @@ -101,7 +105,7 @@ class FeiShu(RequestMixin): 'code': code } - data = self._requests.post(URL().get_user_info_by_code, json=body, check_errcode_is_0=False) + data = self._requests.post(self.url_instance.get_user_info_by_code, json=body, check_errcode_is_0=False) self._requests.check_errcode_is_0(data) return data['data']['user_id'], data['data'] @@ -126,7 +130,7 @@ class FeiShu(RequestMixin): try: logger.info(f'{self.__class__.__name__} send text: user_ids={user_ids} msg={msg}') - self._requests.post(URL().send_message, params=params, json=body) + self._requests.post(self.url_instance.send_message, params=params, json=body) except APIException as e: # 只处理可预知的错误 logger.exception(e) @@ -134,13 +138,24 @@ class FeiShu(RequestMixin): return invalid_users @staticmethod - def get_user_detail(user_id, **kwargs): - # get_user_id_by_code 已经返回个人信息,这里直接解析 - data = kwargs['other_info'] - username = user_id + def default_user_detail(data): + username = data['user_id'] name = data.get('name', username) email = data.get('email') or data.get('enterprise_email') email = construct_user_email(username, email) return { 'username': username, 'name': name, 'email': email } + + def get_user_detail(self, user_id, **kwargs): + # get_user_id_by_code 已经返回个人信息,这里直接解析 + data = kwargs['other_info'] + data['user_id'] = user_id + detail = self.default_user_detail(data) + + for local_name, remote_name in self.attributes.items(): + value = data.get(remote_name) + if not value: + continue + detail[local_name] = value + return detail diff --git a/apps/common/sdk/im/lark/__init__.py b/apps/common/sdk/im/lark/__init__.py index dcfaa838a..cacd75297 100644 --- a/apps/common/sdk/im/lark/__init__.py +++ b/apps/common/sdk/im/lark/__init__.py @@ -1,3 +1,5 @@ +from django.conf import settings + from common.utils.common import get_logger from ..feishu import URL as FeiShuURL, FeishuRequests, FeiShu @@ -9,8 +11,9 @@ class URL(FeiShuURL): class LarkRequests(FeishuRequests): - pass + url_instance = URL() class Lark(FeiShu): requests_cls = LarkRequests + attributes = settings.LARK_RENAME_ATTRIBUTES diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index 6b97c35ea..21c58bf9c 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -408,11 +408,21 @@ class Config(dict): 'AUTH_FEISHU': False, 'FEISHU_APP_ID': '', 'FEISHU_APP_SECRET': '', + 'FEISHU_RENAME_ATTRIBUTES': { + 'name': 'name', + 'username': 'user_id', + 'email': 'enterprise_email' + }, # Lark 'AUTH_LARK': False, 'LARK_APP_ID': '', 'LARK_APP_SECRET': '', + 'LARK_RENAME_ATTRIBUTES': { + 'name': 'en_name', + 'username': 'user_id', + 'email': 'enterprise_email' + }, # Slack 'AUTH_SLACK': False, diff --git a/apps/jumpserver/settings/auth.py b/apps/jumpserver/settings/auth.py index 60d2aeab8..d765ff108 100644 --- a/apps/jumpserver/settings/auth.py +++ b/apps/jumpserver/settings/auth.py @@ -141,10 +141,12 @@ DINGTALK_APPSECRET = CONFIG.DINGTALK_APPSECRET AUTH_FEISHU = CONFIG.AUTH_FEISHU FEISHU_APP_ID = CONFIG.FEISHU_APP_ID FEISHU_APP_SECRET = CONFIG.FEISHU_APP_SECRET +FEISHU_RENAME_ATTRIBUTES = CONFIG.FEISHU_RENAME_ATTRIBUTES AUTH_LARK = CONFIG.AUTH_LARK LARK_APP_ID = CONFIG.LARK_APP_ID LARK_APP_SECRET = CONFIG.LARK_APP_SECRET +LARK_RENAME_ATTRIBUTES = CONFIG.LARK_RENAME_ATTRIBUTES # Slack auth AUTH_SLACK = CONFIG.AUTH_SLACK diff --git a/apps/settings/api/feishu.py b/apps/settings/api/feishu.py index 1f639f66c..31afc194c 100644 --- a/apps/settings/api/feishu.py +++ b/apps/settings/api/feishu.py @@ -5,6 +5,7 @@ from rest_framework.generics import GenericAPIView from rest_framework.views import Response from common.sdk.im.feishu import FeiShu +from common.sdk.im.lark import Lark from settings.models import Setting from .. import serializers @@ -30,8 +31,10 @@ class FeiShuTestingAPI(GenericAPIView): app_secret = app_secret or '' + auth_cls = FeiShu if self.category == 'FEISHU' else Lark + try: - feishu = FeiShu(app_id=app_id, app_secret=app_secret) + feishu = auth_cls(app_id=app_id, app_secret=app_secret) feishu.send_text(['test'], 'test') return Response(status=status.HTTP_200_OK, data={'msg': _('Test success')}) except APIException as e: @@ -40,8 +43,3 @@ class FeiShuTestingAPI(GenericAPIView): except: error = e.detail return Response(status=status.HTTP_400_BAD_REQUEST, data={'error': error}) - - -class LarkTestingAPI(FeiShuTestingAPI): - category = 'LARK' - serializer_class = serializers.LarkSettingSerializer diff --git a/apps/settings/serializers/auth/feishu.py b/apps/settings/serializers/auth/feishu.py index 771a7997c..81f3f7ee9 100644 --- a/apps/settings/serializers/auth/feishu.py +++ b/apps/settings/serializers/auth/feishu.py @@ -12,3 +12,10 @@ class FeiShuSettingSerializer(serializers.Serializer): AUTH_FEISHU = serializers.BooleanField(default=False, label=_('FeiShu')) FEISHU_APP_ID = serializers.CharField(max_length=256, required=True, label='App ID') FEISHU_APP_SECRET = EncryptedField(max_length=256, required=False, label='App Secret') + FEISHU_RENAME_ATTRIBUTES = serializers.JSONField( + required=False, label=_('User attribute'), + help_text=_( + "User attribute mapping, where the `key` is the CAS service user attribute name " + "and the `value` is the JumpServer user attribute name" + ) + ) \ No newline at end of file diff --git a/apps/settings/serializers/auth/lark.py b/apps/settings/serializers/auth/lark.py index 36b493ab0..0726ac334 100644 --- a/apps/settings/serializers/auth/lark.py +++ b/apps/settings/serializers/auth/lark.py @@ -12,3 +12,10 @@ class LarkSettingSerializer(serializers.Serializer): AUTH_LARK = serializers.BooleanField(default=False, label=_('Lark')) LARK_APP_ID = serializers.CharField(max_length=256, required=True, label='App ID') LARK_APP_SECRET = EncryptedField(max_length=256, required=False, label='App Secret') + LARK_RENAME_ATTRIBUTES = serializers.JSONField( + required=False, label=_('User attribute'), + help_text=_( + "User attribute mapping, where the `key` is the CAS service user attribute name " + "and the `value` is the JumpServer user attribute name" + ) + ) \ No newline at end of file