diff --git a/models/wechat_bind.go b/models/wechat_bind.go index f75188280..3cca4888a 100644 --- a/models/wechat_bind.go +++ b/models/wechat_bind.go @@ -47,6 +47,18 @@ func BindWechatOpenId(userId int64, wechatOpenId string) error { return sess.Commit() } +func GetUserWechatOpenId(userId int64) string { + param := &User{} + x.Cols("wechat_open_id").Where("ID =?", userId).Get(param) + return param.WechatOpenId +} + +func GetUserByWechatOpenId(wechatOpenId string) *User { + user := &User{} + x.Where("wechat_open_id = ?", wechatOpenId).Get(user) + return user +} + func UnbindWechatOpenId(userId int64, oldWechatOpenID string) error { sess := x.NewSession() defer sess.Close() diff --git a/modules/auth/wechat/bind.go b/modules/auth/wechat/bind.go index 54937e4e1..a2172718a 100644 --- a/modules/auth/wechat/bind.go +++ b/modules/auth/wechat/bind.go @@ -2,6 +2,8 @@ package wechat import ( "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/log" + "fmt" ) type QRCode4BindCache struct { @@ -16,10 +18,54 @@ const ( BIND_STATUS_EXPIRED = 9 ) +const ( + BIND_REPLY_SUCCESS = "启智账号认证微信成功" + BIND_REPLY_WECHAT_ACCOUNT_USED = "认证失败,您的微信号已绑定其他启智账号" + BIND_REPLY_OPENI_ACCOUNT_USED = "认证失败,您待认证的启智账号已绑定其他微信号" + BIND_REPLY_FAILED_DEFAULT = "微信认证失败" +) + +type WechatBindError struct { + Reply string +} + +func NewWechatBindError(reply string) WechatBindError { + return WechatBindError{Reply: reply} +} + +func (err WechatBindError) Error() string { + return fmt.Sprint("wechat bind error,reply=%s", err.Reply) +} + func BindWechat(userId int64, wechatOpenId string) error { + if !IsWechatAccountAvailable(userId, wechatOpenId) { + log.Error("bind wechat failed, because user use wrong wechat account to bind,userId=%d wechatOpenId=%s", userId, wechatOpenId) + return NewWechatBindError(BIND_REPLY_WECHAT_ACCOUNT_USED) + } + if !IsUserAvailableForWechatBind(userId, wechatOpenId) { + log.Error("openI account has been used,userId=%d wechatOpenId=%s", userId, wechatOpenId) + return NewWechatBindError(BIND_REPLY_OPENI_ACCOUNT_USED) + } return models.BindWechatOpenId(userId, wechatOpenId) } func UnbindWechat(userId int64, oldWechatOpenId string) error { return models.UnbindWechatOpenId(userId, oldWechatOpenId) } + +//IsUserAvailableForWechatBind if user has bound wechat and the bound openId is not the given wechatOpenId,return false +//otherwise,return true +func IsUserAvailableForWechatBind(userId int64, wechatOpenId string) bool { + currentOpenId := models.GetUserWechatOpenId(userId) + return currentOpenId == "" || currentOpenId == wechatOpenId +} + +//IsWechatAccountAvailable if wechat account used by another account,return false +//if wechat account not used or used by the given user,return true +func IsWechatAccountAvailable(userId int64, wechatOpenId string) bool { + user := models.GetUserByWechatOpenId(wechatOpenId) + if user != nil && user.WechatOpenId != "" && user.ID != userId { + return false + } + return true +} diff --git a/modules/auth/wechat/event_handle.go b/modules/auth/wechat/event_handle.go index 9e05f5e6e..c49c6d763 100644 --- a/modules/auth/wechat/event_handle.go +++ b/modules/auth/wechat/event_handle.go @@ -9,8 +9,6 @@ import ( "time" ) -const BIND_REPLY = "启智账号认证微信成功" - // // // @@ -52,12 +50,18 @@ func HandleSubscribeEvent(we WechatEvent) string { } qrCache := new(QRCode4BindCache) json.Unmarshal([]byte(val), qrCache) - //todo 已绑定微信号的如何处理? - //更新微信openId和流水 - BindWechat(qrCache.UserId, we.FromUserName) + if qrCache.Status == BIND_STATUS_UNBIND { + err := BindWechat(qrCache.UserId, we.FromUserName) + if err != nil { + if err, ok := err.(WechatBindError); ok { + return err.Reply + } + return BIND_REPLY_FAILED_DEFAULT + } + qrCache.Status = BIND_STATUS_BOUND + jsonStr, _ := json.Marshal(qrCache) + redis_client.Setex(redis_key.WechatBindingUserIdKey(sceneStr), string(jsonStr), 60*time.Second) + } - qrCache.Status = BIND_STATUS_BOUND - jsonStr, _ := json.Marshal(qrCache) - redis_client.Setex(redis_key.WechatBindingUserIdKey(sceneStr), string(jsonStr), 60*time.Second) - return BIND_REPLY + return BIND_REPLY_SUCCESS } diff --git a/modules/context/auth.go b/modules/context/auth.go index 48a23e421..b374e385b 100755 --- a/modules/context/auth.go +++ b/modules/context/auth.go @@ -127,7 +127,7 @@ func Toggle(options *ToggleOptions) macaron.Handler { } } - if options.WechatAuthRequired { + if setting.WechatAuthSwitch && options.WechatAuthRequired { if !ctx.IsSigned { ctx.SetCookie("redirect_to", setting.AppSubURL+ctx.Req.URL.RequestURI(), 0, setting.AppSubURL) ctx.Redirect(setting.AppSubURL + "/user/login") diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 227a05656..06cbd6de5 100755 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -535,6 +535,7 @@ var ( WechatAppId string WechatAppSecret string WechatQRCodeExpireSeconds int + WechatAuthSwitch bool //nginx proxy PROXYURL string @@ -1355,6 +1356,7 @@ func NewContext() { WechatAppId = sec.Key("APP_ID").MustString("wxba77b915a305a57d") WechatAppSecret = sec.Key("APP_SECRET").MustString("e48e13f315adc32749ddc7057585f198") WechatQRCodeExpireSeconds = sec.Key("QR_CODE_EXPIRE_SECONDS").MustInt(120) + WechatAuthSwitch = sec.Key("AUTH_SWITCH").MustBool(true) SetRadarMapConfig()