代码优化

xsign
nineven 3 years ago
parent 115d1c95df
commit d571b399d7
  1. 12
      fir_client/src/components/FirDownload.vue
  2. 20
      fir_client/src/components/FirLogin.vue
  3. 24
      fir_client/src/components/FirRegist.vue
  4. 20
      fir_client/src/components/FirResetPwd.vue
  5. 12
      fir_client/src/components/ShortDownload.vue
  6. 29
      fir_client/src/components/user/FirUserProfileCertification.vue
  7. 42
      fir_client/src/components/user/FirUserProfileInfo.vue
  8. 18
      fir_ser/admin/views/login.py
  9. 52
      fir_ser/api/utils/auth/captcha.py
  10. 25
      fir_ser/api/utils/auth/geetest.py
  11. 7
      fir_ser/api/utils/auth/mfa.py
  12. 69
      fir_ser/api/utils/auth/util.py
  13. 7
      fir_ser/api/utils/auth/weixin.py
  14. 77
      fir_ser/api/utils/utils.py
  15. 294
      fir_ser/api/views/login.py
  16. 75
      fir_ser/api/views/login_wx.py
  17. 9
      fir_ser/api/views/report.py
  18. 8
      fir_ser/common/core/sysconfig.py
  19. 106
      fir_ser/common/utils/sendmsg.py
  20. 4
      fir_ser/config.py
  21. 2
      fir_ser/xsign/utils/ctasks.py
  22. 5
      fir_ser/xsign/utils/supersignutils.py
  23. 10
      fir_ser/xsign/utils/utils.py

