def send_sms(mobile, code, template): ''' 向指定手机发送验证 ''' sms_config = SMSConfig.get_current() smser = SMSAliyunManager( access_key=sms_config.access_key, access_key_secret=sms_config.access_secret, ) signature = sms_config.signature if is_cn_mobile( mobile) else sms_config.signature_i18n mobile = ''.join([literal for literal in mobile if literal.isdigit()]) # `+86 18812341234` -> `8618812341234` try: smser.send_auth_code( mobile=mobile, vc_code=code, sign_name=signature, template_code=template, ) except RuntimeError as exc: if 'MOBILE_NUMBER_ILLEGAL' in repr(exc): raise ValidationError({'mobile': 'invalid'}) raise exc
def setUp(self): super().setUp() account_config = AccountConfig.get_current() account_config.allow_email = True account_config.allow_mobile = True account_config.allow_register = True account_config.save() email_config = EmailConfig.get_current() email_config.is_valid = True email_config.save() mobile_config = SMSConfig.get_current() mobile_config.is_valid = True mobile_config.save() self.clear_sms_token_patcher = mock.patch( 'infrastructure.serializers.sms.SMSClaimSerializer.clear_sms_token' ) self.mock_clear_sms_token = self.clear_sms_token_patcher.start() self.mock_clear_sms_token.return_value = True self.clear_email_token_patcher = mock.patch( 'infrastructure.serializers.email.EmailClaimSerializer.clear_email_token' ) self.mock_clear_email_token = self.clear_email_token_patcher.start() self.mock_clear_email_token.return_value = True
def get_template_id(self): # pylint: disable=no-self-use ''' 读取模板id ''' sms_config = SMSConfig.get_current() i18n = not is_cn_mobile( self.validated_data['mobile']) # 国内号码即使加上区号,也无法使用国际模板 return sms_config.get_template_code("code", i18n)
def get_template_id(self): ''' 读取模板ID ''' sms_config = SMSConfig.get_current() i18n = not is_cn_mobile(self.validated_data['mobile']) return sms_config.get_template_code("reset_mobile", i18n) or \ sms_config.get_template_code("code", i18n)
def get_template_id(self): ''' 读取模板ID ''' sms_config = SMSConfig.get_current() if sms_config.template_activate: return sms_config.template_activate return super().get_template_id()
def get_template_id(self): ''' 读取模板ID ''' sms_config = SMSConfig.get_current() if sms_config.template_reset_mobile: return sms_config.template_reset_mobile return super().get_template_id()
def update(self, instance, validated_data): company_config_data = validated_data.pop('company_config', None) if company_config_data: serializer = CompanyConfigSerializer(CompanyConfig.get_current(), company_config_data) serializer.is_valid(raise_exception=True) serializer.save() ding_config_data = validated_data.pop('ding_config', None) if ding_config_data: serializer = DingConfigSerializer(DingConfig.get_current(), ding_config_data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() account_config_data = validated_data.pop('account_config', None) if account_config_data: serializer = AccountConfigSerializer(AccountConfig.get_current(), account_config_data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() sms_config_data = validated_data.pop('sms_config', None) if sms_config_data: access_secret = sms_config_data.pop('access_secret', '') serializer = SMSConfigSerializer(SMSConfig.get_current(), sms_config_data, partial=True) serializer.is_valid(raise_exception=True) # pylint: disable=not-callable config = serializer.save() if access_secret and access_secret != config.access_secret_encrypt: config.access_secret = access_secret config.is_valid = config.check_valid() config.save() email_config_data = validated_data.pop('email_config', None) if email_config_data: access_secret = email_config_data.pop('access_secret', '') serializer = EmailConfigSerializer(EmailConfig.get_current(), email_config_data, partial=True) serializer.is_valid(raise_exception=True) # pylint: disable=not-callable config = serializer.save() if access_secret and access_secret != config.access_secret_encrypt: config.access_secret = access_secret config.is_valid = config.check_valid() config.save() instance.refresh_from_db() return instance
def setUp(self): super().setUp() account_config = AccountConfig.get_current() account_config.allow_email = True account_config.allow_mobile = True account_config.allow_register = True account_config.save() email_config = EmailConfig.get_current() email_config.is_valid = True email_config.save() mobile_config = SMSConfig.get_current() mobile_config.is_valid = True mobile_config.save()
def setUp(self): super().setUp() self.user = User.objects.create(username='******', mobile=MOBILE) account_config = AccountConfig.get_current() account_config.allow_email = True account_config.allow_mobile = True account_config.allow_register = True account_config.save() email_config = EmailConfig.get_current() email_config.is_valid = True email_config.save() mobile_config = SMSConfig.get_current() mobile_config.is_valid = True mobile_config.save()
def test_block_by_account_config(self): mobile_config = SMSConfig.get_current() mobile_config.is_valid = False mobile_config.save() res = self.anonymous.json_post(reverse('infra:sms', args=('activate_user', )), data={ 'key': '*', }) self.assertEqual({'mobile': ['unsupported']}, res.json()) account_config = AccountConfig.get_current() account_config.allow_register = False account_config.save() res = self.anonymous.json_post(reverse('infra:email', args=('register', )), data={ 'email': '*', }) self.assertEqual({'email': ['unsupported']}, res.json())
def test_login(self, mock_check_sms_token): mock_check_sms_token.side_effect = [{'mobile': '18812341234'}] user = User.create_user(username='******', password='******') user.mobile = '18812341234' user.private_email = '*****@*****.**' user.save() client = APIClient() res = client.get(reverse('siteapi:user_self_perm')) self.assertEqual(res.status_code, 401) res = client.post(reverse('siteapi:user_login'), data={'username': '******', 'password': '******'}) self.assertEqual(res.status_code, 200) res = client.post(reverse('siteapi:user_login'), data={'private_email': '*****@*****.**', 'password': '******'}) self.assertEqual(res.status_code, 200) res = client.post(reverse('siteapi:user_login'), data={'mobile': '18812341234', 'sms_token': 'mock'}) self.assertEqual(res.status_code, 200) user = User.objects.get(username='******') self.assertIsNotNone(user.last_active_time) self.assertTrue(user.is_settled) client.credentials(HTTP_AUTHORIZATION='Token ' + res.json()['token']) res = client.get(reverse('siteapi:user_self_perm')) self.assertEqual(res.status_code, 200) res = client.post(reverse('siteapi:user_login'), data={'username': '******', 'password': '******'}) self.assertEqual(res.json()['perms'], ['system_oneid_all', 'system_ark-meta-server_all']) # test login failed because of account_config email_config = EmailConfig.get_current() email_config.is_valid = False email_config.save() res = client.post(reverse('siteapi:user_login'), data={'private_email': '*****@*****.**', 'password': '******'}) self.assertEqual(res.status_code, 400) mobile_config = SMSConfig.get_current() mobile_config.is_valid = False mobile_config.save() res = client.post(reverse('siteapi:user_login'), data={'mobile': '18812341234', 'sms_token': 'mock'}) self.assertEqual(res.status_code, 400)
def send_sms(mobile, code, template=''): ''' 向指定手机发送验证 ''' sms_config = SMSConfig.get_current() smser = SMSAliyunManager( access_key=sms_config.access_key, access_key_secret=sms_config.access_secret, ) try: smser.send_auth_code( mobile=mobile, vc_code=code, sign_name=sms_config.signature, template_code=sms_config.template_code if not template else template, ) except RuntimeError as exc: if 'MOBILE_NUMBER_ILLEGAL' in repr(exc): raise ValidationError({'mobile': 'invalid'}) raise exc
def update(self, instance, validated_data): company_config_data = validated_data.pop('company_config', None) if company_config_data: if not Dept.valid_objects.filter(parent__uid='root').exists(): uid = gen_uid(name=company_config_data.get('name_cn', ''), cls=Dept) parent_dept = Dept.valid_objects.filter(uid='root').first() cli = CLI() dept_data = { 'parent_uid': 'root', 'name': company_config_data.get('name_cn', ''), 'uid': uid, } child_dept = cli.create_dept(dept_data) cli.add_dept_to_dept(child_dept, parent_dept) else: company_dept = Dept.valid_objects.filter(parent__uid='root').first() company_dept.name = company_config_data.get('name_cn', '') company_dept.save() serializer = CompanyConfigSerializer(CompanyConfig.get_current(), company_config_data) serializer.is_valid(raise_exception=True) serializer.save() ding_config_data = validated_data.pop('ding_config', None) if ding_config_data: serializer = DingConfigSerializer(DingConfig.get_current(), ding_config_data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() account_config_data = validated_data.pop('account_config', None) if account_config_data: serializer = AccountConfigSerializer(AccountConfig.get_current(), account_config_data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() sms_config_data = validated_data.pop('sms_config', None) if sms_config_data: access_secret = sms_config_data.pop('access_secret', '') config = SMSConfig.get_current() serializer = SMSConfigSerializer(config, sms_config_data, partial=True) serializer.is_valid(raise_exception=True) # pylint: disable=not-callable config.__dict__.update(serializer.validated_data) if access_secret: config.access_secret = access_secret if not config.check_valid(): raise ValidationError({'sms': ['invalid']}) config.is_valid = True config.save() email_config_data = validated_data.pop('email_config', None) if email_config_data: access_secret = email_config_data.pop('access_secret', '') config = EmailConfig.get_current() serializer = EmailConfigSerializer(config, email_config_data, partial=True) serializer.is_valid(raise_exception=True) # pylint: disable=not-callable config.__dict__.update(serializer.validated_data) if access_secret: config.access_secret = access_secret if not config.check_valid(): raise ValidationError({'email': ['invalid']}) config.is_valid = True config.save() instance.refresh_from_db() return instance
def test_update_config(self, mock_connect, mock_send_auth_code): mock_connect.return_value = True mock_send_auth_code.return_value = True res = self.client.json_patch(reverse('siteapi:config'), data={ 'company_config': { 'fullname_cn': 'demo', 'color': 'color', }, 'ding_config': { 'app_key': 'app_key', }, 'account_config': { 'allow_register': True, 'allow_mobile': True, }, 'sms_config': { 'access_key': 'access_key', 'access_secret': 'pwd', }, 'email_config': { 'host': '12.12.12.12', 'access_secret': 'pwd', } }) expect = { 'company_config': { 'name_cn': '', 'fullname_cn': 'demo', 'name_en': '', 'fullname_en': '', 'icon': '', 'address': '', 'domain': '', 'color': 'color', }, 'ding_config': { 'app_key': 'app_key', 'app_secret': '', 'app_valid': False, 'corp_id': '', 'corp_secret': '', 'corp_valid': False, }, 'account_config': { 'allow_email': False, 'allow_mobile': True, 'allow_register': True, }, 'sms_config': { 'access_key': 'access_key', 'access_secret': SMSConfig.encrypt('pwd'), 'signature': '', 'template_code': '', 'template_register': '', 'template_reset_pwd': '', 'template_activate': '', 'template_reset_mobile': '', 'vendor': 'aliyun', 'is_valid': True, }, 'email_config': { 'access_key': '', 'access_secret': EmailConfig.encrypt('pwd'), 'host': '12.12.12.12', 'nickname': 'OneID', 'port': 587, 'is_valid': True, }, } self.assertEqual(res.json(), expect) self.assertEqual(EmailConfig.get_current().access_secret, 'pwd') self.assertEqual(SMSConfig.get_current().access_secret, 'pwd') res = self.client.json_patch(reverse('siteapi:config'), data={ 'sms_config': { 'access_secret': SMSConfig.encrypt('pwd') }, 'email_config': { 'access_secret': EmailConfig.encrypt('pwd') } }) self.assertEqual(res.json()['sms_config']['access_secret'], SMSConfig.encrypt('pwd')) self.assertEqual(res.json()['email_config']['access_secret'], SMSConfig.encrypt('pwd')) self.assertEqual(SMSConfig.get_current().access_secret, 'pwd') self.assertEqual(EmailConfig.get_current().access_secret, 'pwd')
def test_update_config(self, mock_validate_corp_config, mock_validate_app_config,\ mock_validate_qr_app_config, mock_check_valid, mock_connect,\ mock_send_auth_code): mock_validate_corp_config.return_value = True mock_validate_app_config.return_value = False mock_validate_qr_app_config.return_value = True mock_check_valid.return_value = True mock_connect.return_value = True mock_send_auth_code.return_value = True res = self.client.json_patch(reverse('siteapi:config'), data={ 'company_config': { 'name_cn': 'demo', 'fullname_cn': 'demo', 'color': 'color', }, 'ding_config': { 'app_key': 'app_key', 'app_secret': 'pwd', 'corp_id': 'corp_id', 'corp_secret': 'pwd', 'qr_app_id': 'qr_app_id', 'qr_app_secret': 'qr_app_secret', }, 'account_config': { 'allow_register': True, 'allow_mobile': True, 'allow_ding_qr': True, 'allow_alipay_qr': False, 'allow_qq_qr': True, 'allow_work_wechat_qr': True }, 'sms_config': { 'access_key': 'access_key', 'access_secret': 'pwd', }, 'email_config': { 'host': '12.12.12.12', 'access_secret': 'pwd', }, }) expect = { 'company_config': { 'name_cn': 'demo', 'fullname_cn': 'demo', 'name_en': '', 'fullname_en': '', 'icon': '', 'address': '', 'domain': '', 'color': 'color', }, 'ding_config': { 'app_key': '', 'app_valid': False, 'corp_id': 'corp_id', 'corp_valid': True, 'qr_app_id': 'qr_app_id', 'qr_app_valid': True, }, 'account_config': { 'allow_email': False, 'allow_mobile': True, 'allow_register': True, 'allow_ding_qr': True, 'allow_alipay_qr': False, 'allow_qq_qr': True, 'allow_work_wechat_qr': True, 'allow_wechat_qr': False, }, 'sms_config': { 'access_key': 'access_key', 'signature': '', 'template_code': '', 'template_register': '', 'template_reset_pwd': '', 'template_activate': '', 'template_reset_mobile': '', 'vendor': 'aliyun', 'is_valid': True, }, 'email_config': { 'access_key': '', 'host': '12.12.12.12', 'nickname': 'OneID', 'port': 587, 'is_valid': True, }, 'alipay_config': None, 'work_wechat_config': None, 'wechat_config': None, 'qq_config': None, } self.assertEqual(res.json(), expect) self.assertEqual(EmailConfig.get_current().access_secret, 'pwd') self.assertEqual(SMSConfig.get_current().access_secret, 'pwd') res = self.client.json_patch(reverse('siteapi:config'), data={ 'email_config': { 'host': '12.12.12.13', 'access_secret': '', } }) self.assertEqual(res.status_code, 200) self.assertEqual(res.json()['email_config']['host'], "12.12.12.13")
def get_template_id(self): ''' 读取模板id ''' sms_config = SMSConfig.get_current() return sms_config.template_code
def get_template_id(self): # pylint: disable=no-self-use ''' 读取模板id ''' sms_config = SMSConfig.get_current() return sms_config.template_code
def update(self, instance, validated_data): company_config_data = validated_data.pop('company_config', None) if company_config_data: serializer = CompanyConfigSerializer(CompanyConfig.get_current(), company_config_data) serializer.is_valid(raise_exception=True) serializer.save() ding_config_data = validated_data.pop('ding_config', None) if ding_config_data: serializer = DingConfigSerializer(DingConfig.get_current(), ding_config_data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() account_config_data = validated_data.pop('account_config', None) if account_config_data: serializer = AccountConfigSerializer(AccountConfig.get_current(), account_config_data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() sms_config_data = validated_data.pop('sms_config', None) if sms_config_data: access_secret = sms_config_data.pop('access_secret', '') config = SMSConfig.get_current() serializer = SMSConfigSerializer(config, sms_config_data, partial=True) serializer.is_valid(raise_exception=True) # pylint: disable=not-callable config.__dict__.update(serializer.validated_data) if access_secret: config.access_secret = access_secret if not config.check_valid(): raise ValidationError({'sms': ['invalid']}) config.is_valid = True config.save() email_config_data = validated_data.pop('email_config', None) if email_config_data: access_secret = email_config_data.pop('access_secret', '') config = EmailConfig.get_current() serializer = EmailConfigSerializer(config, email_config_data, partial=True) serializer.is_valid(raise_exception=True) # pylint: disable=not-callable config.__dict__.update(serializer.validated_data) if access_secret: config.access_secret = access_secret if not config.check_valid(): raise ValidationError({'email': ['invalid']}) config.is_valid = True config.save() instance.refresh_from_db() return instance
def update(self, instance, validated_data): # pylint: disable=too-many-locals, too-many-statements, too-many-branches company_config_data = validated_data.pop('company_config', None) if company_config_data: if not Dept.valid_objects.filter(parent__uid='root').exists(): uid = gen_uid(name=company_config_data.get('name_cn', ''), cls=Dept) parent_dept = Dept.valid_objects.filter(uid='root').first() cli = CLI() dept_data = { 'parent_uid': 'root', 'name': company_config_data.get('name_cn', ''), 'uid': uid, } child_dept = cli.create_dept(dept_data) cli.add_dept_to_dept(child_dept, parent_dept) else: company_dept = Dept.valid_objects.filter( parent__uid='root').first() company_dept.name = company_config_data.get('name_cn', '') company_dept.save() serializer = CompanyConfigSerializer(CompanyConfig.get_current(), company_config_data) serializer.is_valid(raise_exception=True) serializer.save() account_config_data = validated_data.pop('account_config', None) if account_config_data: serializer = AccountConfigSerializer(AccountConfig.get_current(), account_config_data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() ding_config_data = validated_data.pop('ding_config', None) if ding_config_data: serializer = DingConfigSerializer(DingConfig.get_current(), ding_config_data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() sms_config_data = validated_data.pop('sms_config', None) if sms_config_data: access_secret = sms_config_data.pop('access_secret', '') config = SMSConfig.get_current() serializer = SMSConfigSerializer(config, sms_config_data, partial=True) serializer.is_valid(raise_exception=True) # pylint: disable=not-callable config.__dict__.update(serializer.validated_data) if access_secret: config.access_secret = access_secret if not config.check_valid(): raise ValidationError({'sms': ['invalid']}) config.is_valid = True config.save() email_config_data = validated_data.pop('email_config', None) if email_config_data: access_secret = email_config_data.pop('access_secret', '') config = EmailConfig.get_current() serializer = EmailConfigSerializer(config, email_config_data, partial=True) serializer.is_valid(raise_exception=True) # pylint: disable=not-callable config.__dict__.update(serializer.validated_data) if access_secret: config.access_secret = access_secret if not config.check_valid(): raise ValidationError({'email': ['invalid']}) config.is_valid = True config.save() alipay_config_data = validated_data.pop('alipay_config', None) if alipay_config_data: if alipay_config_data["app_id"] != '': serializer = AlipayConfigSerializer(AlipayConfig.get_current(), alipay_config_data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() qq_config_data = validated_data.pop('qq_config', None) if qq_config_data: serializer = QQConfigSerializer(QQConfig.get_current(), qq_config_data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() work_wechat_config_data = validated_data.pop('work_wechat_config', None) if work_wechat_config_data: serializer = WorkWechatConfigSerializer(WorkWechatConfig.get_current(),\ work_wechat_config_data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() wechat_config_data = validated_data.pop('wechat_config', None) if wechat_config_data: serializer = WechatConfigSerializer(WechatConfig.get_current(),\ wechat_config_data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() password_config_data = validated_data.pop('password_config', None) if password_config_data: config = PasswordComplexityConfig.get_current() serializer = PasswordConfigSerializer(config, password_config_data, partial=True) serializer.is_valid(raise_exception=True) # pylint: disable=not-callable config.__dict__.update(serializer.validated_data) config.save() github_config = validated_data.pop('github_config', None) if github_config: config = GithubConfig.get_current() serializer = GithubConfigSerializer(config, github_config, partial=True) serializer.is_valid(raise_exception=True) serializer.save() instance.refresh_from_db() return instance
def test_update_config(self, mock_validate_corp_config, mock_validate_app_config,\ mock_validate_qr_app_config, mock_check_valid, mock_connect,\ mock_send_auth_code): mock_validate_corp_config.return_value = True mock_validate_app_config.return_value = False mock_validate_qr_app_config.return_value = True mock_check_valid.return_value = True mock_connect.return_value = True mock_send_auth_code.return_value = True res = self.client.json_patch(reverse('siteapi:config'), data={ 'company_config': { 'name_cn': 'demo', 'fullname_cn': 'demo', 'color': '006404', }, 'ding_config': { 'app_key': 'app_key', 'app_secret': 'pwd', 'corp_id': 'corp_id', 'corp_secret': 'pwd', 'qr_app_id': 'qr_app_id', 'qr_app_secret': 'qr_app_secret', }, 'account_config': { 'allow_register': True, 'allow_mobile': True, 'allow_ding_qr': True, 'allow_alipay_qr': False, 'allow_qq_qr': True, 'allow_work_wechat_qr': True }, 'sms_config': { 'signature': 's', 'signature_i18n': 's_i18n', 'template_login': '******', 'template_login_i18n': 'tl_i18n', 'access_key': 'access_key', 'access_secret': 'pwd', }, 'email_config': { 'host': '12.12.12.12', 'access_secret': 'pwd', }, 'password_config': { 'is_active': True, 'min_digit': 1, 'min_length': 1, 'min_letter': 1, 'min_lower': 1, 'min_special': 1, 'min_upper': 1, 'min_word': 1 }, }) expect = { 'company_config': { 'name_cn': 'demo', 'fullname_cn': 'demo', 'name_en': '', 'fullname_en': '', 'icon': '', 'address': '', 'domain': '', 'color': '006404', }, 'ding_config': { 'app_key': '', 'app_valid': False, 'corp_id': 'corp_id', 'corp_valid': True, 'qr_app_id': 'qr_app_id', 'qr_app_valid': True, }, 'account_config': { 'allow_email': False, 'allow_mobile': True, 'allow_register': True, 'allow_ding_qr': True, 'allow_alipay_qr': False, 'allow_qq_qr': True, 'allow_work_wechat_qr': True, 'allow_wechat_qr': False, 'allow_github': False, }, 'sms_config': { 'access_key': 'access_key', 'signature': 's', 'template_code': '', 'template_login': '******', 'template_register': '', 'template_reset_pwd': '', 'template_activate': '', 'template_reset_mobile': '', 'signature_i18n': 's_i18n', 'template_code_i18n': '', 'template_login_i18n': 'tl_i18n', 'template_register_i18n': '', 'template_reset_pwd_i18n': '', 'template_activate_i18n': '', 'template_reset_mobile_i18n': '', 'vendor': 'aliyun', 'is_valid': True, }, 'email_config': { 'access_key': '', 'host': '12.12.12.12', 'nickname': 'OneID', 'port': 587, 'is_valid': True, }, 'alipay_config': None, 'work_wechat_config': None, 'wechat_config': None, 'qq_config': None, 'password_config': { 'is_active': True, 'min_digit': 1, 'min_length': 1, 'min_letter': 1, 'min_lower': 1, 'min_special': 1, 'min_upper': 1, 'min_word': 1 }, 'github_config': { 'client_id': '', 'client_valid': False } } self.assertEqual(res.json(), expect) self.assertEqual(EmailConfig.get_current().access_secret, 'pwd') self.assertEqual(SMSConfig.get_current().access_secret, 'pwd') res = self.client.json_patch(reverse('siteapi:config'), data={ 'email_config': { 'host': '12.12.12.13', 'access_secret': '', } }) self.assertEqual(res.status_code, 200) self.assertEqual(res.json()['email_config']['host'], "12.12.12.13") res = self.client.json_patch(reverse('siteapi:config'), data={'company_config':\ {'name_cn': "abc", 'icon': "", 'color': "zzzzzz"}}) expect = {'company_config': {'non_field_errors': ["color invalid"]}} self.assertEqual(res.json(), expect) res = self.client.json_patch(reverse('siteapi:config'), data={'company_config':\ {'name_cn': "abc", 'icon': "", 'color': "AAFEAE"}}) self.assertEqual(res.status_code, HTTP_200_OK)