perf: 支持slack通知和认证 (#12193)

* perf: 支持slack通知和认证

* perf: 生成迁移文件

* perf: 优化获取access_token逻辑

---------

Co-authored-by: jiangweidong <weidong.jiang@fit2cloud.com>
This commit is contained in:
fit2bot
2023-11-29 17:45:44 +08:00
committed by GitHub
parent 575562c416
commit 0fdae00722
26 changed files with 523 additions and 114 deletions

View File

@@ -1,8 +1,6 @@
from urllib.parse import urlencode
from django.conf import settings
from django.contrib.auth import logout as auth_logout
from django.db.utils import IntegrityError
from django.http.request import HttpRequest
from django.http.response import HttpResponseRedirect
from django.utils.translation import gettext_lazy as _
@@ -13,7 +11,6 @@ from rest_framework.permissions import IsAuthenticated, AllowAny
from authentication import errors
from authentication.const import ConfirmType
from authentication.mixins import AuthMixin
from authentication.notifications import OAuthBindMessage
from authentication.permissions import UserConfirmation
from common.sdk.im.wecom import URL
from common.sdk.im.wecom import WeCom
@@ -24,7 +21,7 @@ from common.utils.random import random_string
from common.views.mixins import UserConfirmRequiredExceptionMixin, PermissionsMixin
from users.models import User
from users.views import UserVerifyPasswordView
from .base import BaseLoginCallbackView
from .base import BaseLoginCallbackView, BaseBindCallbackView
from .mixins import METAMixin, FlashMessageMixin
logger = get_logger(__file__)
@@ -104,64 +101,21 @@ class WeComQRBindView(WeComQRMixin, View):
permission_classes = (IsAuthenticated, UserConfirmation.require(ConfirmType.RELOGIN))
def get(self, request: HttpRequest):
user = request.user
redirect_url = request.GET.get('redirect_url')
redirect_uri = reverse('authentication:wecom-qr-bind-callback', kwargs={'user_id': user.id}, external=True)
redirect_uri = reverse('authentication:wecom-qr-bind-callback', external=True)
redirect_uri += '?' + urlencode({'redirect_url': redirect_url})
url = self.get_qr_url(redirect_uri)
return HttpResponseRedirect(url)
class WeComQRBindCallbackView(WeComQRMixin, View):
class WeComQRBindCallbackView(WeComQRMixin, BaseBindCallbackView):
permission_classes = (IsAuthenticated,)
def get(self, request: HttpRequest, user_id):
code = request.GET.get('code')
redirect_url = request.GET.get('redirect_url')
if not self.verify_state():
return self.get_verify_state_failed_response(redirect_url)
user = get_object_or_none(User, id=user_id)
if user is None:
logger.error(f'WeComQR bind callback error, user_id invalid: user_id={user_id}')
msg = _('Invalid user_id')
response = self.get_failed_response(redirect_url, msg, msg)
return response
if user.wecom_id:
response = self.get_already_bound_response(redirect_url)
return response
wecom = WeCom(
corpid=settings.WECOM_CORPID,
corpsecret=settings.WECOM_SECRET,
agentid=settings.WECOM_AGENTID
)
wecom_userid, __ = wecom.get_user_id_by_code(code)
if not wecom_userid:
msg = _('WeCom query user failed')
response = self.get_failed_response(redirect_url, msg, msg)
return response
try:
user.wecom_id = wecom_userid
user.save()
except IntegrityError as e:
if e.args[0] == 1062:
msg = _('The WeCom is already bound to another user')
response = self.get_failed_response(redirect_url, msg, msg)
return response
raise e
ip = get_request_ip(request)
OAuthBindMessage(user, ip, _('WeCom'), wecom_userid).publish_async()
msg = _('Binding WeCom successfully')
auth_logout(request)
response = self.get_success_response(redirect_url, msg, msg)
return response
client_type_path = 'common.sdk.im.wecom.WeCom'
client_auth_params = {'corpid': 'WECOM_CORPID', 'corpsecret': 'WECOM_SECRET', 'agentid': 'WECOM_AGENTID'}
auth_type = 'wecom'
auth_type_label = _('Wecom')
class WeComEnableStartView(UserVerifyPasswordView):