@ -39,7 +39,7 @@
<el-row v-if="captcha.captcha_image" style="margin-top: 10px;margin-bottom: -10px"> <el-row v-if="captcha.captcha_image" style="margin-top: 10px;margin-bottom: -10px">
<el-col :span="16"> <el-col :span="16">
<el-input v-model="report_info.authcode" clearable maxlength="6" placeholder="请输入图片验证码"/> <el-input v-model="report_info.verify_code" clearable maxlength="6" placeholder="请输入图片验证码"/>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-image <el-image
@ -368,12 +368,13 @@ export default {
data() { data() {
return { return {
captcha: {"captcha_image": '', "captcha_key": '', "length": 8}, captcha: {"captcha_image": '', "captcha_key": '', "length": 8},
auth_rules: {},
report_info: { report_info: {
'username': '', 'username': '',
'report_type': '', 'report_type': '',
'report_reason': '', 'report_reason': '',
'seicode': '', 'seicode': '',
'authcode': '', 'verify_code': '',
'email': '', 'email': '',
'auth_token': '', 'auth_token': '',
'act': 'email', 'act': 'email',
@ -482,12 +483,12 @@ export default {
} }
let picode = { let picode = {
"authcode": this.report_info.authcode, "verify_code": this.report_info.verify_code,
"captcha_key": this.captcha.captcha_key, "captcha_key": this.captcha.captcha_key,
"report": this.currentappinfo.app_id "report": this.currentappinfo.app_id
}; };
let params = {'act': this.report_info.act, 'target': this.report_info.email, 'ext': picode}; let params = {'act': this.report_info.act, 'target': this.report_info.email, 'ext': picode};
if (this.captcha.geetest) { if (this.auth_rules.geetest) {
geetest(this, this.report_info.email, params, (n_params) => { geetest(this, this.report_info.email, params, (n_params) => {
this.do_get_auth_token(n_params); this.do_get_auth_token(n_params);
}) })
@ -517,7 +518,8 @@ export default {
if (data.code === 1000) { if (data.code === 1000) {
let jdata = data.data; let jdata = data.data;
if (jdata.enable) { if (jdata.enable) {
this.captcha = data.data; this.auth_rules = data.data.auth_rules;
this.captcha = this.auth_rules.captcha;
if (data.data.s_list) { if (data.data.s_list) {
this.report_info_list = data.data.s_list; this.report_info_list = data.data.s_list;
} }

@ -44,7 +44,7 @@
<el-form-item v-if="captcha.captcha_image" style="height: 40px"> <el-form-item v-if="captcha.captcha_image" style="height: 40px">
<el-row style="height: 40px"> <el-row style="height: 40px">
<el-col :span="16"> <el-col :span="16">
<el-input v-model="form.authcode" clearable maxlength="6" <el-input v-model="form.verify_code" clearable maxlength="6"
placeholder="请输入验证码" @keyup.enter.native="onSubmit"/> placeholder="请输入验证码" @keyup.enter.native="onSubmit"/>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
@ -113,9 +113,10 @@ export default {
form: { form: {
email: '', email: '',
password: '', password: '',
authcode: '' verify_code: ''
}, },
captcha: {"captcha_image": '', "captcha_key": '', "length": 8}, captcha: {"captcha_image": '', "captcha_key": '', "length": 8},
auth_rules: {},
activeName: 'username', activeName: 'username',
allow_ways: {'third': {}}, allow_ways: {'third': {}},
rutitle: '', rutitle: '',
@ -196,7 +197,7 @@ export default {
} }
}, },
is_captcha() { is_captcha() {
let captcha_flag = this.form.authcode.length === this.captcha.length; let captcha_flag = this.form.verify_code.length === this.captcha.length;
if (this.captcha.captcha_key === '' || !this.captcha.captcha_key) { if (this.captcha.captcha_key === '' || !this.captcha.captcha_key) {
captcha_flag = true captcha_flag = true
} }
@ -205,9 +206,9 @@ export default {
onSubmit() { onSubmit() {
let email = this.form.email; let email = this.form.email;
let password = this.form.password; let password = this.form.password;
let authcode = this.form.authcode; let verify_code = this.form.verify_code;
let login_type = 'up'; let login_type = 'up';
let captcha_flag = this.form.authcode.length === this.captcha.length; let captcha_flag = this.form.verify_code.length === this.captcha.length;
if (this.captcha.captcha_key === '' || !this.captcha.captcha_key) { if (this.captcha.captcha_key === '' || !this.captcha.captcha_key) {
captcha_flag = true captcha_flag = true
} }
@ -248,12 +249,12 @@ export default {
let params = { let params = {
"username": email, "username": email,
"password": password, "password": password,
"authcode": authcode, "verify_code": verify_code,
"captcha_key": this.captcha.captcha_key, "captcha_key": this.captcha.captcha_key,
"login_type": login_type, "login_type": login_type,
}; };
this.login_disable = true; this.login_disable = true;
if (this.captcha.geetest) { if (this.auth_rules.geetest) {
geetest(this, this.form.email, params, (n_params) => { geetest(this, this.form.email, params, (n_params) => {
this.do_login(n_params); this.do_login(n_params);
}) })
@ -318,10 +319,11 @@ export default {
get_auth_code() { get_auth_code() {
loginFun(data => { loginFun(data => {
if (data.code === 1000) { if (data.code === 1000) {
this.captcha = data.data; this.auth_rules = data.data.auth_rules
this.captcha = this.auth_rules.captcha;
this.allow_ways = data.data.login_type; this.allow_ways = data.data.login_type;
this.register_enable = data.data.register_enable; this.register_enable = data.data.register_enable;
this.form.authcode = ''; this.form.verify_code = '';
this.set_rtitle(); this.set_rtitle();
this.set_activename(); this.set_activename();
} else { } else {

@ -29,7 +29,7 @@
<el-form-item v-if="captcha.captcha_image" style="height: 40px"> <el-form-item v-if="captcha.captcha_image" style="height: 40px">
<el-row style="height: 40px"> <el-row style="height: 40px">
<el-col :span="16"> <el-col :span="16">
<el-input v-model="form.authcode" clearable maxlength="6" placeholder="请输入图片验证码"/> <el-input v-model="form.verify_code" clearable maxlength="6" placeholder="请输入图片验证码"/>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-image <el-image
@ -98,7 +98,7 @@ export default {
email: '', email: '',
password: '', password: '',
password2: '', password2: '',
authcode: '', verify_code: '',
srccode: '', srccode: '',
seicode: '', seicode: '',
authtoken: '', authtoken: '',
@ -107,6 +107,7 @@ export default {
}, },
captcha: {"captcha_image": '', "captcha_key": '', "length": 8}, captcha: {"captcha_image": '', "captcha_key": '', "length": 8},
auth_rules: {},
allow_r: false, allow_r: false,
allow_ways: {}, allow_ways: {},
rutitle: '', rutitle: '',
@ -132,9 +133,10 @@ export default {
if (jdata.enable) { if (jdata.enable) {
this.allow_r = true; this.allow_r = true;
this.allow_ways = jdata.register_type; this.allow_ways = jdata.register_type;
this.form.authcode = ''; this.form.verify_code = '';
this.set_rtitle(); this.set_rtitle();
this.captcha = data.data; this.auth_rules = data.data.auth_rules;
this.captcha = this.auth_rules.captcha;
} else { } else {
this.allow_r = false; this.allow_r = false;
this.$message({ this.$message({
@ -181,19 +183,19 @@ export default {
if (checkEmail(this.form.email)) { if (checkEmail(this.form.email)) {
act = 'email' act = 'email'
} }
let authcode = this.form.authcode; let verify_code = this.form.verify_code;
let captcha_flag = authcode.length === this.captcha.length; let captcha_flag = verify_code.length === this.captcha.length;
if (this.captcha.captcha_key === '' || !this.captcha.captcha_key) { if (this.captcha.captcha_key === '' || !this.captcha.captcha_key) {
captcha_flag = true captcha_flag = true
} }
if (captcha_flag) { if (captcha_flag) {
let picode = { let picode = {
"authcode": authcode, "verify_code": verify_code,
"captcha_key": this.captcha.captcha_key, "captcha_key": this.captcha.captcha_key,
"icode": this.form.icode, "icode": this.form.icode,
}; };
let params = {'act': act, 'target': this.form.email, 'ext': picode}; let params = {'act': act, 'target': this.form.email, 'ext': picode};
if (this.captcha.geetest) { if (this.auth_rules.geetest) {
geetest(this, this.form.email, params, (n_params) => { geetest(this, this.form.email, params, (n_params) => {
this.do_get_auth_token(n_params); this.do_get_auth_token(n_params);
}) })
@ -277,8 +279,8 @@ export default {
if (!this.docheck()) { if (!this.docheck()) {
return return
} }
let authcode = this.form.authcode; let verify_code = this.form.verify_code;
let captcha_flag = authcode.length === this.captcha.length; let captcha_flag = verify_code.length === this.captcha.length;
if (this.captcha.captcha_key === '' || !this.captcha.captcha_key) { if (this.captcha.captcha_key === '' || !this.captcha.captcha_key) {
captcha_flag = true captcha_flag = true
} }
@ -292,7 +294,7 @@ export default {
"auth_key": this.form.seicode "auth_key": this.form.seicode
}; };
this.register_disable = true; this.register_disable = true;
if (this.captcha.geetest) { if (this.auth_rules.geetest) {
geetest(this, this.form.email, params, (n_params) => { geetest(this, this.form.email, params, (n_params) => {
this.do_register(n_params); this.do_register(n_params);
}) })

@ -20,7 +20,7 @@
<el-form-item v-if="captcha.captcha_image" style="height: 40px"> <el-form-item v-if="captcha.captcha_image" style="height: 40px">
<el-row style="height: 40px"> <el-row style="height: 40px">
<el-col :span="16"> <el-col :span="16">
<el-input v-model="form.authcode" clearable maxlength="6" <el-input v-model="form.verify_code" clearable maxlength="6"
placeholder="请输入验证码" @keyup.enter.native="onSubmit"/> placeholder="请输入验证码" @keyup.enter.native="onSubmit"/>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
@ -81,11 +81,12 @@ export default {
form: { form: {
email: '', email: '',
password: '', password: '',
authcode: '', verify_code: '',
seicode: '', seicode: '',
auth_token: '' auth_token: ''
}, },
captcha: {"captcha_image": '', "captcha_key": '', "length": 8}, captcha: {"captcha_image": '', "captcha_key": '', "length": 8},
auth_rules: {},
activeName: 'username', activeName: 'username',
allow_ways: {}, allow_ways: {},
rutitle: '', rutitle: '',
@ -108,7 +109,7 @@ export default {
} }
}, },
is_captcha() { is_captcha() {
let captcha_flag = this.form.authcode.length === this.captcha.length; let captcha_flag = this.form.verify_code.length === this.captcha.length;
if (this.captcha.captcha_key === '' || !this.captcha.captcha_key) { if (this.captcha.captcha_key === '' || !this.captcha.captcha_key) {
captcha_flag = true captcha_flag = true
} }
@ -116,8 +117,8 @@ export default {
}, },
onSubmit() { onSubmit() {
let email = this.form.email; let email = this.form.email;
let authcode = this.form.authcode; let verify_code = this.form.verify_code;
let captcha_flag = this.form.authcode.length === this.captcha.length; let captcha_flag = this.form.verify_code.length === this.captcha.length;
if (this.captcha.captcha_key === '' || !this.captcha.captcha_key) { if (this.captcha.captcha_key === '' || !this.captcha.captcha_key) {
captcha_flag = true captcha_flag = true
} }
@ -127,7 +128,7 @@ export default {
if (checke || checkp) { if (checke || checkp) {
let params = { let params = {
"username": email, "username": email,
"authcode": authcode, "verify_code": verify_code,
"captcha_key": this.captcha.captcha_key, "captcha_key": this.captcha.captcha_key,
"login_type": 'reset', "login_type": 'reset',
}; };
@ -140,7 +141,7 @@ export default {
params['auth_token'] = auth_token params['auth_token'] = auth_token
} }
this.login_disable = true; this.login_disable = true;
if (this.captcha.geetest) { if (this.auth_rules.geetest) {
geetest(this, this.form.email, params, (n_params) => { geetest(this, this.form.email, params, (n_params) => {
this.do_login(n_params); this.do_login(n_params);
}) })
@ -196,9 +197,10 @@ export default {
get_auth_code() { get_auth_code() {
loginFun(data => { loginFun(data => {
if (data.code === 1000) { if (data.code === 1000) {
this.captcha = data.data; this.auth_rules = data.data.auth_rules;
this.captcha = this.auth_rules.captcha;
this.register_enable = data.data.register_enable; this.register_enable = data.data.register_enable;
this.form.authcode = ''; this.form.verify_code = '';
} else { } else {
this.$message({ this.$message({
message: data.msg, message: data.msg,

@ -43,7 +43,7 @@
</div> </div>
<div class="content-row"> <div class="content-row">
<div v-if="captcha.captcha_image" class="report_captcha"> <div v-if="captcha.captcha_image" class="report_captcha">
<input v-model="report_info.authcode" maxlength="6" placeholder="请输入图片验证码" type="text"/> <input v-model="report_info.verify_code" maxlength="6" placeholder="请输入图片验证码" type="text"/>
<img :src="captcha.captcha_image" alt="验证码" @click="get_auth_code"/> <img :src="captcha.captcha_image" alt="验证码" @click="get_auth_code"/>
</div> </div>
@ -355,12 +355,13 @@ export default {
data() { data() {
return { return {
captcha: {"captcha_image": '', "captcha_key": '', "length": 8}, captcha: {"captcha_image": '', "captcha_key": '', "length": 8},
auth_rules: {},
report_info: { report_info: {
'username': '', 'username': '',
'report_type': '', 'report_type': '',
'report_reason': '', 'report_reason': '',
'seicode': '', 'seicode': '',
'authcode': '', 'verify_code': '',
'email': '', 'email': '',
'auth_token': '', 'auth_token': '',
'act': 'email', 'act': 'email',
@ -459,12 +460,12 @@ export default {
} }
let picode = { let picode = {
"authcode": this.report_info.authcode, "verify_code": this.report_info.verify_code,
"captcha_key": this.captcha.captcha_key, "captcha_key": this.captcha.captcha_key,
"report": this.currentappinfo.app_id "report": this.currentappinfo.app_id
}; };
let params = {'act': this.report_info.act, 'target': this.report_info.email, 'ext': picode}; let params = {'act': this.report_info.act, 'target': this.report_info.email, 'ext': picode};
if (this.captcha.geetest) { if (this.auth_rules.geetest) {
geetest(this, this.report_info.email, params, (n_params) => { geetest(this, this.report_info.email, params, (n_params) => {
this.do_get_auth_token(n_params); this.do_get_auth_token(n_params);
}) })
@ -487,7 +488,8 @@ export default {
if (data.code === 1000) { if (data.code === 1000) {
let jdata = data.data; let jdata = data.data;
if (jdata.enable) { if (jdata.enable) {
this.captcha = data.data; this.auth_rules = data.data.auth_rules;
this.captcha = this.auth_rules.captcha;
if (data.data.s_list) { if (data.data.s_list) {
this.report_info_list = data.data.s_list; this.report_info_list = data.data.s_list;
} }

@ -100,7 +100,7 @@
</el-form-item> </el-form-item>
<el-form-item v-if="captcha.change_type.sms" label="手机号码"> <el-form-item v-if="change_type.sms" label="手机号码">
<el-row :gutter="36"> <el-row :gutter="36">
<el-col :span="18"> <el-col :span="18">
<el-input ref="phone" v-model="form.mobile" clearable <el-input ref="phone" v-model="form.mobile" clearable
@ -111,7 +111,7 @@
<el-form-item v-if="captcha.captcha_image" label="图片验证码"> <el-form-item v-if="captcha.captcha_image" label="图片验证码">
<el-row :gutter="11"> <el-row :gutter="11">
<el-col :span="12"> <el-col :span="12">
<el-input v-model="form.authcode" clearable maxlength="6" placeholder="请输入图片验证码"/> <el-input v-model="form.verify_code" clearable maxlength="6" placeholder="请输入图片验证码"/>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-image <el-image
@ -123,7 +123,7 @@
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item v-if="captcha.change_type.sms" label="手机验证码"> <el-form-item v-if="change_type.sms" label="手机验证码">
<el-row :gutter="11"> <el-row :gutter="11">
<el-col :span="12"> <el-col :span="12">
<el-input v-model="form.auth_key" clearable maxlength="6" <el-input v-model="form.auth_key" clearable maxlength="6"
@ -232,10 +232,11 @@ export default {
captcha: { captcha: {
captcha_image: '', captcha_image: '',
captcha_key: '', captcha_key: '',
authcode: '', verify_code: '',
length: 8, length: 8,
change_type: {email: false, sms: false}
}, },
change_type: {email: false, sms: false},
auth_rules: {},
user_certification: {'one': '', 'two': '', 'three': ''}, user_certification: {'one': '', 'two': '', 'three': ''},
certification: {}, certification: {},
certification_status: 0, certification_status: 0,
@ -264,7 +265,7 @@ export default {
this.$message.error("身份证输入不合法"); this.$message.error("身份证输入不合法");
return false; return false;
} }
if (this.captcha.change_type.sms) { if (this.change_type.sms) {
let checkp = checkphone(this.form.mobile); let checkp = checkphone(this.form.mobile);
if (!checkp) { if (!checkp) {
this.$message.error("手机号输入不合法"); this.$message.error("手机号输入不合法");
@ -306,15 +307,15 @@ export default {
getsmsemailcode(act, target) { getsmsemailcode(act, target) {
let picode = { let picode = {
"authcode": this.form.authcode, "verify_code": this.form.verify_code,
"captcha_key": this.captcha.captcha_key, "captcha_key": this.captcha.captcha_key,
}; };
if (this.captcha.captcha_image) { if (this.captcha.captcha_image) {
if (!this.form.authcode) { if (!this.form.verify_code) {
this.$message.error("图片验证码输入有误"); this.$message.error("图片验证码输入有误");
return; return;
} }
let captcha_flag = this.form.authcode.length === this.captcha.length; let captcha_flag = this.form.verify_code.length === this.captcha.length;
if (this.captcha.captcha_key === '' || !this.captcha.captcha_key) { if (this.captcha.captcha_key === '' || !this.captcha.captcha_key) {
captcha_flag = true captcha_flag = true
} }
@ -331,7 +332,7 @@ export default {
} }
let params = {'act': act, 'target': target, 'ext': picode, 'user_id': target, 'ftype': 'certification'}; let params = {'act': act, 'target': target, 'ext': picode, 'user_id': target, 'ftype': 'certification'};
if (this.captcha.geetest) { if (this.auth_rules.geetest) {
geetest(this, this.form.mobile, params, (n_params) => { geetest(this, this.form.mobile, params, (n_params) => {
this.get_phone_code(n_params); this.get_phone_code(n_params);
}) })
@ -359,12 +360,14 @@ export default {
}, },
get_auth_code() { get_auth_code() {
if (this.form.authcode) { if (this.form.verify_code) {
this.form.authcode = ''; this.form.verify_code = '';
} }
changeInfoFun(data => { changeInfoFun(data => {
if (data.code === 1000) { if (data.code === 1000) {
this.captcha = data.data; this.change_type = data.data.change_type;
this.auth_rules = data.data.auth_rules;
this.captcha = this.auth_rules.captcha
if (this.captcha.captcha_key) { if (this.captcha.captcha_key) {
this.form.captcha_key = this.captcha.captcha_key; this.form.captcha_key = this.captcha.captcha_key;
} }

@ -114,7 +114,7 @@
<el-form-item label="手机号码"> <el-form-item label="手机号码">
<el-row :gutter="36"> <el-row :gutter="36">
<el-col :span="16"> <el-col :span="16">
<el-input ref="phone" v-model="userinfo.mobile" :disabled="!captcha.change_type.sms" <el-input ref="phone" v-model="userinfo.mobile" :disabled="!change_type.sms"
:readonly="editphone !== true" clearable maxlength="11" placeholder="手机" :readonly="editphone !== true" clearable maxlength="11" placeholder="手机"
prefix-icon="el-icon-mobile"/> prefix-icon="el-icon-mobile"/>
</el-col> </el-col>
@ -122,7 +122,7 @@
<el-button icon="el-icon-edit" @click="changePhoneValue"> <el-button icon="el-icon-edit" @click="changePhoneValue">
</el-button> </el-button>
</el-col> </el-col>
<el-col v-if="editphone === true && captcha.change_type.sms" :span="5"> <el-col v-if="editphone === true && change_type.sms" :span="5">
<el-button class="save-button" plain type="success" <el-button class="save-button" plain type="success"
@click="savePhone"> @click="savePhone">
保存 保存
@ -131,11 +131,11 @@
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item v-if="editphone === true && captcha.captcha_image && captcha.change_type.sms" label="图片验证码" <el-form-item v-if="editphone === true && captcha.captcha_image && change_type.sms" label="图片验证码"
style="height: 40px"> style="height: 40px">
<el-row :gutter="36" style="height: 40px"> <el-row :gutter="36" style="height: 40px">
<el-col :span="14"> <el-col :span="14">
<el-input v-model="userinfo.authcode" clearable maxlength="6" placeholder="请输入图片验证码"/> <el-input v-model="userinfo.verify_code" clearable maxlength="6" placeholder="请输入图片验证码"/>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-image <el-image
@ -147,7 +147,7 @@
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item v-if="editphone === true && captcha.change_type.sms" label="手机验证码"> <el-form-item v-if="editphone === true && change_type.sms" label="手机验证码">
<el-row :gutter="36"> <el-row :gutter="36">
<el-col :span="16"> <el-col :span="16">
<el-input v-model="userinfo.auth_key" clearable maxlength="6" <el-input v-model="userinfo.auth_key" clearable maxlength="6"
@ -167,7 +167,7 @@
<el-form-item label="邮箱地址"> <el-form-item label="邮箱地址">
<el-row :gutter="36"> <el-row :gutter="36">
<el-col :span="16"> <el-col :span="16">
<el-input ref="email" v-model="userinfo.email" :disabled="!captcha.change_type.email" <el-input ref="email" v-model="userinfo.email" :disabled="!change_type.email"
:readonly="editemail !== true" clearable maxlength="20" placeholder="邮箱" :readonly="editemail !== true" clearable maxlength="20" placeholder="邮箱"
prefix-icon="el-icon-bank-card"/> prefix-icon="el-icon-bank-card"/>
</el-col> </el-col>
@ -175,7 +175,7 @@
<el-button icon="el-icon-edit" @click="changeemailValue"> <el-button icon="el-icon-edit" @click="changeemailValue">
</el-button> </el-button>
</el-col> </el-col>
<el-col v-if="editemail === true && captcha.change_type.email" :span="5"> <el-col v-if="editemail === true && change_type.email" :span="5">
<el-button class="save-button" plain type="success" <el-button class="save-button" plain type="success"
@click="saveemail"> @click="saveemail">
保存 保存
@ -185,11 +185,11 @@
</el-form-item> </el-form-item>
<el-form-item v-if="editemail === true && captcha.captcha_image && captcha.change_type.email" label="图片验证码" <el-form-item v-if="editemail === true && captcha.captcha_image && change_type.email" label="图片验证码"
style="height: 40px"> style="height: 40px">
<el-row :gutter="36" style="height: 40px"> <el-row :gutter="36" style="height: 40px">
<el-col :span="14"> <el-col :span="14">
<el-input v-model="userinfo.authcode" clearable maxlength="6" placeholder="请输入图片验证码"/> <el-input v-model="userinfo.verify_code" clearable maxlength="6" placeholder="请输入图片验证码"/>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-image <el-image
@ -201,7 +201,7 @@
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item v-if="editemail === true && captcha.change_type.email" label="邮箱验证码"> <el-form-item v-if="editemail === true && change_type.email" label="邮箱验证码">
<el-row :gutter="36"> <el-row :gutter="36">
<el-col :span="16"> <el-col :span="16">
<el-input v-model="userinfo.auth_key" clearable maxlength="6" <el-input v-model="userinfo.auth_key" clearable maxlength="6"
@ -295,7 +295,7 @@ export default {
return { return {
userinfo: { userinfo: {
srccode: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg', srccode: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
authcode: '' verify_code: ''
}, },
orguserinfo: {}, orguserinfo: {},
editphone: false, editphone: false,
@ -303,7 +303,9 @@ export default {
editdomain_name: false, editdomain_name: false,
edituser_name: false, edituser_name: false,
editposition: false, editposition: false,
captcha: {"captcha_image": '', "captcha_key": '', "length": 8, change_type: {email: false, sms: false}}, captcha: {"captcha_image": '', "captcha_key": '', "length": 8},
change_type: {email: false, sms: false},
auth_rules: {},
form: {}, form: {},
wx_login_qr_url: '', wx_login_qr_url: '',
wx_visible: false, wx_visible: false,
@ -419,10 +421,12 @@ export default {
get_auth_code() { get_auth_code() {
changeInfoFun(data => { changeInfoFun(data => {
if (data.code === 1000) { if (data.code === 1000) {
this.captcha = data.data; this.auth_rules = data.data.auth_rules;
this.captcha = this.auth_rules.captcha;
this.change_type = data.data.change_type;
this.userinfo.captcha_key = this.captcha.captcha_key; this.userinfo.captcha_key = this.captcha.captcha_key;
if (this.userinfo.authcode) { if (this.userinfo.verify_code) {
this.userinfo.authcode = ''; this.userinfo.verify_code = '';
} }
} else { } else {
this.$message({ this.$message({
@ -457,7 +461,7 @@ export default {
auth_token: this.userinfo.auth_token, auth_token: this.userinfo.auth_token,
auth_key: this.userinfo.auth_key, auth_key: this.userinfo.auth_key,
captcha_key: this.userinfo.captcha_key, captcha_key: this.userinfo.captcha_key,
authcode: this.userinfo.authcode, verify_code: this.userinfo.verify_code,
}; };
}, },
saveemail() { saveemail() {
@ -564,14 +568,14 @@ export default {
}, },
getsmsemailcode(act, target) { getsmsemailcode(act, target) {
let picode = { let picode = {
"authcode": this.userinfo.authcode, "verify_code": this.userinfo.verify_code,
"captcha_key": this.captcha.captcha_key, "captcha_key": this.captcha.captcha_key,
}; };
let params = { let params = {
'act': act, 'target': target, 'ext': picode 'act': act, 'target': target, 'ext': picode
}; };
if (this.captcha.geetest) { if (this.auth_rules.geetest) {
geetest(this, this.form.email, target, params, (n_params) => { geetest(this, target, params, (n_params) => {
this.do_get_auth_token(n_params); this.do_get_auth_token(n_params);
}) })
} else { } else {

@ -9,8 +9,9 @@ import logging
from django.contrib import auth from django.contrib import auth
from rest_framework.views import APIView from rest_framework.views import APIView
from api.utils.auth.util import AuthInfo
from api.utils.serializer import UserInfoSerializer from api.utils.serializer import UserInfoSerializer
from api.utils.utils import get_captcha, valid_captcha, set_user_token from api.utils.utils import set_user_token
from common.core.auth import ExpiringTokenAuthentication from common.core.auth import ExpiringTokenAuthentication
from common.core.response import ApiResponse from common.core.response import ApiResponse
from common.core.sysconfig import Config from common.core.sysconfig import Config
@ -29,11 +30,11 @@ class LoginView(APIView):
code = 1000 code = 1000
msg = 'success' msg = 'success'
data = None data = None
if Config.LOGIN.get("captcha"): # if Config.LOGIN.get("captcha"):
is_valid = valid_captcha(receive.get("captcha_key", None), receive.get("authcode", None), username) # is_valid = valid_captcha(receive.get("captcha_key", None), receive.get("verify_code", None), username)
else: # else:
is_valid = True # is_valid = True
if is_valid: if True:
if login_auth_failed("get", username): if login_auth_failed("get", username):
password = receive.get("password") password = receive.get("password")
user = auth.authenticate(username=username, password=password) user = auth.authenticate(username=username, password=password)
@ -68,9 +69,8 @@ class LoginView(APIView):
return ApiResponse(code=code, msg=msg, data=data) return ApiResponse(code=code, msg=msg, data=data)
def get(self, request): def get(self, request):
data = {} auth_obj = AuthInfo(Config.LOGIN.get("captcha"), False)
if Config.LOGIN.get("captcha"): data = auth_obj.make_rules_info()
data = get_captcha()
return ApiResponse(data=data) return ApiResponse(data=data)

@ -0,0 +1,52 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author: liuyu
# date: 2022/2/7
import logging
from captcha.helpers import captcha_image_url
from captcha.models import CaptchaStore
from common.core.sysconfig import Config
from common.libs.storage.localApi import LocalStorage
logger = logging.getLogger(__name__)
class CaptchaAuth(object):
def __init__(self, captcha_key='', g_type=1):
self.g_type = g_type
self.captcha_key = captcha_key
self.random_char_fun = self.__generator()
def __generator(self):
if self.g_type == 1:
# 随机字符串
return 'captcha.helpers.random_char_challenge'
elif self.g_type == 2:
# 数学运算
return 'captcha.helpers.math_challenge'
return None
def __get_captcha_obj(self):
return CaptchaStore.objects.filter(hashkey=self.captcha_key).first()
def generate(self):
self.captcha_key = CaptchaStore.generate_key(self.random_char_fun)
captcha_image = captcha_image_url(self.captcha_key)
captcha_obj = self.__get_captcha_obj()
code_length = 0
if captcha_obj:
code_length = len(captcha_obj.response)
local_storage = LocalStorage(**Config.IOS_PMFILE_DOWNLOAD_DOMAIN)
return {"captcha_image": "/".join([local_storage.get_base_url(), captcha_image.strip("/"), '']),
"captcha_key": self.captcha_key,
"length": code_length}
def valid(self, verify_code):
captcha_obj = self.__get_captcha_obj()
logger.info(f"captcha_key:{self.captcha_key} verify_code:{verify_code} challenge:{captcha_obj}")
if captcha_obj:
if self.captcha_key and verify_code and verify_code.strip(" ").lower() == captcha_obj.response.lower():
return True
return False

@ -0,0 +1,25 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author: liuyu
# date: 2022/2/7
import hashlib
import logging
from common.libs.geetest.geetest_utils import first_register, second_validate
logger = logging.getLogger(__name__)
class GeeTestAuth(object):
def __init__(self, unique_key='', ip_address=''):
self.ip_address = ip_address
self.unique_key = unique_key
def generate(self):
assert self.unique_key
assert self.ip_address
sha = hashlib.sha1(str(self.unique_key).encode("utf-8"))
return first_register(sha.hexdigest(), self.ip_address)
def valid(self, geetest_data):
return second_validate(geetest_data).get("result", "") == "success"

@ -0,0 +1,7 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author: liuyu
# date: 2022/2/7
import logging
logger = logging.getLogger(__name__)

@ -0,0 +1,69 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author: liuyu
# date: 2022/2/7
import logging
from api.utils.auth.captcha import CaptchaAuth
from api.utils.auth.geetest import GeeTestAuth
logger = logging.getLogger(__name__)
"""
验证流程
微信公众号验证码短信验证码邮件验证码
图片验证码mfa验证最后将数据通过geetest验证发送到后台进验证
"""
class AuthInfo(object):
def __init__(self, captcha=False, geetest=False):
"""
{
"captcha": True, # 是否开启注册字母验证码
"geetest": False, # 是否开启geetest验证,如要开启请先配置geetest
}
"""
self.captcha = captcha
self.geetest = geetest
def make_rules_info(self):
data = {}
if self.captcha:
data['captcha'] = CaptchaAuth().generate()
if self.geetest:
data['geetest'] = True
return data
def make_geetest_info(self, unique_key='', ip_address=''):
if self.geetest:
return GeeTestAuth(unique_key, ip_address).generate()
return {}
def valid(self, data):
if self.captcha:
captcha_key = data.get("captcha_key", '')
verify_code = data.get("verify_code", '')
is_valid = CaptchaAuth(captcha_key=captcha_key).valid(verify_code)
if not is_valid:
return False, '验证码有误'
if self.geetest:
"""
"geetest_challenge" # 极验二次验证表单传参字段 chllenge
"geetest_validate" # 极验二次验证表单传参字段 validate
"geetest_seccode" # 极验二次验证表单传参字段 seccode
"""
geetest = data.get("geetest", {})
is_valid = GeeTestAuth().valid(geetest)
# geetest_data = {
# "geetest_challenge": geetest.get("geetest_challenge"),
# "geetest_validate": geetest.get("geetest_validate"),
# "geetest_seccode": geetest.get("geetest_seccode")
# }
# is_valid = GeeTestAuth().valid(geetest_data)
if not is_valid:
return False, '滑动验证有误'
return True, '验证通过'

@ -0,0 +1,7 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author: liuyu
# date: 2022/2/7
import logging
logger = logging.getLogger(__name__)

@ -8,52 +8,22 @@ import datetime
import logging import logging
import os import os
from captcha.helpers import captcha_image_url
from captcha.models import CaptchaStore
from django.core.cache import cache from django.core.cache import cache
from api.models import UserInfo, AppReleaseInfo, AppScreenShot, Token, UserAdDisplayInfo from api.models import UserInfo, AppReleaseInfo, AppScreenShot, Token, UserAdDisplayInfo
from api.utils.modelutils import get_app_d_count_by_app_id from api.utils.modelutils import get_app_d_count_by_app_id
from common.base.baseutils import get_real_ip_address from common.base.baseutils import get_real_ip_address
from common.cache.storage import UserTokenCache, TempCache from common.cache.storage import UserTokenCache
from common.core.signals import xsign_migrate_data_signal, xsign_clean_data_signal from common.core.signals import xsign_migrate_data_signal, xsign_clean_data_signal
from common.core.sysconfig import Config
from common.libs.storage.localApi import LocalStorage from common.libs.storage.localApi import LocalStorage
from common.utils.caches import consume_user_download_times from common.utils.caches import consume_user_download_times
from common.utils.sendmsg import SendMessage
from common.utils.storage import Storage from common.utils.storage import Storage
from common.utils.token import generate_numeric_token_of_length, generate_alphanumeric_token_of_length, make_token, \ from common.utils.token import generate_alphanumeric_token_of_length
verify_token
from fir_ser.settings import MEDIA_ROOT from fir_ser.settings import MEDIA_ROOT
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def get_captcha():
# 随机字符串
random_char_fun = 'captcha.helpers.random_char_challenge'
# 数学运算
math_fun = 'captcha.helpers.math_challenge'
captcha_key = CaptchaStore.generate_key(random_char_fun)
captcha_image = captcha_image_url(captcha_key)
local_storage = LocalStorage(**Config.IOS_PMFILE_DOWNLOAD_DOMAIN)
return {"captcha_image": "/".join([local_storage.get_base_url(), captcha_image.strip("/"), '']),
"captcha_key": captcha_key,
"length": len(CaptchaStore.objects.filter(hashkey=captcha_key).first().response)}
def valid_captcha(captcha_key, code, username):
if username:
captcha_obj = CaptchaStore.objects.filter(hashkey=captcha_key).values("response").first()
logger.info(f"captcha_key:{captcha_key} code:{code} challenge:{captcha_obj}")
if captcha_obj:
if captcha_key and code and code.strip(" ").lower() == captcha_obj.get("response").lower():
return True
return False
def upload_oss_default_head_img(user_obj, storage_obj): def upload_oss_default_head_img(user_obj, storage_obj):
head_img_full_path = os.path.join(MEDIA_ROOT, "head_img.jpeg") head_img_full_path = os.path.join(MEDIA_ROOT, "head_img.jpeg")
if storage_obj: if storage_obj:
@ -61,40 +31,6 @@ def upload_oss_default_head_img(user_obj, storage_obj):
return storage_obj.upload_file(head_img_full_path) return storage_obj.upload_file(head_img_full_path)
def get_sender_token(sender, user_id, target, action, msg=None):
code = generate_numeric_token_of_length(6)
if msg:
code = msg
token = make_token(code, time_limit=300, key=user_id)
TempCache(user_id, token).set_storage_cache(target, 60 * 5)
if action in ('change', 'password', 'register', 'login', 'common'):
sender.send_msg_by_act(target, code, action)
elif action == 'msg':
sender.send_email_msg(target, msg)
else:
logger.error(f"get_sender_token failed. action is {action}")
return None, None
return token, code
def get_sender_sms_token(key, phone, action, msg=None):
sender = SendMessage('sms')
if sender.sender:
return get_sender_token(sender, key, phone, action, msg)
return False, False
def is_valid_sender_code(key, token, code, success_once=False):
return verify_token(token, code, success_once), TempCache(key, token).get_storage_cache()
def get_sender_email_token(key, email, action, msg=None):
sender = SendMessage('email')
if sender.sender:
return get_sender_token(sender, key, email, action, msg)
return False, False
def check_username_exists(username): def check_username_exists(username):
user_obj = UserInfo.objects.filter(username=username).values("username").first() user_obj = UserInfo.objects.filter(username=username).values("username").first()
if user_obj and user_obj['username'] == username: if user_obj and user_obj['username'] == username:
@ -109,15 +45,6 @@ def get_random_username(length=16):
return username return username
def send_ios_developer_active_status(user_info, msg):
act = 'email'
email = user_info.email
if email:
get_sender_email_token(act, email, 'msg', msg)
else:
logger.warning(f"user {user_info} has no email. so {msg} can't send!")
def get_filename_from_apptype(filename, apptype): def get_filename_from_apptype(filename, apptype):
if apptype == 0: if apptype == 0:
filename = filename + '.apk' filename = filename + '.apk'

@ -5,20 +5,19 @@ from rest_framework.response import Response
from rest_framework.views import APIView from rest_framework.views import APIView
from api.models import UserInfo, UserCertificationInfo, CertificationInfo, Apps from api.models import UserInfo, UserCertificationInfo, CertificationInfo, Apps
from api.utils.auth.util import AuthInfo
from api.utils.modelutils import get_min_default_domain_cname_obj, add_remote_info_from_request from api.utils.modelutils import get_min_default_domain_cname_obj, add_remote_info_from_request
from api.utils.response import BaseResponse from api.utils.response import BaseResponse
from api.utils.serializer import UserInfoSerializer, CertificationSerializer, UserCertificationSerializer from api.utils.serializer import UserInfoSerializer, CertificationSerializer, UserCertificationSerializer
from api.utils.utils import get_captcha, valid_captcha, \ from api.utils.utils import get_random_username, check_username_exists, set_user_token, clean_user_token_and_cache
get_sender_sms_token, is_valid_sender_code, get_sender_email_token, get_random_username, \
check_username_exists, set_user_token, clean_user_token_and_cache
from common.base.baseutils import is_valid_phone, is_valid_email, get_real_ip_address from common.base.baseutils import is_valid_phone, is_valid_email, get_real_ip_address
from common.core.auth import ExpiringTokenAuthentication from common.core.auth import ExpiringTokenAuthentication
from common.core.sysconfig import Config from common.core.sysconfig import Config
from common.core.throttle import VisitRegister1Throttle, VisitRegister2Throttle, GetAuthC1Throttle, GetAuthC2Throttle from common.core.throttle import VisitRegister1Throttle, VisitRegister2Throttle, GetAuthC1Throttle, GetAuthC2Throttle
from common.libs.geetest.geetest_utils import first_register, second_validate
from common.libs.mp.wechat import make_wx_login_qrcode, show_qrcode_url from common.libs.mp.wechat import make_wx_login_qrcode, show_qrcode_url
from common.utils.caches import login_auth_failed, set_wx_ticket_login_info_cache, get_wx_ticket_login_info_cache, \ from common.utils.caches import login_auth_failed, set_wx_ticket_login_info_cache, get_wx_ticket_login_info_cache, \
new_user_download_times_gift new_user_download_times_gift
from common.utils.sendmsg import get_sender_sms_token, is_valid_sender_code, get_sender_email_token
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -251,130 +250,117 @@ class LoginView(APIView):
response = BaseResponse() response = BaseResponse()
receive = request.data receive = request.data
username = receive.get("username", None) username = receive.get("username", None)
if Config.LOGIN.get("captcha"): auth_obj = AuthInfo(Config.LOGIN.get("captcha"), Config.LOGIN.get("geetest"))
is_valid = valid_captcha(receive.get("captcha_key", None), receive.get("authcode", None), username) is_valid, msg = auth_obj.valid(receive)
else: if not is_valid or username is None:
is_valid = True response.code = 1001
if is_valid: response.msg = msg
if Config.LOGIN.get("geetest"): return Response(response.dict)
geetest = receive.get("geetest", None)
if geetest and second_validate(geetest).get("result", "") == "success":
pass
else:
response.code = 1001
response.msg = "geetest 验证有误"
return Response(response.dict)
login_type = receive.get("login_type", None) login_type = receive.get("login_type", None)
seicode = receive.get("seicode", None) seicode = receive.get("seicode", None)
if login_auth_failed("get", username): if login_auth_failed("get", username):
if login_type == 'reset': if login_type == 'reset':
user1_obj = None user1_obj = None
user2_obj = None user2_obj = None
act = None act = None
if is_valid_email(username): if is_valid_email(username):
user1_obj = UserInfo.objects.filter(email=username).first() user1_obj = UserInfo.objects.filter(email=username).first()
act = "email" act = "email"
if is_valid_phone(username): if is_valid_phone(username):
user2_obj = UserInfo.objects.filter(mobile=username).first() user2_obj = UserInfo.objects.filter(mobile=username).first()
act = "sms" act = "sms"
if user1_obj or user2_obj: if user1_obj or user2_obj:
user_obj = user1_obj if user1_obj else user2_obj user_obj = user1_obj if user1_obj else user2_obj
password = get_random_username()[:16] password = get_random_username()[:16]
if login_auth_failed("get", user_obj.uid): if login_auth_failed("get", user_obj.uid):
login_auth_failed("set", user_obj.uid) login_auth_failed("set", user_obj.uid)
if seicode: if seicode:
is_valid, target = is_valid_sender_code(act, receive.get("auth_token", None), seicode) is_valid, target = is_valid_sender_code(act, receive.get("auth_token", None), seicode)
if is_valid and str(target) == str(username): if is_valid and str(target) == str(username):
if user2_obj: if user2_obj:
a, b = get_sender_sms_token('sms', username, 'password', password) a, b = get_sender_sms_token('sms', username, 'password', password)
else:
a, b = get_sender_email_token('email', username, 'password', password)
if a and b:
reset_user_pwd(user_obj, password)
login_auth_failed("del", username)
msg = f'{user_obj} 找回密码成功,您的新密码为 {password} 请用新密码登录之后,及时修改密码'
add_remote_info_from_request(request, msg)
logger.warning(f'{user_obj} 找回密码成功,您的新密码为 {password} 请用新密码登录之后,及时修改密码')
else:
response.code = 1007
response.msg = "密码重置失败,请稍后重试或者联系管理员"
else: else:
response.code = 1009 a, b = get_sender_email_token('email', username, 'password', password)
response.msg = "验证码有误,请检查或者重新尝试" if a and b:
reset_user_pwd(user_obj, password)
login_auth_failed("del", username)
msg = f'{user_obj} 找回密码成功,您的新密码为 {password} 请用新密码登录之后,及时修改密码'
add_remote_info_from_request(request, msg)
logger.warning(f'{user_obj} 找回密码成功,您的新密码为 {password} 请用新密码登录之后,及时修改密码')
else:
response.code = 1007
response.msg = "密码重置失败,请稍后重试或者联系管理员"
else: else:
res = check_register_userinfo(username, act, 'change', 'reset') response.code = 1009
return Response(res.dict) response.msg = "验证码有误,请检查或者重新尝试"
else: else:
response.code = 1008 res = check_register_userinfo(username, act, 'change', 'reset')
response.msg = "手机或者邮箱已经超过最大发送,请24小时后重试" return Response(res.dict)
else:
response.code = 1002
response.msg = "邮箱或者手机号不存在"
return Response(response.dict)
password = receive.get("password")
user = get_authenticate(username, password, login_type, get_login_type())
logger.info(f"username:{username} password:{password}")
if user:
if user.is_active:
login_auth_failed("del", username)
# update the token
key, user_info = set_user_token(user, request)
serializer = UserInfoSerializer(user_info, )
data = serializer.data
response.msg = "验证成功!"
response.userinfo = data
response.token = key
add_remote_info_from_request(request, f"登录成功, token: {key}")
else: else:
response.msg = "用户被禁用" response.code = 1008
response.code = 1005 response.msg = "手机或者邮箱已经超过最大发送,请24小时后重试"
else: else:
login_auth_failed("set", username)
#
# try:
# UserInfo.objects.get(username=username)
response.msg = "密码账户有误或用户被禁用"
response.code = 1002 response.code = 1002
# except UserInfo.DoesNotExist: response.msg = "邮箱或者手机号不存在"
# response.msg = "用户不存在!" return Response(response.dict)
# response.code = 1003
password = receive.get("password")
user = get_authenticate(username, password, login_type, get_login_type())
logger.info(f"username:{username} password:{password}")
if user:
if user.is_active:
login_auth_failed("del", username)
# update the token
key, user_info = set_user_token(user, request)
serializer = UserInfoSerializer(user_info, )
data = serializer.data
response.msg = "验证成功!"
response.userinfo = data
response.token = key
add_remote_info_from_request(request, f"登录成功, token: {key}")
else:
response.msg = "用户被禁用"
response.code = 1005
else: else:
response.code = 1006 login_auth_failed("set", username)
logger.error(f"username:{username} failed too try , locked") #
response.msg = "用户登录失败次数过多,已被锁定,请1小时之后再次尝试" # try:
# UserInfo.objects.get(username=username)
response.msg = "密码账户有误或用户被禁用"
response.code = 1002
# except UserInfo.DoesNotExist:
# response.msg = "用户不存在!"
# response.code = 1003
else: else:
response.code = 1001 response.code = 1006
response.msg = "验证码有误" logger.error(f"username:{username} failed too try , locked")
response.msg = "用户登录失败次数过多,已被锁定,请1小时之后再次尝试"
add_remote_info_from_request(request, response.msg) add_remote_info_from_request(request, response.msg)
return Response(response.dict) return Response(response.dict)
def get(self, request): def get(self, request):
response = BaseResponse() response = BaseResponse()
response.data = {} response.data = {}
if Config.LOGIN.get("captcha"): auth_obj = AuthInfo(Config.LOGIN.get("captcha"), Config.LOGIN.get("geetest"))
response.data = get_captcha() response.data['auth_rules'] = auth_obj.make_rules_info()
if Config.LOGIN.get("geetest"):
response.data['geetest'] = True
response.data['login_type'] = get_login_type() response.data['login_type'] = get_login_type()
allow_f = Config.REGISTER.get("enable") allow_f = Config.REGISTER.get("enable")
response.data['register_enable'] = allow_f response.data['register_enable'] = allow_f
return Response(response.dict) return Response(response.dict)
def put(self, request): def put(self, request):
import hashlib
response = BaseResponse() response = BaseResponse()
user_id = request.data.get('user_id', None) user_id = request.data.get('user_id', None)
if user_id: if user_id:
sha = hashlib.sha1(str(user_id).encode("utf-8")) auth_obj = AuthInfo(Config.LOGIN.get("captcha"), Config.LOGIN.get("geetest"))
response.data = first_register(sha.hexdigest(), request.META.get('REMOTE_ADDR')) response.data = auth_obj.make_geetest_info(user_id, request.META.get('REMOTE_ADDR'))
else: else:
response.code = 1002 response.code = 1002
response.msg = '参数错误' response.msg = '参数错误'
@ -404,14 +390,12 @@ class RegistView(APIView):
response.msg = "不允许该类型注册" response.msg = "不允许该类型注册"
return Response(response.dict) return Response(response.dict)
if Config.REGISTER.get("geetest"): auth_obj = AuthInfo(Config.REGISTER.get("captcha"), Config.REGISTER.get("geetest"))
geetest = request.data.get("geetest", None) is_valid, msg = auth_obj.valid(request.data)
if geetest and second_validate(geetest).get("result", "") == "success": if not is_valid:
pass response.code = 1001
else: response.msg = msg
response.code = 1018 return Response(response.dict)
response.msg = "geetest验证有误"
return Response(response.dict)
is_valid, target = is_valid_sender_code(act, receive.get("auth_token", None), receive.get("auth_key", None)) is_valid, target = is_valid_sender_code(act, receive.get("auth_token", None), receive.get("auth_key", None))
if is_valid and str(target) == str(username): if is_valid and str(target) == str(username):
@ -460,10 +444,8 @@ class RegistView(APIView):
response.data = {} response.data = {}
allow_f = Config.REGISTER.get("enable") allow_f = Config.REGISTER.get("enable")
if allow_f: if allow_f:
if Config.REGISTER.get("captcha"): auth_obj = AuthInfo(Config.REGISTER.get("captcha"), Config.REGISTER.get("geetest"))
response.data = get_captcha() response.data['auth_rules'] = auth_obj.make_rules_info()
if Config.REGISTER.get("geetest"):
response.data['geetest'] = True
response.data['register_type'] = get_register_type() response.data['register_type'] = get_register_type()
response.data['enable'] = allow_f response.data['enable'] = allow_f
return Response(response.dict) return Response(response.dict)
@ -510,12 +492,13 @@ class UserInfoView(APIView):
mobile = data.get("mobile", None) mobile = data.get("mobile", None)
email = data.get("email", None) email = data.get("email", None)
if mobile or email: if mobile or email:
if Config.CHANGER.get('captcha'):
is_valid = valid_captcha(data.get("captcha_key", None), data.get("authcode", None), request) auth_obj = AuthInfo(Config.CHANGER.get("captcha"), False)
if not is_valid: is_valid, msg = auth_obj.valid(data)
res.code = 1008 if not is_valid:
res.msg = "图片验证码异常" res.code = 1001
return Response(res.dict) res.msg = msg
return Response(res.dict)
if old_password and sure_password: if old_password and sure_password:
user = auth.authenticate(username=request.user.username, password=old_password) user = auth.authenticate(username=request.user.username, password=old_password)
@ -624,23 +607,14 @@ class AuthorizationView(APIView):
else: else:
p_data = Config.REGISTER p_data = Config.REGISTER
if p_data.get("captcha"): auth_obj = AuthInfo(p_data.get("captcha"), p_data.get("geetest"))
is_valid = valid_captcha(ext.get("captcha_key", None), ext.get("authcode", None), target) auth_data = {'geetest': request.data.get("geetest", None)}
if ext and is_valid: auth_data.update(ext)
pass is_valid, msg = auth_obj.valid(auth_data)
else: if not is_valid:
res.code = 1018 res.code = 1001
res.msg = "图片验证码有误" res.msg = msg
return Response(res.dict) return Response(res.dict)
if p_data.get("geetest"):
geetest = request.data.get("geetest", None)
if geetest and second_validate(geetest).get("result", "") == "success":
pass
else:
res.code = 1018
res.msg = "geetest验证有误"
return Response(res.dict)
if ext and ext.get('report'): if ext and ext.get('report'):
app_obj = Apps.objects.filter(app_id=ext.get('report')).first() app_obj = Apps.objects.filter(app_id=ext.get('report')).first()
if app_obj: if app_obj:
@ -666,22 +640,15 @@ class ChangeAuthorizationView(APIView):
target = request.data.get("target", None) target = request.data.get("target", None)
ext = request.data.get("ext", None) ext = request.data.get("ext", None)
f_type = request.data.get("ftype", None) f_type = request.data.get("ftype", None)
if Config.REGISTER.get("captcha"):
if ext and valid_captcha(ext.get("captcha_key", None), ext.get("authcode", None), target):
pass
else:
res.code = 1009
res.msg = "图片验证码有误"
return Response(res.dict)
if Config.REGISTER.get("geetest"): auth_obj = AuthInfo(Config.REGISTER.get("captcha"), Config.REGISTER.get("geetest"))
geetest = request.data.get("geetest", None) auth_data = {'geetest': request.data.get("geetest", None)}
if geetest and second_validate(geetest).get("result", "") == "success": auth_data.update(ext)
pass is_valid, msg = auth_obj.valid(auth_data)
else: if not is_valid or target is None:
res.code = 1018 res.code = 1001
res.msg = "geetest验证有误" res.msg = msg
return Response(res.dict) return Response(res.dict)
res = check_change_userinfo(target, act, 'change', request.user, f_type) res = check_change_userinfo(target, act, 'change', request.user, f_type)
return Response(res.dict) return Response(res.dict)
@ -754,15 +721,14 @@ class CertificationView(APIView):
return Response(res.dict) return Response(res.dict)
try: try:
if Config.CHANGER.get("captcha"): auth_obj = AuthInfo(Config.CHANGER.get("captcha"), False)
if data and valid_captcha(data.get("captcha_key", None), data.get("authcode", None), is_valid, msg = auth_obj.valid(data)
data.get("mobile")): if not is_valid or not data.get("mobile"):
del data["captcha_key"] res.code = 1001
del data["authcode"] res.msg = msg
else: return Response(res.dict)
res.code = 1009 del data["captcha_key"]
res.msg = "图片验证码有误" del data["verify_code"]
return Response(res.dict)
if Config.CHANGER.get('change_type').get('sms'): if Config.CHANGER.get('change_type').get('sms'):
is_valid, target = is_valid_sender_code('sms', data.get("auth_token", None), data.get("auth_key", None)) is_valid, target = is_valid_sender_code('sms', data.get("auth_token", None), data.get("auth_key", None))
if is_valid and str(target) == str(data.get("mobile")): if is_valid and str(target) == str(data.get("mobile")):
@ -809,10 +775,8 @@ class ChangeInfoView(APIView):
response.data = {} response.data = {}
allow_f = Config.CHANGER.get("enable") allow_f = Config.CHANGER.get("enable")
if allow_f: if allow_f:
if Config.CHANGER.get("captcha"): auth_obj = AuthInfo(Config.CHANGER.get("captcha"), Config.CHANGER.get("geetest"))
response.data = get_captcha() response.data['auth_rules'] = auth_obj.make_rules_info()
if Config.CHANGER.get("geetest"):
response.data['geetest'] = True
response.data['change_type'] = Config.CHANGER.get("change_type") response.data['change_type'] = Config.CHANGER.get("change_type")
response.data['enable'] = allow_f response.data['enable'] = allow_f
return Response(response.dict) return Response(response.dict)

@ -0,0 +1,75 @@
import logging
from rest_framework.response import Response
from rest_framework.views import APIView
from api.models import UserInfo
from api.utils.response import BaseResponse
from api.utils.serializer import UserInfoSerializer
from api.utils.utils import set_user_token
from common.base.baseutils import get_real_ip_address
from common.core.throttle import VisitRegister1Throttle, VisitRegister2Throttle
from common.libs.mp.wechat import make_wx_login_qrcode, show_qrcode_url
from common.utils.caches import set_wx_ticket_login_info_cache, get_wx_ticket_login_info_cache
logger = logging.getLogger(__name__)
def wx_qr_code_response(ret, code, qr_info, ip_addr):
if code:
logger.info(f"微信登录码获取成功, {qr_info}")
errmsg = qr_info.get('errmsg')
if errmsg:
ret.code = 1003
ret.msg = "微信登录码获取失败,请稍后"
else:
ticket = qr_info.get('ticket')
if ticket:
set_wx_ticket_login_info_cache(ticket, {'ip_addr': ip_addr})
ret.data = {'qr': show_qrcode_url(ticket), 'ticket': ticket}
else:
ret.code = 1003
ret.msg = "微信登录码获取失败,请稍后"
return Response(ret.dict)
class WeChatLoginView(APIView):
throttle_classes = [VisitRegister1Throttle, VisitRegister2Throttle]
def get(self, request):
ret = BaseResponse()
if get_login_type().get('third', '').get('wxp'):
code, qr_info = make_wx_login_qrcode()
return wx_qr_code_response(ret, code, qr_info, get_real_ip_address(request))
return Response(ret.dict)
class WeChatLoginCheckView(APIView):
def post(self, request):
ret = BaseResponse()
if not get_login_type().get('third', '').get('wxp'):
return Response(ret.dict)
ticket = request.data.get("ticket")
if ticket:
wx_ticket_data = get_wx_ticket_login_info_cache(ticket)
if wx_ticket_data and wx_ticket_data.get('pk'):
if wx_ticket_data.get('pk', -1) == -1:
ret.msg = "还未绑定用户,请通过手机或者邮箱登录账户之后进行绑定"
ret.code = 1005
else:
user = UserInfo.objects.filter(pk=wx_ticket_data['pk']).first()
if user.is_active:
key, user_info = set_user_token(user, request)
serializer = UserInfoSerializer(user_info)
data = serializer.data
ret.msg = "验证成功!"
ret.userinfo = data
ret.token = key
else:
ret.msg = "用户被禁用"
ret.code = 1005
else:
ret.code = 1006
else:
ret.code = 1006
return Response(ret.dict)

@ -9,14 +9,15 @@ from rest_framework.response import Response
from rest_framework.views import APIView from rest_framework.views import APIView
from api.models import Apps, AppReportInfo from api.models import Apps, AppReportInfo
from api.utils.auth.util import AuthInfo
from api.utils.modelutils import add_remote_info_from_request from api.utils.modelutils import add_remote_info_from_request
from api.utils.response import BaseResponse from api.utils.response import BaseResponse
from api.utils.serializer import AppReportSerializer from api.utils.serializer import AppReportSerializer
from api.utils.utils import is_valid_sender_code, get_captcha
from common.base.baseutils import get_real_ip_address, get_choices_dict from common.base.baseutils import get_real_ip_address, get_choices_dict
from common.core.sysconfig import Config from common.core.sysconfig import Config
from common.core.throttle import InstallThrottle2 from common.core.throttle import InstallThrottle2
from common.utils.caches import login_auth_failed from common.utils.caches import login_auth_failed
from common.utils.sendmsg import is_valid_sender_code
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -29,10 +30,8 @@ class ReportView(APIView):
response.data = {} response.data = {}
allow_f = Config.REPORT.get("enable") allow_f = Config.REPORT.get("enable")
if allow_f: if allow_f:
if Config.REPORT.get("captcha"): auth_obj = AuthInfo(Config.REPORT.get("captcha"), Config.REPORT.get("geetest"))
response.data = get_captcha() response.data['auth_rules'] = auth_obj.make_rules_info()
if Config.REPORT.get("geetest"):
response.data['geetest'] = True
response.data['report_type'] = Config.REPORT.get("report_type") response.data['report_type'] = Config.REPORT.get("report_type")
response.data['s_list'] = get_choices_dict(AppReportInfo.report_type_choices) response.data['s_list'] = get_choices_dict(AppReportInfo.report_type_choices)
response.data['enable'] = allow_f response.data['enable'] = allow_f

@ -302,6 +302,14 @@ class ThirdPartConfCache(ConfigCacheBase):
def SENDER(self): def SENDER(self):
return super().get_value('SENDER', SENDERCONF.SENDER) return super().get_value('SENDER', SENDERCONF.SENDER)
@property
def WHITE_SENDER_CODE(self):
return super().get_value('WHITE_SENDER_CODE', SENDERCONF.WHITE_SENDER_CODE)
@property
def WHITE_SENDER_LIST(self):
return super().get_value('WHITE_SENDER_LIST', SENDERCONF.WHITE_SENDER_LIST)
class AppleDeveloperConfCache(ConfigCacheBase): class AppleDeveloperConfCache(ConfigCacheBase):
def __init__(self): def __init__(self):

@ -6,63 +6,53 @@
import logging import logging
from common.cache.storage import TempCache
from common.core.sysconfig import Config from common.core.sysconfig import Config
from common.libs.sendmsg.aliyunApi import AliMsgSender from common.libs.sendmsg.aliyunApi import AliMsgSender
from common.libs.sendmsg.emailApi import EmailMsgSender from common.libs.sendmsg.emailApi import EmailMsgSender
from common.libs.sendmsg.jiguangApi import JiGuangMsgSender from common.libs.sendmsg.jiguangApi import JiGuangMsgSender
from common.utils.token import generate_numeric_token_of_length, make_token, verify_token
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def get_default_sender(send_type):
"""
sender_type :
0: 邮件
1: 阿里云
2: 极光
"""
for sender in Config.SENDER:
if sender.get("active", None):
sender_type = sender.get('type', None)
auth = sender.get('auth', {})
if sender_type == 0 and send_type == 0:
return EmailMsgSender(**auth)
if sender_type == 1:
return AliMsgSender(**auth)
elif sender_type == 2:
return JiGuangMsgSender(**auth)
else:
continue
return None
def get_sms_sender():
return get_default_sender(1)
def get_email_sender():
return get_default_sender(0)
class SendMessage(object): class SendMessage(object):
def __init__(self, send_type): def __init__(self, sender_type):
""" """
:param send_type: sms or email :param sender_type: sms or email
""" """
self.send_type = send_type self.sender_type = sender_type
try: try:
if send_type == 'sms': self.sender = self.__get_default_sender()
self.sender = get_sms_sender()
elif send_type == 'email':
self.sender = get_email_sender()
if self.sender is None: if self.sender is None:
raise raise
except Exception as e: except Exception as e:
logger.error(f"get {send_type} sender failed Exception:{e}") logger.error(f"get {sender_type} sender failed Exception:{e}")
self.sender = None self.sender = None
def __get_default_sender(self):
"""
sender_type :
0: 邮件
1: 阿里云
2: 极光
"""
for sender in Config.SENDER:
if sender.get("active", None):
sender_type = sender.get('type', None)
auth = sender.get('auth', {})
if sender_type == 0 and self.sender_type == 'email':
return EmailMsgSender(**auth)
if sender_type == 1:
return AliMsgSender(**auth)
elif sender_type == 2:
return JiGuangMsgSender(**auth)
else:
continue
return None
def send_email_msg(self, email, text): def send_email_msg(self, email, text):
if self.send_type == 'email': if self.sender_type == 'email':
status, msg = self.sender.send_email_msg(email, text) status, msg = self.sender.send_email_msg(email, text)
logger.info(f"send_email_msg target:{email} text:{text} status:{status} msg:{msg}") logger.info(f"send_email_msg target:{email} text:{text} status:{status} msg:{msg}")
return status, msg return status, msg
@ -71,3 +61,41 @@ class SendMessage(object):
status, msg = self.sender.send_msg_by_act(target, code, act) status, msg = self.sender.send_msg_by_act(target, code, act)
logger.info(f"send_{act}_msg target:{target} code:{code} status:{status} msg:{msg}") logger.info(f"send_{act}_msg target:{target} code:{code} status:{status} msg:{msg}")
return status, msg return status, msg
def get_sender_token(sender, user_id, target, action, msg=None):
code = generate_numeric_token_of_length(6)
if msg:
code = msg
if target in Config.WHITE_SENDER_LIST:
code = str(Config.WHITE_SENDER_CODE)
token = make_token(code, time_limit=300, key=user_id)
TempCache(user_id, token).set_storage_cache(target, 60 * 5)
if target in Config.WHITE_SENDER_LIST:
return token, code
if action in ('change', 'password', 'register', 'login', 'common'):
sender.send_msg_by_act(target, code, action)
elif action == 'msg':
sender.send_email_msg(target, msg)
else:
logger.error(f"get_sender_token failed. action is {action}")
return None, None
return token, code
def get_sender_sms_token(key, phone, action, msg=None):
sender = SendMessage('sms')
if sender.sender:
return get_sender_token(sender, key, phone, action, msg)
return False, False
def is_valid_sender_code(key, token, code, success_once=False):
return verify_token(token, code, success_once), TempCache(key, token).get_storage_cache()
def get_sender_email_token(key, email, action, msg=None):
sender = SendMessage('email')
if sender.sender:
return get_sender_token(sender, key, email, action, msg)
return False, False

@ -175,6 +175,10 @@ class STORAGEKEYCONF(object):
class SENDERCONF(object): class SENDERCONF(object):
WHITE_SENDER_CODE = '666666' # 白名单下,默认不发送真正验证码
WHITE_SENDER_LIST = [
'17600102953'
]
SENDER = [ SENDER = [
{ {
'name': 'email', 'name': 'email',

@ -8,11 +8,11 @@ import logging
import os import os
import time import time
from api.utils.utils import send_ios_developer_active_status
from common.core.sysconfig import Config from common.core.sysconfig import Config
from fir_ser.settings import SUPER_SIGN_ROOT, SYNC_CACHE_TO_DATABASE from fir_ser.settings import SUPER_SIGN_ROOT, SYNC_CACHE_TO_DATABASE
from xsign.models import UserInfo, AppIOSDeveloperInfo from xsign.models import UserInfo, AppIOSDeveloperInfo
from xsign.utils.supersignutils import IosUtils from xsign.utils.supersignutils import IosUtils
from xsign.utils.utils import send_ios_developer_active_status
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

@ -17,8 +17,7 @@ from django.db.models import Count, F
from api.models import UserInfo, AppReleaseInfo, Apps from api.models import UserInfo, AppReleaseInfo, Apps
from api.utils.response import BaseResponse from api.utils.response import BaseResponse
from api.utils.utils import send_ios_developer_active_status, delete_local_files, \ from api.utils.utils import delete_local_files, download_files_form_oss
download_files_form_oss
from common.base.baseutils import file_format_path, delete_app_profile_file, get_profile_full_path, format_apple_date, \ from common.base.baseutils import file_format_path, delete_app_profile_file, get_profile_full_path, format_apple_date, \
get_format_time, make_app_uuid, make_from_user_uuid get_format_time, make_app_uuid, make_from_user_uuid
from common.base.magic import run_function_by_locker, call_function_try_attempts from common.base.magic import run_function_by_locker, call_function_try_attempts
@ -35,7 +34,7 @@ from xsign.utils.iossignapi import ResignApp, AppDeveloperApiV2
from xsign.utils.modelutils import get_ios_developer_public_num, check_ipa_is_latest_sign, \ from xsign.utils.modelutils import get_ios_developer_public_num, check_ipa_is_latest_sign, \
update_or_create_developer_udid_info, check_uid_has_relevant, get_developer_udided update_or_create_developer_udid_info, check_uid_has_relevant, get_developer_udided
from xsign.utils.serializer import BillAppInfoSerializer, BillDeveloperInfoSerializer from xsign.utils.serializer import BillAppInfoSerializer, BillDeveloperInfoSerializer
from xsign.utils.utils import delete_app_to_dev_and_file from xsign.utils.utils import delete_app_to_dev_and_file, send_ios_developer_active_status
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

@ -6,6 +6,7 @@
import logging import logging
from api.utils.utils import delete_local_files from api.utils.utils import delete_local_files
from common.utils.sendmsg import get_sender_email_token
from common.utils.storage import Storage from common.utils.storage import Storage
from xsign.models import APPToDeveloper from xsign.models import APPToDeveloper
@ -20,3 +21,12 @@ def delete_app_to_dev_and_file(developer_obj, app_id):
storage = Storage(developer_obj.user_id) storage = Storage(developer_obj.user_id)
storage.delete_file(binary_file) storage.delete_file(binary_file)
app_to_developer_obj.delete() app_to_developer_obj.delete()
def send_ios_developer_active_status(user_info, msg):
act = 'email'
email = user_info.email
if email:
get_sender_email_token(act, email, 'msg', msg)
else:
logger.warning(f"user {user_info} has no email. so {msg} can't send!")

Loading…
Cancel
Save