feat: 添加短信服务和用户消息通知

This commit is contained in:
xinwen
2021-08-24 14:20:54 +08:00
parent d49d1e1414
commit b1fceca8a6
57 changed files with 1442 additions and 296 deletions

View File

@@ -20,18 +20,24 @@ from django.shortcuts import reverse
from orgs.utils import current_org
from orgs.models import OrganizationMember, Organization
from common.exceptions import JMSException
from common.utils import date_expired_default, get_logger, lazyproperty, random_string
from common import fields
from common.const import choices
from common.db.models import TextChoices
from users.exceptions import MFANotEnabled
from users.exceptions import MFANotEnabled, PhoneNotSet
from ..signals import post_user_change_password
__all__ = ['User', 'UserPasswordHistory']
__all__ = ['User', 'UserPasswordHistory', 'MFAType']
logger = get_logger(__file__)
class MFAType(TextChoices):
OTP = 'otp', _('One-time password')
SMS_CODE = 'sms', _('SMS verify code')
class AuthMixin:
date_password_last_updated: datetime.datetime
is_local: bool
@@ -514,19 +520,52 @@ class MFAMixin:
from ..utils import check_otp_code
return check_otp_code(self.otp_secret_key, code)
def check_mfa(self, code):
def check_mfa(self, code, mfa_type=MFAType.OTP):
if not self.mfa_enabled:
raise MFANotEnabled
if settings.OTP_IN_RADIUS:
return self.check_radius(code)
else:
return self.check_otp(code)
if mfa_type == MFAType.OTP:
if settings.OTP_IN_RADIUS:
return self.check_radius(code)
else:
return self.check_otp(code)
elif mfa_type == MFAType.SMS_CODE:
return self.check_sms_code(code)
def get_supported_mfa_types(self):
methods = []
if self.otp_secret_key:
methods.append(MFAType.OTP)
if self.phone:
methods.append(MFAType.SMS_CODE)
return methods
def check_sms_code(self, code):
from authentication.sms_verify_code import VerifyCodeUtil
if not self.phone:
raise PhoneNotSet
try:
util = VerifyCodeUtil(self.phone)
return util.verify(code)
except JMSException:
return False
def send_sms_code(self):
from authentication.sms_verify_code import VerifyCodeUtil
if not self.phone:
raise PhoneNotSet
util = VerifyCodeUtil(self.phone)
util.touch()
return util.timeout
def mfa_enabled_but_not_set(self):
if not self.mfa_enabled:
return False, None
if self.mfa_is_otp() and not self.otp_secret_key:
if self.mfa_is_otp() and not self.otp_secret_key and not self.phone:
return True, reverse('authentication:user-otp-enable-start')
return False, None