From d72bf77a3310d0b52f0fc6c887d68c2f361eebf7 Mon Sep 17 00:00:00 2001 From: Gitea Date: Fri, 18 Feb 2022 09:32:00 +0800 Subject: [PATCH 01/47] #1494 create qrcode4bind --- modules/auth/wechat/access_token.go | 44 ++++++++++ modules/auth/wechat/client.go | 95 +++++++++++++++++++++ modules/auth/wechat/event.go | 1 + modules/auth/wechat/qr_code.go | 6 ++ modules/redis/redis_client/client.go | 54 ++++++++++++ modules/redis/redis_key/key_base.go | 16 ++++ modules/redis/redis_key/wechat_redis_key.go | 11 +++ modules/setting/setting.go | 18 +++- routers/authentication/wechat.go | 67 +++++++++++++++ routers/routes/routes.go | 8 ++ 10 files changed, 318 insertions(+), 2 deletions(-) create mode 100644 modules/auth/wechat/access_token.go create mode 100644 modules/auth/wechat/client.go create mode 100644 modules/auth/wechat/event.go create mode 100644 modules/auth/wechat/qr_code.go create mode 100644 modules/redis/redis_client/client.go create mode 100644 modules/redis/redis_key/key_base.go create mode 100644 modules/redis/redis_key/wechat_redis_key.go create mode 100644 routers/authentication/wechat.go diff --git a/modules/auth/wechat/access_token.go b/modules/auth/wechat/access_token.go new file mode 100644 index 000000000..a312db215 --- /dev/null +++ b/modules/auth/wechat/access_token.go @@ -0,0 +1,44 @@ +package wechat + +import ( + "code.gitea.io/gitea/modules/redis/redis_client" + "code.gitea.io/gitea/modules/redis/redis_key" + "time" +) + +const EMPTY_REDIS_VAL = "Nil" + +func GetWechatAccessToken() string { + token, _ := redis_client.Get(redis_key.WechatAccessTokenKey()) + if token != "" { + if token == EMPTY_REDIS_VAL { + return "" + } + live, _ := redis_client.TTL(token) + //refresh wechat access token when expire time less than 5 minutes + if live > 0 && live < 300 { + refreshAccessTokenCache() + } + return token + } + return refreshAccessTokenCache() +} + +func refreshAccessTokenCache() string { + r := callAccessToken() + + var token string + if r != nil { + token = r.Access_token + } + + if token == "" { + redis_client.Setex(redis_key.WechatAccessTokenKey(), EMPTY_REDIS_VAL, 10*time.Second) + return "" + } + + redis_client.Setex(redis_key.WechatAccessTokenKey(), token, time.Duration(r.Expires_in)*time.Second) + + return token + +} diff --git a/modules/auth/wechat/client.go b/modules/auth/wechat/client.go new file mode 100644 index 000000000..edf010b33 --- /dev/null +++ b/modules/auth/wechat/client.go @@ -0,0 +1,95 @@ +package wechat + +import ( + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + "encoding/json" + "github.com/go-resty/resty/v2" + "time" +) + +var ( + client *resty.Client +) + +const ( + GRANT_TYPE = "client_credential" + ACCESS_TOKEN_PATH = "/cgi-bin/token" + QR_CODE_Path = "/cgi-bin/qrcode/create" + ACTION_QR_STR_SCENE = "QR_STR_SCENE" +) + +type AccessTokenResponse struct { + Access_token string + Expires_in int +} + +type QRCodeResponse struct { + Ticket string `json:"ticket"` + Expire_Seconds int `json:"expire_seconds"` + Url string `json:"url"` +} + +type QRCodeRequest struct { + Action_name string `json:"action_name"` + Action_info ActionInfo `json:"action_info"` + Expire_seconds int `json:"expire_seconds"` +} + +type ActionInfo struct { + Scene Scene +} + +type Scene struct { + Scene_str string +} + +func getWechatRestyClient() *resty.Client { + if client == nil { + client = resty.New() + client.SetTimeout(time.Duration(setting.WechatApiTimeoutSeconds) * time.Second) + } + return client +} + +func callAccessToken() *AccessTokenResponse { + client := getWechatRestyClient() + + var result AccessTokenResponse + _, err := client.R(). + SetQueryParam("grant_type", GRANT_TYPE). + SetQueryParam("appid", setting.WechatAppId). + SetQueryParam("secret", setting.WechatAppSecret). + SetResult(&result). + Get(setting.WechatApiHost + ACCESS_TOKEN_PATH) + if err != nil { + log.Error("get wechat access token failed,e=%v", err) + return nil + } + return &result +} + +func callQRCodeCreate(sceneStr string) *QRCodeResponse { + client := getWechatRestyClient() + + body := &QRCodeRequest{ + Action_name: ACTION_QR_STR_SCENE, + Action_info: ActionInfo{Scene: Scene{Scene_str: sceneStr}}, + Expire_seconds: setting.WechatQRCodeExpireSeconds, + } + bodyJson, _ := json.Marshal(body) + var result QRCodeResponse + r, err := client.R(). + SetHeader("Content-Type", "application/json"). + SetQueryParam("access_token", GetWechatAccessToken()). + SetBody(bodyJson). + SetResult(&result). + Post(setting.WechatApiHost + QR_CODE_Path) + if err != nil || result.Url == "" { + log.Error("create QR code failed,e=%v", err) + return nil + } + //todo 识别token失效的错误码,重试机制 + log.Info("%v", r) + return &result +} diff --git a/modules/auth/wechat/event.go b/modules/auth/wechat/event.go new file mode 100644 index 000000000..ecd4201a5 --- /dev/null +++ b/modules/auth/wechat/event.go @@ -0,0 +1 @@ +package wechat diff --git a/modules/auth/wechat/qr_code.go b/modules/auth/wechat/qr_code.go new file mode 100644 index 000000000..1e462861e --- /dev/null +++ b/modules/auth/wechat/qr_code.go @@ -0,0 +1,6 @@ +package wechat + +func GetWechatQRCode4Bind(sceneStr string) *QRCodeResponse { + r := callQRCodeCreate(sceneStr) + return r +} diff --git a/modules/redis/redis_client/client.go b/modules/redis/redis_client/client.go new file mode 100644 index 000000000..0590f13b1 --- /dev/null +++ b/modules/redis/redis_client/client.go @@ -0,0 +1,54 @@ +package redis_client + +import ( + "code.gitea.io/gitea/modules/labelmsg" + "fmt" + "math" + "strconv" + "time" +) + +//todo redis连接池 +func Setex(key, value string, timeout time.Duration) (bool, error) { + redisClient := labelmsg.Get() + defer redisClient.Close() + + seconds := int(math.Floor(timeout.Seconds())) + reply, err := redisClient.Do("SETEX", key, seconds, value) + if err != nil { + return false, err + } + if reply != "OK" { + return false, nil + } + return true, nil + +} + +func Get(key string) (string, error) { + redisClient := labelmsg.Get() + defer redisClient.Close() + + reply, err := redisClient.Do("GET", key) + if err != nil { + return "", err + } + if reply == nil { + return "", err + } + return fmt.Sprint(reply), nil + +} + +func TTL(key string) (int, error) { + redisClient := labelmsg.Get() + defer redisClient.Close() + + reply, err := redisClient.Do("TTL", key) + if err != nil { + return 0, err + } + n, _ := strconv.Atoi(fmt.Sprint(reply)) + return n, nil + +} diff --git a/modules/redis/redis_key/key_base.go b/modules/redis/redis_key/key_base.go new file mode 100644 index 000000000..0efc6ed38 --- /dev/null +++ b/modules/redis/redis_key/key_base.go @@ -0,0 +1,16 @@ +package redis_key + +import "strings" + +const KEY_SEPARATE = ":" + +func KeyJoin(keys ...string) string { + var build strings.Builder + for _, v := range keys { + build.WriteString(v) + build.WriteString(KEY_SEPARATE) + } + s := build.String() + s = strings.TrimSuffix(s, KEY_SEPARATE) + return s +} diff --git a/modules/redis/redis_key/wechat_redis_key.go b/modules/redis/redis_key/wechat_redis_key.go new file mode 100644 index 000000000..def7e93ee --- /dev/null +++ b/modules/redis/redis_key/wechat_redis_key.go @@ -0,0 +1,11 @@ +package redis_key + +const PREFIX = "wechat" + +func WechatBindingUserIdKey(sceneStr string) string { + return KeyJoin(PREFIX, sceneStr, "scene_userId") +} + +func WechatAccessTokenKey() string { + return KeyJoin(PREFIX, "access_token") +} diff --git a/modules/setting/setting.go b/modules/setting/setting.go index c6828f9f7..227a05656 100755 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -470,7 +470,7 @@ var ( BenchmarkTypes string BenchmarkGpuTypes string BenchmarkResourceSpecs string - BenchmarkMaxDuration int64 + BenchmarkMaxDuration int64 //snn4imagenet config IsSnn4imagenetEnabled bool @@ -512,7 +512,7 @@ var ( ProfileID string PoolInfos string Flavor string - DebugHost string + DebugHost string //train-job ResourcePools string Engines string @@ -529,6 +529,13 @@ var ( ElkTimeFormat string PROJECT_LIMIT_PAGES []string + //wechat config + WechatApiHost string + WechatApiTimeoutSeconds int + WechatAppId string + WechatAppSecret string + WechatQRCodeExpireSeconds int + //nginx proxy PROXYURL string RadarMap = struct { @@ -1342,6 +1349,13 @@ func NewContext() { ElkTimeFormat = sec.Key("ELKTIMEFORMAT").MustString("date_time") PROJECT_LIMIT_PAGES = strings.Split(sec.Key("project_limit_pages").MustString(""), ",") + sec = Cfg.Section("wechat") + WechatApiHost = sec.Key("HOST").MustString("https://api.weixin.qq.com") + WechatApiTimeoutSeconds = sec.Key("TIMEOUT_SECONDS").MustInt(3) + WechatAppId = sec.Key("APP_ID").MustString("wxba77b915a305a57d") + WechatAppSecret = sec.Key("APP_SECRET").MustString("e48e13f315adc32749ddc7057585f198") + WechatQRCodeExpireSeconds = sec.Key("QR_CODE_EXPIRE_SECONDS").MustInt(120) + SetRadarMapConfig() sec = Cfg.Section("warn_mail") diff --git a/routers/authentication/wechat.go b/routers/authentication/wechat.go new file mode 100644 index 000000000..d9004ace9 --- /dev/null +++ b/routers/authentication/wechat.go @@ -0,0 +1,67 @@ +package authentication + +import ( + "code.gitea.io/gitea/modules/auth/wechat" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/redis/redis_client" + "code.gitea.io/gitea/modules/redis/redis_key" + "code.gitea.io/gitea/modules/setting" + "errors" + "fmt" + gouuid "github.com/satori/go.uuid" + "time" +) + +type QRCodeResponse struct { + Url string + Ticket string + SceneStr string + ExpireSeconds int +} + +// GetQRCode4Bind get QR code for wechat binding +func GetQRCode4Bind(ctx *context.Context) { + userId := ctx.User.ID + + r, err := createQRCode4Bind(userId) + if err != nil { + ctx.JSON(200, map[string]interface{}{ + "code": 9, + "msg": "Get QR code failed", + }) + return + } + + ctx.JSON(200, map[string]interface{}{ + "code": 0, + "msg": "success", + "data": r, + }) +} + +func createQRCode4Bind(userId int64) (*QRCodeResponse, error) { + sceneStr := gouuid.NewV4().String() + r := wechat.GetWechatQRCode4Bind(sceneStr) + if r == nil { + return nil, errors.New("createQRCode4Bind failed") + } + + isOk, err := redis_client.Setex(redis_key.WechatBindingUserIdKey(sceneStr), fmt.Sprint(userId), time.Duration(setting.WechatQRCodeExpireSeconds)*time.Second) + if err != nil { + log.Error("createQRCode4Bind failed.e=%v", err) + return nil, err + } + if !isOk { + log.Error("createQRCode4Bind failed.redis reply is not ok") + return nil, errors.New("reply is not ok when set WechatBindingUserIdKey") + } + + result := &QRCodeResponse{ + Url: r.Url, + Ticket: r.Ticket, + SceneStr: sceneStr, + ExpireSeconds: setting.WechatQRCodeExpireSeconds, + } + return result, nil +} diff --git a/routers/routes/routes.go b/routers/routes/routes.go index aa85b8f2b..9613b43cd 100755 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -6,6 +6,7 @@ package routes import ( "bytes" + "code.gitea.io/gitea/routers/authentication" "encoding/gob" "net/http" "path" @@ -391,6 +392,13 @@ func RegisterRoutes(m *macaron.Macaron) { }, ignSignInAndCsrf, reqSignIn) m.Post("/login/oauth/access_token", bindIgnErr(auth.AccessTokenForm{}), ignSignInAndCsrf, user.AccessTokenOAuth) + m.Group("/authentication/wechat", func() { + m.Get("/qrCode4Bind", authentication.GetQRCode4Bind) + m.Post("/grant", bindIgnErr(auth.GrantApplicationForm{}), user.GrantApplicationOAuth) + // TODO manage redirection + m.Post("/authorize", bindIgnErr(auth.AuthorizationForm{}), user.AuthorizeOAuth) + }, reqSignIn) + m.Group("/user/settings", func() { m.Get("", userSetting.Profile) m.Post("", bindIgnErr(auth.UpdateProfileForm{}), userSetting.ProfilePost) From 3085628544d4412660420dbd340eda7b053a2b15 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Fri, 18 Feb 2022 10:57:58 +0800 Subject: [PATCH 02/47] fix issue --- package-lock.json | 5 +++++ package.json | 1 + templates/repo/wx_autorize.tmpl | 23 +++++++++++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 templates/repo/wx_autorize.tmpl diff --git a/package-lock.json b/package-lock.json index a8e5e3e25..41a484f9e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11147,6 +11147,11 @@ "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" }, + "qrcodejs2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/qrcodejs2/-/qrcodejs2-0.0.2.tgz", + "integrity": "sha1-Rlr+Xjnxn6zsuTLBH3oYYQkUauE=" + }, "qs": { "version": "6.9.4", "resolved": "https://registry.npm.taobao.org/qs/download/qs-6.9.4.tgz", diff --git a/package.json b/package.json index ba5459a07..70f292584 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "postcss-loader": "3.0.0", "postcss-preset-env": "6.7.0", "postcss-safe-parser": "4.0.2", + "qrcodejs2": "0.0.2", "qs": "6.9.4", "remixicon": "2.5.0", "spark-md5": "3.0.1", diff --git a/templates/repo/wx_autorize.tmpl b/templates/repo/wx_autorize.tmpl new file mode 100644 index 000000000..615897f85 --- /dev/null +++ b/templates/repo/wx_autorize.tmpl @@ -0,0 +1,23 @@ + +{{template "base/head" .}} +
+ {{template "repo/header" .}} + {{template "base/alert" .}} +
+
+
+

微信扫码认证

+

请绑定微信,然后再使用启智算力环境

+
+ +
+ 绑定微信代表已阅读并接受OpenI启智社区AI协作平台使用协议 +
+
+
+
\ No newline at end of file From 851d4be30a179f0213d4680207bac557258416f4 Mon Sep 17 00:00:00 2001 From: Gitea Date: Fri, 18 Feb 2022 16:11:39 +0800 Subject: [PATCH 03/47] #1494 add wechat event handler --- models/models.go | 1 + models/user.go | 3 ++ models/wechat_bind.go | 74 ++++++++++++++++++++++++++ modules/auth/wechat/access_token.go | 2 +- modules/auth/wechat/bind.go | 11 ++++ modules/auth/wechat/call.go | 5 ++ modules/auth/wechat/client.go | 38 +++++++++++-- modules/auth/wechat/qr_code.go | 8 ++- modules/redis/redis_client/client.go | 20 ++++++- routers/api/v1/api.go | 4 ++ routers/authentication/wechat.go | 4 +- routers/authentication/wechat_event.go | 68 +++++++++++++++++++++++ 12 files changed, 227 insertions(+), 11 deletions(-) create mode 100644 models/wechat_bind.go create mode 100644 modules/auth/wechat/bind.go create mode 100644 modules/auth/wechat/call.go create mode 100644 routers/authentication/wechat_event.go diff --git a/models/models.go b/models/models.go index 11f445830..0f4679b4f 100755 --- a/models/models.go +++ b/models/models.go @@ -136,6 +136,7 @@ func init() { new(AiModelManage), new(OfficialTag), new(OfficialTagRepos), + new(WechatBindLog), ) tablesStatistic = append(tablesStatistic, diff --git a/models/user.go b/models/user.go index b362472e8..1aa7dac27 100755 --- a/models/user.go +++ b/models/user.go @@ -177,6 +177,9 @@ type User struct { //BlockChain PublicKey string `xorm:"INDEX"` PrivateKey string `xorm:"INDEX"` + + //Wechat + WechatOpenId string `xorm:"INDEX"` } // SearchOrganizationsOptions options to filter organizations diff --git a/models/wechat_bind.go b/models/wechat_bind.go new file mode 100644 index 000000000..ab2d1e06d --- /dev/null +++ b/models/wechat_bind.go @@ -0,0 +1,74 @@ +package models + +import ( + "code.gitea.io/gitea/modules/log" + "time" +) + +type WechatBindAction int + +const ( + WECHAT_BIND WechatBindAction = iota + 1 + WECHAT_UNBIND +) + +type WechatBindLog struct { + ID int64 `xorm:"pk autoincr"` + UserID int64 `xorm:"INDEX"` + WechatOpenId string `xorm:"INDEX"` + Action int + CreateTime time.Time `xorm:"INDEX created"` +} + +func BindWechatOpenId(userId int64, wechatOpenId string) error { + sess := x.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return err + } + + param := &User{WechatOpenId: wechatOpenId} + n, err := sess.Where("ID = ?", userId).Update(param) + if err != nil { + log.Error("update wechat_open_id failed,e=%v", err) + return err + } + if n == 0 { + log.Error("update wechat_open_id failed,user not exist,userId=%d", userId) + return nil + } + + logParam := &WechatBindLog{ + UserID: userId, + WechatOpenId: wechatOpenId, + Action: int(WECHAT_BIND), + } + sess.Insert(logParam) + return sess.Commit() +} + +func UnbindWechatOpenId(userId int64) error { + sess := x.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return err + } + + param := &User{WechatOpenId: ""} + n, err := x.Where("ID = ?", userId).Update(param) + if err != nil { + log.Error("update wechat_open_id failed,e=%v", err) + return err + } + if n == 0 { + log.Error("update wechat_open_id failed,user not exist,userId=%d", userId) + return nil + } + //todo 是否记录原有微信openId + logParam := &WechatBindLog{ + UserID: userId, + Action: int(WECHAT_UNBIND), + } + sess.Insert(logParam) + return sess.Commit() +} diff --git a/modules/auth/wechat/access_token.go b/modules/auth/wechat/access_token.go index a312db215..1bfef2758 100644 --- a/modules/auth/wechat/access_token.go +++ b/modules/auth/wechat/access_token.go @@ -14,7 +14,7 @@ func GetWechatAccessToken() string { if token == EMPTY_REDIS_VAL { return "" } - live, _ := redis_client.TTL(token) + live, _ := redis_client.TTL(redis_key.WechatAccessTokenKey()) //refresh wechat access token when expire time less than 5 minutes if live > 0 && live < 300 { refreshAccessTokenCache() diff --git a/modules/auth/wechat/bind.go b/modules/auth/wechat/bind.go new file mode 100644 index 000000000..a2a05c6a3 --- /dev/null +++ b/modules/auth/wechat/bind.go @@ -0,0 +1,11 @@ +package wechat + +import "code.gitea.io/gitea/models" + +func BindWechat(userId int64, wechatOpenId string) error { + return models.BindWechatOpenId(userId, wechatOpenId) +} + +func UnbindWechat(userId int64) error { + return models.UnbindWechatOpenId(userId) +} diff --git a/modules/auth/wechat/call.go b/modules/auth/wechat/call.go new file mode 100644 index 000000000..f93535c6b --- /dev/null +++ b/modules/auth/wechat/call.go @@ -0,0 +1,5 @@ +package wechat + +type WechatCall interface { + call() +} diff --git a/modules/auth/wechat/client.go b/modules/auth/wechat/client.go index edf010b33..680e0bb34 100644 --- a/modules/auth/wechat/client.go +++ b/modules/auth/wechat/client.go @@ -4,7 +4,9 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "encoding/json" + "fmt" "github.com/go-resty/resty/v2" + "strconv" "time" ) @@ -17,6 +19,9 @@ const ( ACCESS_TOKEN_PATH = "/cgi-bin/token" QR_CODE_Path = "/cgi-bin/qrcode/create" ACTION_QR_STR_SCENE = "QR_STR_SCENE" + + ERR_CODE_ACCESSTOKEN_EXPIRE = 42001 + ERR_CODE_ACCESSTOKEN_INVALID = 40001 ) type AccessTokenResponse struct { @@ -44,6 +49,11 @@ type Scene struct { Scene_str string } +type ErrorResponse struct { + Errcode int + Errmsg string +} + func getWechatRestyClient() *resty.Client { if client == nil { client = resty.New() @@ -69,7 +79,7 @@ func callAccessToken() *AccessTokenResponse { return &result } -func callQRCodeCreate(sceneStr string) *QRCodeResponse { +func callQRCodeCreate(sceneStr string) (*QRCodeResponse, bool) { client := getWechatRestyClient() body := &QRCodeRequest{ @@ -85,11 +95,29 @@ func callQRCodeCreate(sceneStr string) *QRCodeResponse { SetBody(bodyJson). SetResult(&result). Post(setting.WechatApiHost + QR_CODE_Path) - if err != nil || result.Url == "" { + if err != nil { log.Error("create QR code failed,e=%v", err) - return nil + return nil, false + } + errCode := getErrorCodeFromResponse(r) + if errCode == ERR_CODE_ACCESSTOKEN_EXPIRE || errCode == ERR_CODE_ACCESSTOKEN_INVALID { + return nil, true + } + if result.Url == "" { + return nil, false } - //todo 识别token失效的错误码,重试机制 log.Info("%v", r) - return &result + return &result, false +} + +func getErrorCodeFromResponse(r *resty.Response) int { + a := r.Body() + resultMap := make(map[string]interface{}, 0) + json.Unmarshal(a, &resultMap) + code := resultMap["errcode"] + if code == nil { + return -1 + } + c, _ := strconv.Atoi(fmt.Sprint(code)) + return c } diff --git a/modules/auth/wechat/qr_code.go b/modules/auth/wechat/qr_code.go index 1e462861e..5506cecb7 100644 --- a/modules/auth/wechat/qr_code.go +++ b/modules/auth/wechat/qr_code.go @@ -1,6 +1,10 @@ package wechat func GetWechatQRCode4Bind(sceneStr string) *QRCodeResponse { - r := callQRCodeCreate(sceneStr) - return r + result, retryFlag := callQRCodeCreate(sceneStr) + if retryFlag { + refreshAccessTokenCache() + result, _ = callQRCodeCreate(sceneStr) + } + return result } diff --git a/modules/redis/redis_client/client.go b/modules/redis/redis_client/client.go index 0590f13b1..5257da521 100644 --- a/modules/redis/redis_client/client.go +++ b/modules/redis/redis_client/client.go @@ -3,6 +3,7 @@ package redis_client import ( "code.gitea.io/gitea/modules/labelmsg" "fmt" + "github.com/gomodule/redigo/redis" "math" "strconv" "time" @@ -36,7 +37,24 @@ func Get(key string) (string, error) { if reply == nil { return "", err } - return fmt.Sprint(reply), nil + s, _ := redis.String(reply, nil) + return s, nil + +} + +func Del(key string) (int, error) { + redisClient := labelmsg.Get() + defer redisClient.Close() + + reply, err := redisClient.Do("DEL", key) + if err != nil { + return 0, err + } + if reply == nil { + return 0, err + } + s, _ := redis.Int(reply, nil) + return s, nil } diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 72a68a6d3..1484d6eb5 100755 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -59,6 +59,7 @@ package v1 import ( + "code.gitea.io/gitea/routers/authentication" "net/http" "strings" @@ -995,6 +996,9 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/topics", func() { m.Get("/search", repo.TopicSearch) }) + m.Group("/from_wechat", func() { + m.Get("/event", authentication.AcceptWechatEvent) + }) }, securityHeaders(), context.APIContexter(), sudo()) } diff --git a/routers/authentication/wechat.go b/routers/authentication/wechat.go index d9004ace9..f720332bb 100644 --- a/routers/authentication/wechat.go +++ b/routers/authentication/wechat.go @@ -27,14 +27,14 @@ func GetQRCode4Bind(ctx *context.Context) { r, err := createQRCode4Bind(userId) if err != nil { ctx.JSON(200, map[string]interface{}{ - "code": 9, + "code": "9999", "msg": "Get QR code failed", }) return } ctx.JSON(200, map[string]interface{}{ - "code": 0, + "code": "00", "msg": "success", "data": r, }) diff --git a/routers/authentication/wechat_event.go b/routers/authentication/wechat_event.go new file mode 100644 index 000000000..8999f771f --- /dev/null +++ b/routers/authentication/wechat_event.go @@ -0,0 +1,68 @@ +package authentication + +import ( + "code.gitea.io/gitea/modules/auth/wechat" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/redis/redis_client" + "code.gitea.io/gitea/modules/redis/redis_key" + "encoding/xml" + "io/ioutil" + "strconv" + "time" +) + +// +// +// +// 123456789 +// +// +// +// +// +type WechatEvent struct { + ToUserName string + FromUserName string + CreateTime int64 + MsgType string + Event string + EventKey string + Ticket string +} + +type Xml struct { + ToUserName string + FromUserName string + CreateTime int64 + MsgType string + Content string +} + +// AcceptWechatEvent +func AcceptWechatEvent(ctx *context.Context) { + b, _ := ioutil.ReadAll(ctx.Req.Request.Body) + we := WechatEvent{} + xml.Unmarshal(b, &we) + + log.Info("accept wechat event= %v", b) + key := redis_key.WechatBindingUserIdKey(we.EventKey) + val, _ := redis_client.Get(key) + if val == "" { + log.Error("sceneStr is not exist,sceneStr=%s", we.EventKey) + ctx.XML(200, "") + return + } + userId, _ := strconv.ParseInt(val, 10, 64) + //更新微信openId和流水 + wechat.BindWechat(userId, we.EventKey) + reply := &Xml{ + ToUserName: we.FromUserName, + FromUserName: we.ToUserName, + CreateTime: time.Now().Unix(), + MsgType: "text", + Content: "启智账号认证微信成功", + } + redis_client.Del(key) + ctx.XML(200, reply) +} From 986d4d5a8df199062cc10c78d22a9061c812fcc5 Mon Sep 17 00:00:00 2001 From: Gitea Date: Mon, 21 Feb 2022 10:11:40 +0800 Subject: [PATCH 04/47] #1494 update --- routers/api/v1/api.go | 1 + 1 file changed, 1 insertion(+) diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 1484d6eb5..eb1665cd2 100755 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -998,6 +998,7 @@ func RegisterRoutes(m *macaron.Macaron) { }) m.Group("/from_wechat", func() { m.Get("/event", authentication.AcceptWechatEvent) + m.Post("/event", authentication.AcceptWechatEvent) }) }, securityHeaders(), context.APIContexter(), sudo()) } From ea59293d6209a8ec38aa68eae098d7d13bfb1889 Mon Sep 17 00:00:00 2001 From: Gitea Date: Mon, 21 Feb 2022 10:38:50 +0800 Subject: [PATCH 05/47] #1494 update --- modules/auth/wechat/bind.go | 14 +++++++++- modules/context/auth.go | 25 +++++++++++++----- routers/api/v1/api.go | 2 +- routers/authentication/wechat.go | 36 ++++++++++++++++++++++++++ routers/authentication/wechat_event.go | 8 +++++- routers/routes/routes.go | 5 ++-- 6 files changed, 79 insertions(+), 11 deletions(-) diff --git a/modules/auth/wechat/bind.go b/modules/auth/wechat/bind.go index a2a05c6a3..f00f26aaa 100644 --- a/modules/auth/wechat/bind.go +++ b/modules/auth/wechat/bind.go @@ -1,6 +1,8 @@ package wechat -import "code.gitea.io/gitea/models" +import ( + "code.gitea.io/gitea/models" +) func BindWechat(userId int64, wechatOpenId string) error { return models.BindWechatOpenId(userId, wechatOpenId) @@ -9,3 +11,13 @@ func BindWechat(userId int64, wechatOpenId string) error { func UnbindWechat(userId int64) error { return models.UnbindWechatOpenId(userId) } + +func IsUserFinishBind(sceneStr string) bool { + //val, _ := redis_client.Get(redis_key.WechatBindingUserIdKey(sceneStr)) + //if val == "" { + // return false + //} + //userId, _ := strconv.ParseInt(val, 10, 64) + return false + +} diff --git a/modules/context/auth.go b/modules/context/auth.go index 61a7b029b..c844040d7 100755 --- a/modules/context/auth.go +++ b/modules/context/auth.go @@ -21,12 +21,13 @@ import ( // ToggleOptions contains required or check options type ToggleOptions struct { - SignInRequired bool - SignOutRequired bool - AdminRequired bool - DisableCSRF bool - BasicAuthRequired bool - OperationRequired bool + SignInRequired bool + SignOutRequired bool + AdminRequired bool + DisableCSRF bool + BasicAuthRequired bool + OperationRequired bool + WechatAuthRequired bool } // Toggle returns toggle options as middleware @@ -126,6 +127,18 @@ func Toggle(options *ToggleOptions) macaron.Handler { } } + if options.WechatAuthRequired { + if !ctx.IsSigned { + ctx.SetCookie("redirect_to", setting.AppSubURL+ctx.Req.URL.RequestURI(), 0, setting.AppSubURL) + ctx.Redirect(setting.AppSubURL + "/user/login") + return + } + if ctx.User.WechatOpenId == "" { + ctx.SetCookie("redirect_to", setting.AppSubURL+ctx.Req.URL.RequestURI(), 0, setting.AppSubURL) + ctx.Redirect(setting.AppSubURL + "/explore/users") + } + } + // Redirect to log in page if auto-signin info is provided and has not signed in. if !options.SignOutRequired && !ctx.IsSigned && !auth.IsAPIPath(ctx.Req.URL.Path) && len(ctx.GetCookie(setting.CookieUserName)) > 0 { diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index eb1665cd2..e1b5ceaee 100755 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -997,7 +997,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Get("/search", repo.TopicSearch) }) m.Group("/from_wechat", func() { - m.Get("/event", authentication.AcceptWechatEvent) + m.Get("/event", authentication.ValidEventSource) m.Post("/event", authentication.AcceptWechatEvent) }) }, securityHeaders(), context.APIContexter(), sudo()) diff --git a/routers/authentication/wechat.go b/routers/authentication/wechat.go index f720332bb..12cc19500 100644 --- a/routers/authentication/wechat.go +++ b/routers/authentication/wechat.go @@ -40,6 +40,42 @@ func GetQRCode4Bind(ctx *context.Context) { }) } +// GetQRCode4Bind get QR code for wechat binding +func GetBindStatus(ctx *context.Context) { + //var status int + //sceneStr := ctx.Query("sceneStr") + //val, _ := redis_client.Get(redis_key.WechatBindingUserIdKey(sceneStr)) + //if val == "" { + // ctx.JSON(200, map[string]interface{}{ + // "code": "9999", + // "msg": "Get QR code failed", + // "data": + // //todo 继续完善查询接口,注意性能 + // //todo 二维码重定向页面需要给一下 + // //todo 微信推送Ng转发验证 + // //todo 整体联调 + // }) + // return + //} + // + //userId, _ := strconv.ParseInt(val, 10, 64) + // + //r, err := createQRCode4Bind(userId) + //if err != nil { + // ctx.JSON(200, map[string]interface{}{ + // "code": "9999", + // "msg": "Get QR code failed", + // }) + // return + //} + + ctx.JSON(200, map[string]interface{}{ + "code": "00", + "msg": "success", + //"data": r, + }) +} + func createQRCode4Bind(userId int64) (*QRCodeResponse, error) { sceneStr := gouuid.NewV4().String() r := wechat.GetWechatQRCode4Bind(sceneStr) diff --git a/routers/authentication/wechat_event.go b/routers/authentication/wechat_event.go index 8999f771f..494d2cd89 100644 --- a/routers/authentication/wechat_event.go +++ b/routers/authentication/wechat_event.go @@ -63,6 +63,12 @@ func AcceptWechatEvent(ctx *context.Context) { MsgType: "text", Content: "启智账号认证微信成功", } - redis_client.Del(key) ctx.XML(200, reply) } + +// ValidEventSource +func ValidEventSource(ctx *context.Context) { + echostr := ctx.Query("echostr") + ctx.Write([]byte(echostr)) + return +} diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 9613b43cd..e5d5bae3b 100755 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -275,6 +275,7 @@ func RegisterRoutes(m *macaron.Macaron) { ignSignInAndCsrf := context.Toggle(&context.ToggleOptions{DisableCSRF: true}) reqSignOut := context.Toggle(&context.ToggleOptions{SignOutRequired: true}) reqBasicAuth := context.Toggle(&context.ToggleOptions{BasicAuthRequired: true, DisableCSRF: true}) + reqWechatBind := context.Toggle(&context.ToggleOptions{WechatAuthRequired: true}) bindIgnErr := binding.BindIgnErr validation.AddBindingRules() @@ -394,7 +395,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/authentication/wechat", func() { m.Get("/qrCode4Bind", authentication.GetQRCode4Bind) - m.Post("/grant", bindIgnErr(auth.GrantApplicationForm{}), user.GrantApplicationOAuth) + m.Get("/bindStatus", authentication.GetBindStatus) // TODO manage redirection m.Post("/authorize", bindIgnErr(auth.AuthorizationForm{}), user.AuthorizeOAuth) }, reqSignIn) @@ -1033,7 +1034,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/debugjob", func() { m.Get("", reqRepoCloudBrainReader, repo.DebugJobIndex) - }, context.RepoRef()) + }, context.RepoRef(), reqWechatBind) m.Group("/modelarts", func() { m.Group("/notebook", func() { From 7545c65565e9cc7881af8e59b43fe3986659e467 Mon Sep 17 00:00:00 2001 From: Gitea Date: Mon, 21 Feb 2022 11:08:54 +0800 Subject: [PATCH 06/47] #1494 update --- routers/authentication/wechat_event.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/authentication/wechat_event.go b/routers/authentication/wechat_event.go index 494d2cd89..e007902a9 100644 --- a/routers/authentication/wechat_event.go +++ b/routers/authentication/wechat_event.go @@ -45,7 +45,7 @@ func AcceptWechatEvent(ctx *context.Context) { we := WechatEvent{} xml.Unmarshal(b, &we) - log.Info("accept wechat event= %v", b) + log.Info("accept wechat event= %v", we) key := redis_key.WechatBindingUserIdKey(we.EventKey) val, _ := redis_client.Get(key) if val == "" { From 4f44b1ca9fae8182595fdbf3b42e1dbfeba08d23 Mon Sep 17 00:00:00 2001 From: Gitea Date: Mon, 21 Feb 2022 12:03:09 +0800 Subject: [PATCH 07/47] #1494 update --- routers/authentication/wechat_event.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/routers/authentication/wechat_event.go b/routers/authentication/wechat_event.go index e007902a9..afd773256 100644 --- a/routers/authentication/wechat_event.go +++ b/routers/authentication/wechat_event.go @@ -45,7 +45,7 @@ func AcceptWechatEvent(ctx *context.Context) { we := WechatEvent{} xml.Unmarshal(b, &we) - log.Info("accept wechat event= %v", we) + log.Info("accept wechat event= %+v", we) key := redis_key.WechatBindingUserIdKey(we.EventKey) val, _ := redis_client.Get(key) if val == "" { @@ -53,6 +53,8 @@ func AcceptWechatEvent(ctx *context.Context) { ctx.XML(200, "") return } + //todo 已绑定微信号的如何处理? + //todo 取消关注事件记得过滤 userId, _ := strconv.ParseInt(val, 10, 64) //更新微信openId和流水 wechat.BindWechat(userId, we.EventKey) From eca19479ddb947a858c0702ad0a8277faae25bbb Mon Sep 17 00:00:00 2001 From: Gitea Date: Mon, 21 Feb 2022 14:17:08 +0800 Subject: [PATCH 08/47] #1494 update --- modules/auth/wechat/client.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/auth/wechat/client.go b/modules/auth/wechat/client.go index 680e0bb34..bb1772b2b 100644 --- a/modules/auth/wechat/client.go +++ b/modules/auth/wechat/client.go @@ -42,11 +42,11 @@ type QRCodeRequest struct { } type ActionInfo struct { - Scene Scene + Scene Scene `json:"scene"` } type Scene struct { - Scene_str string + Scene_str string `json:"scene_str"` } type ErrorResponse struct { From 3b85953513c40360c24b3f3011b7bbbcf0cb99a6 Mon Sep 17 00:00:00 2001 From: Gitea Date: Mon, 21 Feb 2022 14:34:21 +0800 Subject: [PATCH 09/47] #1494 update --- modules/auth/wechat/event.go | 1 - modules/auth/wechat/event_handle.go | 54 ++++++++++++++++++++++++++ routers/authentication/wechat_event.go | 51 ++++-------------------- 3 files changed, 61 insertions(+), 45 deletions(-) delete mode 100644 modules/auth/wechat/event.go create mode 100644 modules/auth/wechat/event_handle.go diff --git a/modules/auth/wechat/event.go b/modules/auth/wechat/event.go deleted file mode 100644 index ecd4201a5..000000000 --- a/modules/auth/wechat/event.go +++ /dev/null @@ -1 +0,0 @@ -package wechat diff --git a/modules/auth/wechat/event_handle.go b/modules/auth/wechat/event_handle.go new file mode 100644 index 000000000..8fd30863b --- /dev/null +++ b/modules/auth/wechat/event_handle.go @@ -0,0 +1,54 @@ +package wechat + +import ( + "code.gitea.io/gitea/modules/redis/redis_client" + "code.gitea.io/gitea/modules/redis/redis_key" + "strconv" + "strings" +) + +// +// +// +// 123456789 +// +// +// +// +// +type WechatEvent struct { + ToUserName string + FromUserName string + CreateTime int64 + MsgType string + Event string + EventKey string + Ticket string +} + +type Xml struct { + ToUserName string + FromUserName string + CreateTime int64 + MsgType string + Content string +} + +func HandleSubscribeEvent(we WechatEvent) string { + eventKey := we.EventKey + if eventKey == "" { + return "" + } + sceneStr := strings.TrimPrefix(eventKey, "qrscene_") + key := redis_key.WechatBindingUserIdKey(sceneStr) + val, _ := redis_client.Get(key) + if val == "" { + return "" + } + //todo 已绑定微信号的如何处理? + //todo 取消关注事件记得过滤 + userId, _ := strconv.ParseInt(val, 10, 64) + //更新微信openId和流水 + BindWechat(userId, we.EventKey) + return "启智账号认证微信成功" +} diff --git a/routers/authentication/wechat_event.go b/routers/authentication/wechat_event.go index afd773256..162f1c182 100644 --- a/routers/authentication/wechat_event.go +++ b/routers/authentication/wechat_event.go @@ -4,66 +4,29 @@ import ( "code.gitea.io/gitea/modules/auth/wechat" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/modules/redis/redis_client" - "code.gitea.io/gitea/modules/redis/redis_key" "encoding/xml" "io/ioutil" - "strconv" "time" ) -// -// -// -// 123456789 -// -// -// -// -// -type WechatEvent struct { - ToUserName string - FromUserName string - CreateTime int64 - MsgType string - Event string - EventKey string - Ticket string -} - -type Xml struct { - ToUserName string - FromUserName string - CreateTime int64 - MsgType string - Content string -} - // AcceptWechatEvent func AcceptWechatEvent(ctx *context.Context) { b, _ := ioutil.ReadAll(ctx.Req.Request.Body) - we := WechatEvent{} + we := wechat.WechatEvent{} xml.Unmarshal(b, &we) log.Info("accept wechat event= %+v", we) - key := redis_key.WechatBindingUserIdKey(we.EventKey) - val, _ := redis_client.Get(key) - if val == "" { - log.Error("sceneStr is not exist,sceneStr=%s", we.EventKey) - ctx.XML(200, "") - return + var replyStr string + if we.Event == "subscribe" { + replyStr = wechat.HandleSubscribeEvent(we) } - //todo 已绑定微信号的如何处理? - //todo 取消关注事件记得过滤 - userId, _ := strconv.ParseInt(val, 10, 64) - //更新微信openId和流水 - wechat.BindWechat(userId, we.EventKey) - reply := &Xml{ + + reply := &wechat.Xml{ ToUserName: we.FromUserName, FromUserName: we.ToUserName, CreateTime: time.Now().Unix(), MsgType: "text", - Content: "启智账号认证微信成功", + Content: replyStr, } ctx.XML(200, reply) } From 13665f17c523ad7408aae339f21cd3079342f241 Mon Sep 17 00:00:00 2001 From: Gitea Date: Mon, 21 Feb 2022 15:26:08 +0800 Subject: [PATCH 10/47] #1494 update --- modules/auth/wechat/bind.go | 22 ++++++------ modules/auth/wechat/event_handle.go | 17 ++++++--- routers/authentication/wechat.go | 53 +++++++++++++---------------- 3 files changed, 47 insertions(+), 45 deletions(-) diff --git a/modules/auth/wechat/bind.go b/modules/auth/wechat/bind.go index f00f26aaa..e060faf06 100644 --- a/modules/auth/wechat/bind.go +++ b/modules/auth/wechat/bind.go @@ -4,6 +4,18 @@ import ( "code.gitea.io/gitea/models" ) +type QRCode4BindCache struct { + UserId int64 + Status int +} + +const ( + BIND_STATUS_UNBIND = 0 + BIND_STATUS_SCANNED = 1 + BIND_STATUS_BOUND = 2 + BIND_STATUS_EXPIRED = 9 +) + func BindWechat(userId int64, wechatOpenId string) error { return models.BindWechatOpenId(userId, wechatOpenId) } @@ -11,13 +23,3 @@ func BindWechat(userId int64, wechatOpenId string) error { func UnbindWechat(userId int64) error { return models.UnbindWechatOpenId(userId) } - -func IsUserFinishBind(sceneStr string) bool { - //val, _ := redis_client.Get(redis_key.WechatBindingUserIdKey(sceneStr)) - //if val == "" { - // return false - //} - //userId, _ := strconv.ParseInt(val, 10, 64) - return false - -} diff --git a/modules/auth/wechat/event_handle.go b/modules/auth/wechat/event_handle.go index 8fd30863b..757d6498a 100644 --- a/modules/auth/wechat/event_handle.go +++ b/modules/auth/wechat/event_handle.go @@ -3,10 +3,13 @@ package wechat import ( "code.gitea.io/gitea/modules/redis/redis_client" "code.gitea.io/gitea/modules/redis/redis_key" - "strconv" + "encoding/json" "strings" + "time" ) +const BIND_REPLY = "启智账号认证微信成功" + // // // @@ -45,10 +48,14 @@ func HandleSubscribeEvent(we WechatEvent) string { if val == "" { return "" } + qrCache := new(QRCode4BindCache) + json.Unmarshal([]byte(val), qrCache) //todo 已绑定微信号的如何处理? - //todo 取消关注事件记得过滤 - userId, _ := strconv.ParseInt(val, 10, 64) //更新微信openId和流水 - BindWechat(userId, we.EventKey) - return "启智账号认证微信成功" + BindWechat(qrCache.UserId, we.FromUserName) + + qrCache.Status = BIND_STATUS_BOUND + jsonStr, _ := json.Marshal(qrCache) + redis_client.Setex(redis_key.WechatBindingUserIdKey(sceneStr), string(jsonStr), 60*time.Second) + return BIND_REPLY } diff --git a/routers/authentication/wechat.go b/routers/authentication/wechat.go index 12cc19500..dacda1180 100644 --- a/routers/authentication/wechat.go +++ b/routers/authentication/wechat.go @@ -7,8 +7,8 @@ import ( "code.gitea.io/gitea/modules/redis/redis_client" "code.gitea.io/gitea/modules/redis/redis_key" "code.gitea.io/gitea/modules/setting" + "encoding/json" "errors" - "fmt" gouuid "github.com/satori/go.uuid" "time" ) @@ -42,37 +42,26 @@ func GetQRCode4Bind(ctx *context.Context) { // GetQRCode4Bind get QR code for wechat binding func GetBindStatus(ctx *context.Context) { - //var status int - //sceneStr := ctx.Query("sceneStr") - //val, _ := redis_client.Get(redis_key.WechatBindingUserIdKey(sceneStr)) - //if val == "" { - // ctx.JSON(200, map[string]interface{}{ - // "code": "9999", - // "msg": "Get QR code failed", - // "data": - // //todo 继续完善查询接口,注意性能 - // //todo 二维码重定向页面需要给一下 - // //todo 微信推送Ng转发验证 - // //todo 整体联调 - // }) - // return - //} - // - //userId, _ := strconv.ParseInt(val, 10, 64) - // - //r, err := createQRCode4Bind(userId) - //if err != nil { - // ctx.JSON(200, map[string]interface{}{ - // "code": "9999", - // "msg": "Get QR code failed", - // }) - // return - //} - + sceneStr := ctx.Query("sceneStr") + val, _ := redis_client.Get(redis_key.WechatBindingUserIdKey(sceneStr)) + if val == "" { + ctx.JSON(200, map[string]interface{}{ + "code": "00", + "msg": "QR code expired", + "data": map[string]interface{}{ + "status": wechat.BIND_STATUS_EXPIRED, + }, + }) + return + } + qrCache := new(wechat.QRCode4BindCache) + json.Unmarshal([]byte(val), qrCache) ctx.JSON(200, map[string]interface{}{ "code": "00", "msg": "success", - //"data": r, + "data": map[string]interface{}{ + "status": qrCache.Status, + }, }) } @@ -83,7 +72,11 @@ func createQRCode4Bind(userId int64) (*QRCodeResponse, error) { return nil, errors.New("createQRCode4Bind failed") } - isOk, err := redis_client.Setex(redis_key.WechatBindingUserIdKey(sceneStr), fmt.Sprint(userId), time.Duration(setting.WechatQRCodeExpireSeconds)*time.Second) + jsonStr, _ := json.Marshal(&wechat.QRCode4BindCache{ + UserId: userId, + Status: wechat.BIND_STATUS_UNBIND, + }) + isOk, err := redis_client.Setex(redis_key.WechatBindingUserIdKey(sceneStr), string(jsonStr), time.Duration(setting.WechatQRCodeExpireSeconds)*time.Second) if err != nil { log.Error("createQRCode4Bind failed.e=%v", err) return nil, err From c3831a31af58f251b37d9dd81a8f47df70dbddb7 Mon Sep 17 00:00:00 2001 From: Gitea Date: Mon, 21 Feb 2022 15:50:13 +0800 Subject: [PATCH 11/47] #1494 update --- models/wechat_bind.go | 10 +++++----- modules/auth/wechat/bind.go | 4 ++-- routers/authentication/wechat.go | 11 ++++++++++- routers/routes/routes.go | 3 +-- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/models/wechat_bind.go b/models/wechat_bind.go index ab2d1e06d..b89a68cd9 100644 --- a/models/wechat_bind.go +++ b/models/wechat_bind.go @@ -47,7 +47,7 @@ func BindWechatOpenId(userId int64, wechatOpenId string) error { return sess.Commit() } -func UnbindWechatOpenId(userId int64) error { +func UnbindWechatOpenId(userId int64, oldWechatOpenID string) error { sess := x.NewSession() defer sess.Close() if err := sess.Begin(); err != nil { @@ -55,7 +55,7 @@ func UnbindWechatOpenId(userId int64) error { } param := &User{WechatOpenId: ""} - n, err := x.Where("ID = ?", userId).Update(param) + n, err := x.Where("ID = ? AND wechat_open_id =?", userId, oldWechatOpenID).Update(param) if err != nil { log.Error("update wechat_open_id failed,e=%v", err) return err @@ -64,10 +64,10 @@ func UnbindWechatOpenId(userId int64) error { log.Error("update wechat_open_id failed,user not exist,userId=%d", userId) return nil } - //todo 是否记录原有微信openId logParam := &WechatBindLog{ - UserID: userId, - Action: int(WECHAT_UNBIND), + UserID: userId, + WechatOpenId: oldWechatOpenID, + Action: int(WECHAT_UNBIND), } sess.Insert(logParam) return sess.Commit() diff --git a/modules/auth/wechat/bind.go b/modules/auth/wechat/bind.go index e060faf06..54937e4e1 100644 --- a/modules/auth/wechat/bind.go +++ b/modules/auth/wechat/bind.go @@ -20,6 +20,6 @@ func BindWechat(userId int64, wechatOpenId string) error { return models.BindWechatOpenId(userId, wechatOpenId) } -func UnbindWechat(userId int64) error { - return models.UnbindWechatOpenId(userId) +func UnbindWechat(userId int64, oldWechatOpenId string) error { + return models.UnbindWechatOpenId(userId, oldWechatOpenId) } diff --git a/routers/authentication/wechat.go b/routers/authentication/wechat.go index dacda1180..0139bb09f 100644 --- a/routers/authentication/wechat.go +++ b/routers/authentication/wechat.go @@ -40,7 +40,7 @@ func GetQRCode4Bind(ctx *context.Context) { }) } -// GetQRCode4Bind get QR code for wechat binding +// GetBindStatus func GetBindStatus(ctx *context.Context) { sceneStr := ctx.Query("sceneStr") val, _ := redis_client.Get(redis_key.WechatBindingUserIdKey(sceneStr)) @@ -65,6 +65,15 @@ func GetBindStatus(ctx *context.Context) { }) } +// UnbindWechat +func UnbindWechat(ctx *context.Context) { + wechat.UnbindWechat(ctx.User.ID, ctx.User.WechatOpenId) + ctx.JSON(200, map[string]interface{}{ + "code": "00", + "msg": "success", + }) +} + func createQRCode4Bind(userId int64) (*QRCodeResponse, error) { sceneStr := gouuid.NewV4().String() r := wechat.GetWechatQRCode4Bind(sceneStr) diff --git a/routers/routes/routes.go b/routers/routes/routes.go index e5d5bae3b..7fc5fa671 100755 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -396,8 +396,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/authentication/wechat", func() { m.Get("/qrCode4Bind", authentication.GetQRCode4Bind) m.Get("/bindStatus", authentication.GetBindStatus) - // TODO manage redirection - m.Post("/authorize", bindIgnErr(auth.AuthorizationForm{}), user.AuthorizeOAuth) + m.Post("/unbind", authentication.UnbindWechat) }, reqSignIn) m.Group("/user/settings", func() { From 4ee2f3d3ee0a975720112a4e1dd321c321762bd2 Mon Sep 17 00:00:00 2001 From: Gitea Date: Mon, 21 Feb 2022 16:20:09 +0800 Subject: [PATCH 12/47] #1494 update --- models/wechat_bind.go | 3 +-- routers/authentication/wechat.go | 5 ++++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/models/wechat_bind.go b/models/wechat_bind.go index b89a68cd9..f75188280 100644 --- a/models/wechat_bind.go +++ b/models/wechat_bind.go @@ -54,8 +54,7 @@ func UnbindWechatOpenId(userId int64, oldWechatOpenID string) error { return err } - param := &User{WechatOpenId: ""} - n, err := x.Where("ID = ? AND wechat_open_id =?", userId, oldWechatOpenID).Update(param) + n, err := x.Table(new(User)).Where("ID = ? AND wechat_open_id =?", userId, oldWechatOpenID).Update(map[string]interface{}{"wechat_open_id": ""}) if err != nil { log.Error("update wechat_open_id failed,e=%v", err) return err diff --git a/routers/authentication/wechat.go b/routers/authentication/wechat.go index 0139bb09f..4362b251e 100644 --- a/routers/authentication/wechat.go +++ b/routers/authentication/wechat.go @@ -67,7 +67,10 @@ func GetBindStatus(ctx *context.Context) { // UnbindWechat func UnbindWechat(ctx *context.Context) { - wechat.UnbindWechat(ctx.User.ID, ctx.User.WechatOpenId) + if ctx.User.WechatOpenId != "" { + wechat.UnbindWechat(ctx.User.ID, ctx.User.WechatOpenId) + } + ctx.JSON(200, map[string]interface{}{ "code": "00", "msg": "success", From 09c3d777d649759e581f7e6dfe5d7cf02f226346 Mon Sep 17 00:00:00 2001 From: Gitea Date: Mon, 21 Feb 2022 17:16:45 +0800 Subject: [PATCH 13/47] #1494 add default wechat bind page --- modules/context/auth.go | 2 +- routers/authentication/wechat.go | 8 ++++++++ routers/routes/routes.go | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/modules/context/auth.go b/modules/context/auth.go index c844040d7..48a23e421 100755 --- a/modules/context/auth.go +++ b/modules/context/auth.go @@ -135,7 +135,7 @@ func Toggle(options *ToggleOptions) macaron.Handler { } if ctx.User.WechatOpenId == "" { ctx.SetCookie("redirect_to", setting.AppSubURL+ctx.Req.URL.RequestURI(), 0, setting.AppSubURL) - ctx.Redirect(setting.AppSubURL + "/explore/users") + ctx.Redirect(setting.AppSubURL + "/authentication/wechat/bind") } } diff --git a/routers/authentication/wechat.go b/routers/authentication/wechat.go index 4362b251e..866825fce 100644 --- a/routers/authentication/wechat.go +++ b/routers/authentication/wechat.go @@ -2,6 +2,7 @@ package authentication import ( "code.gitea.io/gitea/modules/auth/wechat" + "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/redis/redis_client" @@ -13,6 +14,8 @@ import ( "time" ) +const tplBindPage base.TplName = "repo/wx_autorize" + type QRCodeResponse struct { Url string Ticket string @@ -77,6 +80,11 @@ func UnbindWechat(ctx *context.Context) { }) } +// GetBindPage +func GetBindPage(ctx *context.Context) { + ctx.HTML(200, tplBindPage) +} + func createQRCode4Bind(userId int64) (*QRCodeResponse, error) { sceneStr := gouuid.NewV4().String() r := wechat.GetWechatQRCode4Bind(sceneStr) diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 7fc5fa671..213c21733 100755 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -397,6 +397,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Get("/qrCode4Bind", authentication.GetQRCode4Bind) m.Get("/bindStatus", authentication.GetBindStatus) m.Post("/unbind", authentication.UnbindWechat) + m.Get("/bind", authentication.GetBindPage) }, reqSignIn) m.Group("/user/settings", func() { From deab16c88096480356570e527ffd18fa4586a6f1 Mon Sep 17 00:00:00 2001 From: Gitea Date: Mon, 21 Feb 2022 17:27:49 +0800 Subject: [PATCH 14/47] #1494 fix --- routers/authentication/wechat_event.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/routers/authentication/wechat_event.go b/routers/authentication/wechat_event.go index 162f1c182..67149de5d 100644 --- a/routers/authentication/wechat_event.go +++ b/routers/authentication/wechat_event.go @@ -21,6 +21,10 @@ func AcceptWechatEvent(ctx *context.Context) { replyStr = wechat.HandleSubscribeEvent(we) } + if replyStr == "" { + log.Info("reply str is empty") + return + } reply := &wechat.Xml{ ToUserName: we.FromUserName, FromUserName: we.ToUserName, From cf4be7e4b2a20cc5a4350484b7f25b525a42ceb3 Mon Sep 17 00:00:00 2001 From: Gitea Date: Mon, 21 Feb 2022 17:47:58 +0800 Subject: [PATCH 15/47] #1494 fix --- modules/auth/wechat/event_handle.go | 4 +++- routers/authentication/wechat_event.go | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/auth/wechat/event_handle.go b/modules/auth/wechat/event_handle.go index 757d6498a..9e05f5e6e 100644 --- a/modules/auth/wechat/event_handle.go +++ b/modules/auth/wechat/event_handle.go @@ -4,6 +4,7 @@ import ( "code.gitea.io/gitea/modules/redis/redis_client" "code.gitea.io/gitea/modules/redis/redis_key" "encoding/json" + "encoding/xml" "strings" "time" ) @@ -29,7 +30,8 @@ type WechatEvent struct { Ticket string } -type Xml struct { +type EventReply struct { + XMLName xml.Name `xml:"xml"` ToUserName string FromUserName string CreateTime int64 diff --git a/routers/authentication/wechat_event.go b/routers/authentication/wechat_event.go index 67149de5d..35ba23166 100644 --- a/routers/authentication/wechat_event.go +++ b/routers/authentication/wechat_event.go @@ -25,7 +25,7 @@ func AcceptWechatEvent(ctx *context.Context) { log.Info("reply str is empty") return } - reply := &wechat.Xml{ + reply := &wechat.EventReply{ ToUserName: we.FromUserName, FromUserName: we.ToUserName, CreateTime: time.Now().Unix(), From 7e5a5c6cd57647a000e941151d1599ab01742463 Mon Sep 17 00:00:00 2001 From: Gitea Date: Tue, 22 Feb 2022 14:17:27 +0800 Subject: [PATCH 16/47] #1494 add wechat auth switch --- models/wechat_bind.go | 12 +++++++++ modules/auth/wechat/bind.go | 41 +++++++++++++++++++++++++++++ modules/auth/wechat/event_handle.go | 28 ++++++++++++++------ modules/context/auth.go | 2 +- modules/setting/setting.go | 2 ++ 5 files changed, 76 insertions(+), 9 deletions(-) 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..36193d4f9 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,49 @@ const ( BIND_STATUS_EXPIRED = 9 ) +type WechatAccountUsedError struct { +} + +func (err WechatAccountUsedError) Error() string { + return fmt.Sprint("wechat account has been used") +} + +type OpenIAccountUsedError struct { +} + +func (err OpenIAccountUsedError) Error() string { + return fmt.Sprint("openI account has been used") +} + 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 WechatAccountUsedError{} + } + if !IsUserAvailableForWechatBind(userId, wechatOpenId) { + log.Error("openI account has been used,userId=%d wechatOpenId=%s", userId, wechatOpenId) + return OpenIAccountUsedError{} + } 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..3453aa0b2 100644 --- a/modules/auth/wechat/event_handle.go +++ b/modules/auth/wechat/event_handle.go @@ -9,7 +9,11 @@ import ( "time" ) -const BIND_REPLY = "启智账号认证微信成功" +const ( + BIND_REPLY_SUCCESS = "启智账号认证微信成功" + BIND_REPLY_WECHAT_ACCOUNT_USED = "认证失败,您的微信号已绑定其他启智账号" + BIND_REPLY_OPENI_ACCOUNT_USED = "认证失败,您待认证的启智账号已绑定其他微信号" +) // // @@ -52,12 +56,20 @@ 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 _, ok := err.(WechatAccountUsedError); ok { + return BIND_REPLY_WECHAT_ACCOUNT_USED + } + if _, ok := err.(OpenIAccountUsedError); ok { + return BIND_REPLY_OPENI_ACCOUNT_USED + } + } + 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() From 433673ef5a0ce9353c611010abadfaebd995a251 Mon Sep 17 00:00:00 2001 From: Gitea Date: Tue, 22 Feb 2022 16:35:46 +0800 Subject: [PATCH 17/47] #1494 update --- modules/auth/wechat/bind.go | 23 ++++++++++++++--------- modules/auth/wechat/event_handle.go | 14 +++----------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/modules/auth/wechat/bind.go b/modules/auth/wechat/bind.go index 36193d4f9..a2172718a 100644 --- a/modules/auth/wechat/bind.go +++ b/modules/auth/wechat/bind.go @@ -18,28 +18,33 @@ const ( BIND_STATUS_EXPIRED = 9 ) -type WechatAccountUsedError struct { -} +const ( + BIND_REPLY_SUCCESS = "启智账号认证微信成功" + BIND_REPLY_WECHAT_ACCOUNT_USED = "认证失败,您的微信号已绑定其他启智账号" + BIND_REPLY_OPENI_ACCOUNT_USED = "认证失败,您待认证的启智账号已绑定其他微信号" + BIND_REPLY_FAILED_DEFAULT = "微信认证失败" +) -func (err WechatAccountUsedError) Error() string { - return fmt.Sprint("wechat account has been used") +type WechatBindError struct { + Reply string } -type OpenIAccountUsedError struct { +func NewWechatBindError(reply string) WechatBindError { + return WechatBindError{Reply: reply} } -func (err OpenIAccountUsedError) Error() string { - return fmt.Sprint("openI account has been used") +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 WechatAccountUsedError{} + 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 OpenIAccountUsedError{} + return NewWechatBindError(BIND_REPLY_OPENI_ACCOUNT_USED) } return models.BindWechatOpenId(userId, wechatOpenId) } diff --git a/modules/auth/wechat/event_handle.go b/modules/auth/wechat/event_handle.go index 3453aa0b2..c49c6d763 100644 --- a/modules/auth/wechat/event_handle.go +++ b/modules/auth/wechat/event_handle.go @@ -9,12 +9,6 @@ import ( "time" ) -const ( - BIND_REPLY_SUCCESS = "启智账号认证微信成功" - BIND_REPLY_WECHAT_ACCOUNT_USED = "认证失败,您的微信号已绑定其他启智账号" - BIND_REPLY_OPENI_ACCOUNT_USED = "认证失败,您待认证的启智账号已绑定其他微信号" -) - // // // @@ -59,12 +53,10 @@ func HandleSubscribeEvent(we WechatEvent) string { if qrCache.Status == BIND_STATUS_UNBIND { err := BindWechat(qrCache.UserId, we.FromUserName) if err != nil { - if _, ok := err.(WechatAccountUsedError); ok { - return BIND_REPLY_WECHAT_ACCOUNT_USED - } - if _, ok := err.(OpenIAccountUsedError); ok { - return BIND_REPLY_OPENI_ACCOUNT_USED + if err, ok := err.(WechatBindError); ok { + return err.Reply } + return BIND_REPLY_FAILED_DEFAULT } qrCache.Status = BIND_STATUS_BOUND jsonStr, _ := json.Marshal(qrCache) From df021e7e52e284356c398af54b16500bab51a9ac Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Tue, 22 Feb 2022 16:54:27 +0800 Subject: [PATCH 18/47] fix issue --- public/img/qrcode_reload.png | Bin 0 -> 11151 bytes templates/repo/wx_autorize.tmpl | 28 ++--- web_src/js/components/WxAutorize.vue | 147 +++++++++++++++++++++++++++ web_src/js/index.js | 14 ++- 4 files changed, 170 insertions(+), 19 deletions(-) create mode 100644 public/img/qrcode_reload.png create mode 100644 web_src/js/components/WxAutorize.vue diff --git a/public/img/qrcode_reload.png b/public/img/qrcode_reload.png new file mode 100644 index 0000000000000000000000000000000000000000..81ff160b176d5df89aaa95cd87346609952767c4 GIT binary patch literal 11151 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�D9+lVm8~>N`YQ81{Toh%kgl)s?A?)|`!8-Li+KC6XQpSS`I5i9@6lAZ zqg7zGULoHkuZ8}x5Un-N2xdFj{jyZ&jN9gljMiHx19Ed|!Sa@NwcK=O&p~cCEON!E{_v(#HMop8WwZ%_^xb$0%QYO=QlkTa}w&^&U;lPPX z!G|CGAr&w9r-bk3!|Fs@{Me_+HpdseY9}yH?_VArj-9*~mqIG3FSWcRLv3h^&vcD7 zpsv`078YT=UG|^*kw^9#4I(D>ndFVi?NY{{$ex1brB5Ahxe$uD^*)w|T;^9Q6Da*7Ctk zoh(i(+K+6?ArybY?7zw#ZP2mb%Qv;6mqD|+zTqIFo-%14xLRDXW1}Oi>KV8u3me22 z3T@}uB9Nd{JJQbG`&oPPd&+y+DH+WsjcZGPmokAZjy=`{RvSR3Fx@9v0iWZUay2T{# z8~q&VtbUhES05M=>1@s3kP=QQW1LI@B<@SCThBr7nw%NoGo~$!rk^i1vJ@z^jh`Vn zTt;@~D1-%Ws{++vg7g)X*H~;xn89v~RN)OQDBh&INuGgC1Z42Vv`hLbI7!poI%SeA za19f4XJ)>J>0Ge4{|0(2;`4S6gdpJ@%^xHpl-g{`XoDohdIv-ZXU$endsPEePZytsj?`Q2ekMzZJCkqZFgz1 z5#ak>0IZUdPp7Zcyc%*{po+X+xn`AN@v^D+4O4GRhx~=~g3(`g6S*rx(?&zp@>Tbv zWI4uBG}VyOGMyo);144|pVDh;fhuf+QzDl`{QYEkM;(Mk)*Gf)uPNCd(1Z6W8e)t^ z1NcFk4JFLj%xhPp4Tg9+D+RhUpWx5RNt)epfeU*tPCxOWt|CiD#M`X`KJJa^bw?VJ zI?hAehVwr|H`|;Ki&k`#qgF*yM$$qw?gJHwgsYd$F@ubt$T@iR`t10(|e4VAONl0%0z>aDzrW&oQpRUt3UIHclcoIYBV-(^fhHY$ouxC>3txpCEM zK5h_i^r$o_jX9ay<72SV$HTYNSmYpX&g>VNsRm}1 z`%C(ZiNj3~Zv78u+?b-VzZvE4m1 zY(wTvG+XB6*v>r8`IcBlt1h1&82KzEnwJ`!PKX{Lw-_3kRBjz6%tqunt}IoeqE>5qHgy@=<|U>E`yr_q~a%P zCi%HeKTP&rUd$G=$vsfS(7P#o)N@#EmGLp&JgIyVgyCg#Lql~Cv-1u{MX8i){Um=N{%u>Na*=f8J*{%I)vxBkw5>HYjC z(*M(X`p=Hee>S52zxq4>o#20HFRkPGS00R2&grGKpGNiN4&9 {{template "base/head" .}} +
{{template "repo/header" .}} {{template "base/alert" .}} -
-
-
-

微信扫码认证

-

请绑定微信,然后再使用启智算力环境

-
- -
- 绑定微信代表已阅读并接受OpenI启智社区AI协作平台使用协议 -
-
-
-
\ No newline at end of file +
+
+
+
+ + + +
+{{template "base/footer" .}} diff --git a/web_src/js/components/WxAutorize.vue b/web_src/js/components/WxAutorize.vue new file mode 100644 index 000000000..de186932c --- /dev/null +++ b/web_src/js/components/WxAutorize.vue @@ -0,0 +1,147 @@ + + + + + diff --git a/web_src/js/index.js b/web_src/js/index.js index 6bc0d2b88..a654a10a7 100755 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -40,6 +40,8 @@ import EditTopics from './components/EditTopics.vue'; import DataAnalysis from './components/DataAnalysis.vue' import Contributors from './components/Contributors.vue' import Model from './components/Model.vue'; +import WxAutorize from './components/WxAutorize.vue' + Vue.use(ElementUI); Vue.prototype.$axios = axios; @@ -2919,6 +2921,7 @@ $(document).ready(async () => { initVueImages(); initVueModel(); initVueDataAnalysis(); + initVueWxAutorize(); initTeamSettings(); initCtrlEnterSubmit(); initNavbarContentToggle(); @@ -3713,7 +3716,16 @@ function initObsUploader() { template: '' }); } - +function initVueWxAutorize() { + const el = document.getElementById('WxAutorize'); + if (!el) { + return; + } + new Vue({ + el:el, + render: h => h(WxAutorize) + }); +} window.timeAddManual = function () { $('.mini.modal') From 5490e9806ba9d222122165c66fdd3cc982ea2018 Mon Sep 17 00:00:00 2001 From: Gitea Date: Tue, 22 Feb 2022 17:38:22 +0800 Subject: [PATCH 19/47] #1494 add log --- modules/auth/wechat/client.go | 3 +++ modules/auth/wechat/event_handle.go | 9 +++++++++ modules/auth/wechat/qr_code.go | 3 +++ routers/authentication/wechat.go | 5 +++-- routers/authentication/wechat_event.go | 8 ++++++-- 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/modules/auth/wechat/client.go b/modules/auth/wechat/client.go index bb1772b2b..6734977a1 100644 --- a/modules/auth/wechat/client.go +++ b/modules/auth/wechat/client.go @@ -62,6 +62,7 @@ func getWechatRestyClient() *resty.Client { return client } +// api doc:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html func callAccessToken() *AccessTokenResponse { client := getWechatRestyClient() @@ -79,6 +80,8 @@ func callAccessToken() *AccessTokenResponse { return &result } +//callQRCodeCreate call the wechat api to create qr-code, +// api doc: https://developers.weixin.qq.com/doc/offiaccount/Account_Management/Generating_a_Parametric_QR_Code.html func callQRCodeCreate(sceneStr string) (*QRCodeResponse, bool) { client := getWechatRestyClient() diff --git a/modules/auth/wechat/event_handle.go b/modules/auth/wechat/event_handle.go index c49c6d763..b40ab3101 100644 --- a/modules/auth/wechat/event_handle.go +++ b/modules/auth/wechat/event_handle.go @@ -37,6 +37,15 @@ type EventReply struct { Content string } +const ( + WECHAT_EVENT_SUBSCRIBE = "subscribe" + WECHAT_EVENT_SCAN = "SCAN" +) + +const ( + WECHAT_MSG_TYPE_TEXT = "text" +) + func HandleSubscribeEvent(we WechatEvent) string { eventKey := we.EventKey if eventKey == "" { diff --git a/modules/auth/wechat/qr_code.go b/modules/auth/wechat/qr_code.go index 5506cecb7..8c2da55c9 100644 --- a/modules/auth/wechat/qr_code.go +++ b/modules/auth/wechat/qr_code.go @@ -1,8 +1,11 @@ package wechat +import "code.gitea.io/gitea/modules/log" + func GetWechatQRCode4Bind(sceneStr string) *QRCodeResponse { result, retryFlag := callQRCodeCreate(sceneStr) if retryFlag { + log.Info("retry wechat qr-code calling,sceneStr=%s", sceneStr) refreshAccessTokenCache() result, _ = callQRCodeCreate(sceneStr) } diff --git a/routers/authentication/wechat.go b/routers/authentication/wechat.go index 866825fce..7a62850e2 100644 --- a/routers/authentication/wechat.go +++ b/routers/authentication/wechat.go @@ -43,7 +43,7 @@ func GetQRCode4Bind(ctx *context.Context) { }) } -// GetBindStatus +// GetBindStatus the web page will poll the service to get bind status func GetBindStatus(ctx *context.Context) { sceneStr := ctx.Query("sceneStr") val, _ := redis_client.Get(redis_key.WechatBindingUserIdKey(sceneStr)) @@ -86,6 +86,7 @@ func GetBindPage(ctx *context.Context) { } func createQRCode4Bind(userId int64) (*QRCodeResponse, error) { + log.Info("start to create qr-code for binding.userId=%d", userId) sceneStr := gouuid.NewV4().String() r := wechat.GetWechatQRCode4Bind(sceneStr) if r == nil { @@ -98,7 +99,7 @@ func createQRCode4Bind(userId int64) (*QRCodeResponse, error) { }) isOk, err := redis_client.Setex(redis_key.WechatBindingUserIdKey(sceneStr), string(jsonStr), time.Duration(setting.WechatQRCodeExpireSeconds)*time.Second) if err != nil { - log.Error("createQRCode4Bind failed.e=%v", err) + log.Error("createQRCode4Bind failed.e=%+v", err) return nil, err } if !isOk { diff --git a/routers/authentication/wechat_event.go b/routers/authentication/wechat_event.go index 35ba23166..9b1cebec6 100644 --- a/routers/authentication/wechat_event.go +++ b/routers/authentication/wechat_event.go @@ -10,6 +10,8 @@ import ( ) // AcceptWechatEvent +// https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_event_pushes.html +// https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Passive_user_reply_message.html func AcceptWechatEvent(ctx *context.Context) { b, _ := ioutil.ReadAll(ctx.Req.Request.Body) we := wechat.WechatEvent{} @@ -17,8 +19,10 @@ func AcceptWechatEvent(ctx *context.Context) { log.Info("accept wechat event= %+v", we) var replyStr string - if we.Event == "subscribe" { + switch we.Event { + case wechat.WECHAT_EVENT_SUBSCRIBE, wechat.WECHAT_EVENT_SCAN: replyStr = wechat.HandleSubscribeEvent(we) + break } if replyStr == "" { @@ -29,7 +33,7 @@ func AcceptWechatEvent(ctx *context.Context) { ToUserName: we.FromUserName, FromUserName: we.ToUserName, CreateTime: time.Now().Unix(), - MsgType: "text", + MsgType: wechat.WECHAT_MSG_TYPE_TEXT, Content: replyStr, } ctx.XML(200, reply) From 3405e302f7fa50c8b0f10993027ff76f431e2ee8 Mon Sep 17 00:00:00 2001 From: Gitea Date: Tue, 22 Feb 2022 18:08:36 +0800 Subject: [PATCH 20/47] #1494 update --- modules/auth/wechat/bind.go | 2 +- routers/routes/routes.go | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/modules/auth/wechat/bind.go b/modules/auth/wechat/bind.go index a2172718a..e56e9734e 100644 --- a/modules/auth/wechat/bind.go +++ b/modules/auth/wechat/bind.go @@ -19,7 +19,7 @@ const ( ) const ( - BIND_REPLY_SUCCESS = "启智账号认证微信成功" + BIND_REPLY_SUCCESS = "扫码成功,您可以使用OpenI启智社区算例环境。" BIND_REPLY_WECHAT_ACCOUNT_USED = "认证失败,您的微信号已绑定其他启智账号" BIND_REPLY_OPENI_ACCOUNT_USED = "认证失败,您待认证的启智账号已绑定其他微信号" BIND_REPLY_FAILED_DEFAULT = "微信认证失败" diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 213c21733..7241b8299 100755 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -985,17 +985,17 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/cloudbrain", func() { m.Group("/:jobid", func() { m.Get("", reqRepoCloudBrainReader, repo.CloudBrainShow) - m.Get("/debug", cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainDebug) + m.Get("/debug", reqWechatBind, cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainDebug) m.Post("/commit_image", cloudbrain.AdminOrJobCreaterRight, bindIgnErr(auth.CommitImageCloudBrainForm{}), repo.CloudBrainCommitImage) m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop) m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainDel) - m.Post("/restart", cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainRestart) + m.Post("/restart", reqWechatBind, cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainRestart) m.Get("/rate", reqRepoCloudBrainReader, repo.GetRate) m.Get("/models", reqRepoCloudBrainReader, repo.CloudBrainShowModels) m.Get("/download_model", cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainDownloadModel) }) - m.Get("/create", reqRepoCloudBrainWriter, repo.CloudBrainNew) - m.Post("/create", reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.CloudBrainCreate) + m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.CloudBrainNew) + m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.CloudBrainCreate) m.Group("/benchmark", func() { m.Get("", reqRepoCloudBrainReader, repo.CloudBrainBenchmarkIndex) @@ -1005,8 +1005,8 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.BenchmarkDel) m.Get("/rate", reqRepoCloudBrainReader, repo.GetRate) }) - m.Get("/create", reqRepoCloudBrainWriter, repo.CloudBrainBenchmarkNew) - m.Post("/create", reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.CloudBrainBenchmarkCreate) + m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.CloudBrainBenchmarkNew) + m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.CloudBrainBenchmarkCreate) m.Get("/get_child_types", repo.GetChildTypes) }) }, context.RepoRef()) @@ -1034,7 +1034,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/debugjob", func() { m.Get("", reqRepoCloudBrainReader, repo.DebugJobIndex) - }, context.RepoRef(), reqWechatBind) + }, context.RepoRef()) m.Group("/modelarts", func() { m.Group("/notebook", func() { @@ -1068,8 +1068,8 @@ func RegisterRoutes(m *macaron.Macaron) { m.Get("/create_version", cloudbrain.AdminOrJobCreaterRight, repo.TrainJobNewVersion) m.Post("/create_version", cloudbrain.AdminOrJobCreaterRight, bindIgnErr(auth.CreateModelArtsTrainJobForm{}), repo.TrainJobCreateVersion) }) - m.Get("/create", reqRepoCloudBrainWriter, repo.TrainJobNew) - m.Post("/create", reqRepoCloudBrainWriter, bindIgnErr(auth.CreateModelArtsTrainJobForm{}), repo.TrainJobCreate) + m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.TrainJobNew) + m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateModelArtsTrainJobForm{}), repo.TrainJobCreate) m.Get("/para-config-list", reqRepoCloudBrainReader, repo.TrainJobGetConfigList) }) @@ -1081,8 +1081,8 @@ func RegisterRoutes(m *macaron.Macaron) { m.Get("/result_download", cloudbrain.AdminOrJobCreaterRight, repo.ResultDownload) m.Get("/downloadall", repo.DownloadMultiResultFile) }) - m.Get("/create", reqRepoCloudBrainWriter, repo.InferenceJobNew) - m.Post("/create", reqRepoCloudBrainWriter, bindIgnErr(auth.CreateModelArtsInferenceJobForm{}), repo.InferenceJobCreate) + m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.InferenceJobNew) + m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateModelArtsInferenceJobForm{}), repo.InferenceJobCreate) }) }, context.RepoRef()) From f823e04a96a903d3a3562ba5ba0b91f52930ff0d Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Wed, 23 Feb 2022 09:59:37 +0800 Subject: [PATCH 21/47] #1494 update --- routers/authentication/wechat.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/routers/authentication/wechat.go b/routers/authentication/wechat.go index 7a62850e2..880e59623 100644 --- a/routers/authentication/wechat.go +++ b/routers/authentication/wechat.go @@ -82,6 +82,12 @@ func UnbindWechat(ctx *context.Context) { // GetBindPage func GetBindPage(ctx *context.Context) { + userId := ctx.User.ID + r, _ := createQRCode4Bind(userId) + if r != nil { + ctx.Data["qrcode"] = r + } + ctx.HTML(200, tplBindPage) } From f9bede5166f8c25d508a8d309f6fc86ff116806e Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Wed, 23 Feb 2022 11:17:45 +0800 Subject: [PATCH 22/47] #1494 update --- models/user.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/models/user.go b/models/user.go index 1aa7dac27..0103a6c0b 100755 --- a/models/user.go +++ b/models/user.go @@ -188,6 +188,11 @@ type SearchOrganizationsOptions struct { All bool } +// GenerateRandomAvatar generates a random avatar for user. +func (u *User) IsBindWechat() bool { + return u.WechatOpenId != "" +} + // ColorFormat writes a colored string to identify this struct func (u *User) ColorFormat(s fmt.State) { log.ColorFprintf(s, "%d:%s", From acae810f74547e4159a6936519cb96be20502393 Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Wed, 23 Feb 2022 15:09:12 +0800 Subject: [PATCH 23/47] #1494 add lock --- modules/auth/wechat/access_token.go | 35 ++++++++++++++---- modules/auth/wechat/qr_code.go | 2 +- modules/redis/redis_client/client.go | 17 ++++++++- modules/redis/redis_key/wechat_redis_key.go | 3 ++ modules/redis/redis_lock/lock.go | 40 +++++++++++++++++++++ 5 files changed, 89 insertions(+), 8 deletions(-) create mode 100644 modules/redis/redis_lock/lock.go diff --git a/modules/auth/wechat/access_token.go b/modules/auth/wechat/access_token.go index 1bfef2758..0a63bc2de 100644 --- a/modules/auth/wechat/access_token.go +++ b/modules/auth/wechat/access_token.go @@ -3,11 +3,14 @@ package wechat import ( "code.gitea.io/gitea/modules/redis/redis_client" "code.gitea.io/gitea/modules/redis/redis_key" + "code.gitea.io/gitea/modules/redis/redis_lock" "time" ) const EMPTY_REDIS_VAL = "Nil" +var accessTokenLock = redis_lock.NewDistributeLock() + func GetWechatAccessToken() string { token, _ := redis_client.Get(redis_key.WechatAccessTokenKey()) if token != "" { @@ -17,14 +20,37 @@ func GetWechatAccessToken() string { live, _ := redis_client.TTL(redis_key.WechatAccessTokenKey()) //refresh wechat access token when expire time less than 5 minutes if live > 0 && live < 300 { - refreshAccessTokenCache() + refreshAccessToken() } return token } - return refreshAccessTokenCache() + return refreshAndGetAccessToken() +} + +func refreshAccessToken() { + if ok := accessTokenLock.Lock(redis_key.AccessTokenLockKey(), 3*time.Second); ok { + defer accessTokenLock.UnLock(redis_key.AccessTokenLockKey()) + callAccessTokenAndUpdateCache() + } +} + +func refreshAndGetAccessToken() string { + if ok := accessTokenLock.LockWithWait(redis_key.AccessTokenLockKey(), 3*time.Second, 3*time.Second); ok { + defer accessTokenLock.UnLock(redis_key.AccessTokenLockKey()) + token, _ := redis_client.Get(redis_key.WechatAccessTokenKey()) + if token != "" { + if token == EMPTY_REDIS_VAL { + return "" + } + return token + } + return callAccessTokenAndUpdateCache() + } + return "" + } -func refreshAccessTokenCache() string { +func callAccessTokenAndUpdateCache() string { r := callAccessToken() var token string @@ -36,9 +62,6 @@ func refreshAccessTokenCache() string { redis_client.Setex(redis_key.WechatAccessTokenKey(), EMPTY_REDIS_VAL, 10*time.Second) return "" } - redis_client.Setex(redis_key.WechatAccessTokenKey(), token, time.Duration(r.Expires_in)*time.Second) - return token - } diff --git a/modules/auth/wechat/qr_code.go b/modules/auth/wechat/qr_code.go index 8c2da55c9..9d2f6ca04 100644 --- a/modules/auth/wechat/qr_code.go +++ b/modules/auth/wechat/qr_code.go @@ -6,7 +6,7 @@ func GetWechatQRCode4Bind(sceneStr string) *QRCodeResponse { result, retryFlag := callQRCodeCreate(sceneStr) if retryFlag { log.Info("retry wechat qr-code calling,sceneStr=%s", sceneStr) - refreshAccessTokenCache() + refreshAccessToken() result, _ = callQRCodeCreate(sceneStr) } return result diff --git a/modules/redis/redis_client/client.go b/modules/redis/redis_client/client.go index 5257da521..437aecdae 100644 --- a/modules/redis/redis_client/client.go +++ b/modules/redis/redis_client/client.go @@ -9,7 +9,6 @@ import ( "time" ) -//todo redis连接池 func Setex(key, value string, timeout time.Duration) (bool, error) { redisClient := labelmsg.Get() defer redisClient.Close() @@ -26,6 +25,22 @@ func Setex(key, value string, timeout time.Duration) (bool, error) { } +func Setnx(key, value string, timeout time.Duration) (bool, error) { + redisClient := labelmsg.Get() + defer redisClient.Close() + + seconds := int(math.Floor(timeout.Seconds())) + reply, err := redisClient.Do("SET", key, value, "NX", "EX", seconds) + if err != nil { + return false, err + } + if reply != "OK" { + return false, nil + } + return true, nil + +} + func Get(key string) (string, error) { redisClient := labelmsg.Get() defer redisClient.Close() diff --git a/modules/redis/redis_key/wechat_redis_key.go b/modules/redis/redis_key/wechat_redis_key.go index def7e93ee..1858576fd 100644 --- a/modules/redis/redis_key/wechat_redis_key.go +++ b/modules/redis/redis_key/wechat_redis_key.go @@ -9,3 +9,6 @@ func WechatBindingUserIdKey(sceneStr string) string { func WechatAccessTokenKey() string { return KeyJoin(PREFIX, "access_token") } +func AccessTokenLockKey() string { + return KeyJoin(PREFIX, "access_token_lock") +} diff --git a/modules/redis/redis_lock/lock.go b/modules/redis/redis_lock/lock.go new file mode 100644 index 000000000..4dce04c88 --- /dev/null +++ b/modules/redis/redis_lock/lock.go @@ -0,0 +1,40 @@ +package redis_lock + +import ( + "code.gitea.io/gitea/modules/redis/redis_client" + "time" +) + +type DistributeLock struct { +} + +func NewDistributeLock() *DistributeLock { + return &DistributeLock{} +} + +func (lock *DistributeLock) Lock(lockKey string, expireTime time.Duration) bool { + isOk, _ := redis_client.Setnx(lockKey, "", expireTime) + return isOk +} + +func (lock *DistributeLock) LockWithWait(lockKey string, expireTime time.Duration, waitTime time.Duration) bool { + start := time.Now().UnixMilli() + duration := waitTime.Milliseconds() + for { + isOk, _ := redis_client.Setnx(lockKey, "", expireTime) + if isOk { + return true + } + if time.Now().UnixMilli()-start > duration { + return false + } + time.Sleep(50 * time.Millisecond) + } + + return false +} + +func (lock *DistributeLock) UnLock(lockKey string) error { + _, err := redis_client.Del(lockKey) + return err +} From 8f59dc257c643599d3c1256dcaf18d2163a89e06 Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Wed, 23 Feb 2022 16:21:42 +0800 Subject: [PATCH 24/47] #1494 fix --- modules/redis/redis_lock/lock.go | 4 ++-- routers/api/v1/api.go | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/redis/redis_lock/lock.go b/modules/redis/redis_lock/lock.go index 4dce04c88..0faed3237 100644 --- a/modules/redis/redis_lock/lock.go +++ b/modules/redis/redis_lock/lock.go @@ -18,14 +18,14 @@ func (lock *DistributeLock) Lock(lockKey string, expireTime time.Duration) bool } func (lock *DistributeLock) LockWithWait(lockKey string, expireTime time.Duration, waitTime time.Duration) bool { - start := time.Now().UnixMilli() + start := time.Now().Unix() * 1000 duration := waitTime.Milliseconds() for { isOk, _ := redis_client.Setnx(lockKey, "", expireTime) if isOk { return true } - if time.Now().UnixMilli()-start > duration { + if time.Now().Unix()*1000-start > duration { return false } time.Sleep(50 * time.Millisecond) diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index e1b5ceaee..b7f53c783 100755 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -999,6 +999,8 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/from_wechat", func() { m.Get("/event", authentication.ValidEventSource) m.Post("/event", authentication.AcceptWechatEvent) + m.Get("/prd/event", authentication.ValidEventSource) + m.Post("/prd/event", authentication.AcceptWechatEvent) }) }, securityHeaders(), context.APIContexter(), sudo()) } From ba68e7997033d32fc151a786d9a87e6b8c93e749 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Wed, 23 Feb 2022 16:58:39 +0800 Subject: [PATCH 25/47] fix issue --- package-lock.json | 5 ++ package.json | 1 + templates/repo/modelarts/trainjob/show.tmpl | 5 +- templates/repo/wx_autorize.tmpl | 11 +-- templates/user/settings/profile.tmpl | 74 +++++++++++++++++++++ web_src/js/components/WxAutorize.vue | 2 + web_src/js/index.js | 2 + 7 files changed, 92 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 41a484f9e..e885641a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7787,6 +7787,11 @@ } } }, + "js-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.1.tgz", + "integrity": "sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw==" + }, "js-file-download": { "version": "0.4.12", "resolved": "https://registry.npmjs.org/js-file-download/-/js-file-download-0.4.12.tgz", diff --git a/package.json b/package.json index 70f292584..3b26e9721 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "jquery": "3.5.1", "jquery-datetimepicker": "2.5.21", "jquery.are-you-sure": "1.9.0", + "js-cookie": "3.0.1", "less-loader": "6.1.0", "mini-css-extract-plugin": "0.9.0", "monaco-editor": "0.20.0", diff --git a/templates/repo/modelarts/trainjob/show.tmpl b/templates/repo/modelarts/trainjob/show.tmpl index 81d36c1e9..1936c471e 100755 --- a/templates/repo/modelarts/trainjob/show.tmpl +++ b/templates/repo/modelarts/trainjob/show.tmpl @@ -560,16 +560,13 @@ td, th { $('input[name="JobId"]').val(obj.JobID) $('input[name="VersionName"]').val(obj.VersionName).addClass('model_disabled') $('.ui.dimmer').css({"background-color":"rgb(136, 136, 136,0.7)"}) - createModelName() - - + createModelName() }, onHide:function(){ document.getElementById("formId").reset(); $('.ui.dimmer').css({"background-color":""}) $('.ui.error.message').text() $('.ui.error.message').css('display','none') - } }) .modal('show') diff --git a/templates/repo/wx_autorize.tmpl b/templates/repo/wx_autorize.tmpl index dd2ea8635..5c3df656d 100644 --- a/templates/repo/wx_autorize.tmpl +++ b/templates/repo/wx_autorize.tmpl @@ -4,12 +4,15 @@
{{template "repo/header" .}} {{template "base/alert" .}} -
+ +
+ +
- - - {{template "base/footer" .}} + diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl index 54c6695ec..eaf4c776b 100644 --- a/templates/user/settings/profile.tmpl +++ b/templates/user/settings/profile.tmpl @@ -102,6 +102,80 @@ +

+ 微信绑定 +

+ {{if not .SignedUser.IsBindWechat}} + + {{else}} +
+ + + + + + + + + + + + + +
+ 绑定账号信息 + + 详情 + + 绑定时间 + + 操作 +
+ 微信 + + {{.SignedUser.Name}} + + 2022-02-23 14:48 + + +
+
+ {{end}} + + + + {{template "base/footer" .}} + diff --git a/web_src/js/components/WxAutorize.vue b/web_src/js/components/WxAutorize.vue index de186932c..3ac327f9b 100644 --- a/web_src/js/components/WxAutorize.vue +++ b/web_src/js/components/WxAutorize.vue @@ -75,6 +75,8 @@ export default { }, mounted() { this.getWxQrcode(false) + // let QrcodeData = $("#WxAutorize-qrcode").val() + // this.wx_qrcodeImg = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket='+QrcodeData }, created() { } diff --git a/web_src/js/index.js b/web_src/js/index.js index a654a10a7..15728d9c8 100755 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -10,6 +10,7 @@ import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; import axios from 'axios'; import qs from 'qs'; +import Cookies from 'js-cookie' import 'jquery.are-you-sure'; import './vendor/semanticdropdown.js'; import {svg} from './utils.js'; @@ -45,6 +46,7 @@ import WxAutorize from './components/WxAutorize.vue' Vue.use(ElementUI); Vue.prototype.$axios = axios; +Vue.prototype.$Cookies = Cookies; Vue.prototype.qs = qs; const {AppSubUrl, StaticUrlPrefix, csrf} = window.config; From 0e83266380f7557b8064563ebb019965f0cc6655 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Wed, 23 Feb 2022 17:07:29 +0800 Subject: [PATCH 26/47] fix issue --- web_src/js/components/WxAutorize.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/web_src/js/components/WxAutorize.vue b/web_src/js/components/WxAutorize.vue index 3ac327f9b..a055ca426 100644 --- a/web_src/js/components/WxAutorize.vue +++ b/web_src/js/components/WxAutorize.vue @@ -68,6 +68,7 @@ export default { } else if (this.status === 2) { //用户登录成功后清除定时器 clearInterval(times) + window.location.href = this.$Cookies.get('redirect_to') } console.log(times) }, 5000) From ad0e3bf5cf459647fd0555189182d4000a3434b9 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Wed, 23 Feb 2022 17:15:58 +0800 Subject: [PATCH 27/47] fix issue --- templates/repo/wx_autorize.tmpl | 5 +---- web_src/js/components/WxAutorize.vue | 3 +-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/templates/repo/wx_autorize.tmpl b/templates/repo/wx_autorize.tmpl index 5c3df656d..faf80203e 100644 --- a/templates/repo/wx_autorize.tmpl +++ b/templates/repo/wx_autorize.tmpl @@ -6,13 +6,10 @@ {{template "base/alert" .}}
-
{{template "base/footer" .}} - + diff --git a/web_src/js/components/WxAutorize.vue b/web_src/js/components/WxAutorize.vue index a055ca426..f8ef71e26 100644 --- a/web_src/js/components/WxAutorize.vue +++ b/web_src/js/components/WxAutorize.vue @@ -70,8 +70,7 @@ export default { clearInterval(times) window.location.href = this.$Cookies.get('redirect_to') } - console.log(times) - }, 5000) + }, 1000) }, }, mounted() { From c9b3549971be4dfbead51e1c620c79ac1ad222ed Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Wed, 23 Feb 2022 17:24:12 +0800 Subject: [PATCH 28/47] #1494 fix --- modules/auth/wechat/bind.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auth/wechat/bind.go b/modules/auth/wechat/bind.go index e56e9734e..7b4bffc02 100644 --- a/modules/auth/wechat/bind.go +++ b/modules/auth/wechat/bind.go @@ -19,7 +19,7 @@ const ( ) const ( - BIND_REPLY_SUCCESS = "扫码成功,您可以使用OpenI启智社区算例环境。" + BIND_REPLY_SUCCESS = "扫码成功,您可以使用OpenI启智社区算力环境。" BIND_REPLY_WECHAT_ACCOUNT_USED = "认证失败,您的微信号已绑定其他启智账号" BIND_REPLY_OPENI_ACCOUNT_USED = "认证失败,您待认证的启智账号已绑定其他微信号" BIND_REPLY_FAILED_DEFAULT = "微信认证失败" From 72c53266e2a78029ef2f4c29ac9a335f0925692a Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Wed, 23 Feb 2022 18:14:26 +0800 Subject: [PATCH 29/47] fix issue --- templates/repo/debugjob/index.tmpl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/templates/repo/debugjob/index.tmpl b/templates/repo/debugjob/index.tmpl index f7773cf2d..a91b98c58 100755 --- a/templates/repo/debugjob/index.tmpl +++ b/templates/repo/debugjob/index.tmpl @@ -493,6 +493,7 @@ console.log({{.Tasks}}) const {AppSubUrl, StaticUrlPrefix, csrf} = window.config; let url={{.RepoLink}} + let redirect_to = {{$.Link}} let getParam=getQueryVariable('debugListType') let dropdownValue = getParam==='all'||getParam==='' ? '全部' : getParam localStorage.setItem('all',location.href) @@ -545,10 +546,14 @@ }else{ $.ajax({ type:"POST", - url:debugUrl+'restart', + url:debugUrl+'restart?redirect_to='+redirect_to, data:$('#debugAgainForm-'+JobID).serialize(), success:function(res){ + if(res.WechatRedirectUrl){ + window.location.href=WechatRedirectUrl + } if(res.result_code==="0"){ + if(res.job_id!==JobID){ location.reload() }else{ From a3f026872dc2ab12e294c85c69584e574455d3d7 Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Wed, 23 Feb 2022 18:14:54 +0800 Subject: [PATCH 30/47] #1494 fix --- modules/context/auth.go | 39 +++++++++++++++++++++++++++++++-------- routers/routes/routes.go | 5 +++-- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/modules/context/auth.go b/modules/context/auth.go index b374e385b..57fe3350c 100755 --- a/modules/context/auth.go +++ b/modules/context/auth.go @@ -21,13 +21,14 @@ import ( // ToggleOptions contains required or check options type ToggleOptions struct { - SignInRequired bool - SignOutRequired bool - AdminRequired bool - DisableCSRF bool - BasicAuthRequired bool - OperationRequired bool - WechatAuthRequired bool + SignInRequired bool + SignOutRequired bool + AdminRequired bool + DisableCSRF bool + BasicAuthRequired bool + OperationRequired bool + WechatAuthRequired bool + WechatAuthRequiredForAPI bool } // Toggle returns toggle options as middleware @@ -134,11 +135,33 @@ func Toggle(options *ToggleOptions) macaron.Handler { return } if ctx.User.WechatOpenId == "" { - ctx.SetCookie("redirect_to", setting.AppSubURL+ctx.Req.URL.RequestURI(), 0, setting.AppSubURL) + redirectUrl := ctx.Query("redirect_to") + if redirectUrl == "" { + redirectUrl = ctx.Req.URL.RequestURI() + } + ctx.SetCookie("redirect_to", setting.AppSubURL+redirectUrl, 0, setting.AppSubURL) ctx.Redirect(setting.AppSubURL + "/authentication/wechat/bind") } } + if setting.WechatAuthSwitch && options.WechatAuthRequiredForAPI { + if !ctx.IsSigned { + ctx.SetCookie("redirect_to", setting.AppSubURL+ctx.Req.URL.RequestURI(), 0, setting.AppSubURL) + ctx.Redirect(setting.AppSubURL + "/user/login") + return + } + if ctx.User.WechatOpenId == "" { + redirectUrl := ctx.Query("redirect_to") + if redirectUrl == "" { + redirectUrl = ctx.Req.URL.RequestURI() + } + ctx.SetCookie("redirect_to", setting.AppSubURL+redirectUrl, 0, setting.AppSubURL) + ctx.JSON(200, map[string]interface{}{ + "WechatRedirectUrl": setting.AppSubURL + "/authentication/wechat/bind", + }) + } + } + // Redirect to log in page if auto-signin info is provided and has not signed in. if !options.SignOutRequired && !ctx.IsSigned && !auth.IsAPIPath(ctx.Req.URL.Path) && len(ctx.GetCookie(setting.CookieUserName)) > 0 { diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 7241b8299..319af6f0a 100755 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -276,6 +276,7 @@ func RegisterRoutes(m *macaron.Macaron) { reqSignOut := context.Toggle(&context.ToggleOptions{SignOutRequired: true}) reqBasicAuth := context.Toggle(&context.ToggleOptions{BasicAuthRequired: true, DisableCSRF: true}) reqWechatBind := context.Toggle(&context.ToggleOptions{WechatAuthRequired: true}) + reqWechatBindForApi := context.Toggle(&context.ToggleOptions{WechatAuthRequiredForAPI: true}) bindIgnErr := binding.BindIgnErr validation.AddBindingRules() @@ -985,11 +986,11 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/cloudbrain", func() { m.Group("/:jobid", func() { m.Get("", reqRepoCloudBrainReader, repo.CloudBrainShow) - m.Get("/debug", reqWechatBind, cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainDebug) + m.Get("/debug", reqWechatBindForApi, cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainDebug) m.Post("/commit_image", cloudbrain.AdminOrJobCreaterRight, bindIgnErr(auth.CommitImageCloudBrainForm{}), repo.CloudBrainCommitImage) m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop) m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainDel) - m.Post("/restart", reqWechatBind, cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainRestart) + m.Post("/restart", reqWechatBindForApi, cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainRestart) m.Get("/rate", reqRepoCloudBrainReader, repo.GetRate) m.Get("/models", reqRepoCloudBrainReader, repo.CloudBrainShowModels) m.Get("/download_model", cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainDownloadModel) From b11e8269e1f6f21af5dbf87b7432891151cd888b Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Wed, 23 Feb 2022 18:23:07 +0800 Subject: [PATCH 31/47] fix issue --- templates/repo/debugjob/index.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/repo/debugjob/index.tmpl b/templates/repo/debugjob/index.tmpl index a91b98c58..45177d846 100755 --- a/templates/repo/debugjob/index.tmpl +++ b/templates/repo/debugjob/index.tmpl @@ -549,11 +549,11 @@ url:debugUrl+'restart?redirect_to='+redirect_to, data:$('#debugAgainForm-'+JobID).serialize(), success:function(res){ + console.log(res) if(res.WechatRedirectUrl){ window.location.href=WechatRedirectUrl } if(res.result_code==="0"){ - if(res.job_id!==JobID){ location.reload() }else{ From 22e4af4a2aae1e5523d0235d06d5a0ad1b5fef75 Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Wed, 23 Feb 2022 18:26:18 +0800 Subject: [PATCH 32/47] #1494 fix --- modules/context/auth.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/context/auth.go b/modules/context/auth.go index 57fe3350c..0c3ba3b1d 100755 --- a/modules/context/auth.go +++ b/modules/context/auth.go @@ -156,7 +156,7 @@ func Toggle(options *ToggleOptions) macaron.Handler { redirectUrl = ctx.Req.URL.RequestURI() } ctx.SetCookie("redirect_to", setting.AppSubURL+redirectUrl, 0, setting.AppSubURL) - ctx.JSON(200, map[string]interface{}{ + ctx.JSON(200, map[string]string{ "WechatRedirectUrl": setting.AppSubURL + "/authentication/wechat/bind", }) } From eaa136afa5a5366c83dd699d3eac4d5c380aee3c Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Wed, 23 Feb 2022 18:30:24 +0800 Subject: [PATCH 33/47] fix issue --- templates/repo/debugjob/index.tmpl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/templates/repo/debugjob/index.tmpl b/templates/repo/debugjob/index.tmpl index 45177d846..09d2f730b 100755 --- a/templates/repo/debugjob/index.tmpl +++ b/templates/repo/debugjob/index.tmpl @@ -549,8 +549,7 @@ url:debugUrl+'restart?redirect_to='+redirect_to, data:$('#debugAgainForm-'+JobID).serialize(), success:function(res){ - console.log(res) - if(res.WechatRedirectUrl){ + if(res['WechatRedirectUrl']){ window.location.href=WechatRedirectUrl } if(res.result_code==="0"){ From e7277fad6d684fbc63623ec2c4d2ce2ec79fe7a5 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Wed, 23 Feb 2022 18:34:45 +0800 Subject: [PATCH 34/47] fix issue --- templates/repo/debugjob/index.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/repo/debugjob/index.tmpl b/templates/repo/debugjob/index.tmpl index 09d2f730b..011a16dba 100755 --- a/templates/repo/debugjob/index.tmpl +++ b/templates/repo/debugjob/index.tmpl @@ -550,9 +550,9 @@ data:$('#debugAgainForm-'+JobID).serialize(), success:function(res){ if(res['WechatRedirectUrl']){ - window.location.href=WechatRedirectUrl + window.location.href=res['WechatRedirectUrl'] } - if(res.result_code==="0"){ + else if(res.result_code==="0"){ if(res.job_id!==JobID){ location.reload() }else{ From 503d3d807a80267272784563ac10de54c29d9c0e Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Wed, 23 Feb 2022 18:44:29 +0800 Subject: [PATCH 35/47] #1494 fix --- routers/routes/routes.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 319af6f0a..227a22b9e 100755 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -986,7 +986,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/cloudbrain", func() { m.Group("/:jobid", func() { m.Get("", reqRepoCloudBrainReader, repo.CloudBrainShow) - m.Get("/debug", reqWechatBindForApi, cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainDebug) + m.Get("/debug", reqWechatBind, cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainDebug) m.Post("/commit_image", cloudbrain.AdminOrJobCreaterRight, bindIgnErr(auth.CommitImageCloudBrainForm{}), repo.CloudBrainCommitImage) m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop) m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainDel) From 13fb47a5a6868b9eb170a17bd8d254cf50986898 Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Thu, 24 Feb 2022 09:26:01 +0800 Subject: [PATCH 36/47] #1494 add wechat bind time --- models/user.go | 3 ++- models/wechat_bind.go | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/models/user.go b/models/user.go index 0103a6c0b..5b90c38b5 100755 --- a/models/user.go +++ b/models/user.go @@ -179,7 +179,8 @@ type User struct { PrivateKey string `xorm:"INDEX"` //Wechat - WechatOpenId string `xorm:"INDEX"` + WechatOpenId string `xorm:"INDEX"` + WechatBindTime time.Time } // SearchOrganizationsOptions options to filter organizations diff --git a/models/wechat_bind.go b/models/wechat_bind.go index 3cca4888a..5609fa259 100644 --- a/models/wechat_bind.go +++ b/models/wechat_bind.go @@ -27,7 +27,7 @@ func BindWechatOpenId(userId int64, wechatOpenId string) error { return err } - param := &User{WechatOpenId: wechatOpenId} + param := &User{WechatOpenId: wechatOpenId, WechatBindTime: time.Now()} n, err := sess.Where("ID = ?", userId).Update(param) if err != nil { log.Error("update wechat_open_id failed,e=%v", err) @@ -66,7 +66,7 @@ func UnbindWechatOpenId(userId int64, oldWechatOpenID string) error { return err } - n, err := x.Table(new(User)).Where("ID = ? AND wechat_open_id =?", userId, oldWechatOpenID).Update(map[string]interface{}{"wechat_open_id": ""}) + n, err := x.Table(new(User)).Where("ID = ? AND wechat_open_id =?", userId, oldWechatOpenID).Update(map[string]interface{}{"wechat_open_id": "", "wechat_bind_time": nil}) if err != nil { log.Error("update wechat_open_id failed,e=%v", err) return err From 54c142823668439788b484e47d4e78218aa9262a Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Thu, 24 Feb 2022 09:33:28 +0800 Subject: [PATCH 37/47] #1494 update wechat bind time --- models/user.go | 2 +- models/wechat_bind.go | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/models/user.go b/models/user.go index 5b90c38b5..f7857248b 100755 --- a/models/user.go +++ b/models/user.go @@ -180,7 +180,7 @@ type User struct { //Wechat WechatOpenId string `xorm:"INDEX"` - WechatBindTime time.Time + WechatBindUnix timeutil.TimeStamp } // SearchOrganizationsOptions options to filter organizations diff --git a/models/wechat_bind.go b/models/wechat_bind.go index 5609fa259..fde1b2222 100644 --- a/models/wechat_bind.go +++ b/models/wechat_bind.go @@ -2,6 +2,7 @@ package models import ( "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/timeutil" "time" ) @@ -27,7 +28,7 @@ func BindWechatOpenId(userId int64, wechatOpenId string) error { return err } - param := &User{WechatOpenId: wechatOpenId, WechatBindTime: time.Now()} + param := &User{WechatOpenId: wechatOpenId, WechatBindUnix: timeutil.TimeStampNow()} n, err := sess.Where("ID = ?", userId).Update(param) if err != nil { log.Error("update wechat_open_id failed,e=%v", err) @@ -66,7 +67,7 @@ func UnbindWechatOpenId(userId int64, oldWechatOpenID string) error { return err } - n, err := x.Table(new(User)).Where("ID = ? AND wechat_open_id =?", userId, oldWechatOpenID).Update(map[string]interface{}{"wechat_open_id": "", "wechat_bind_time": nil}) + n, err := x.Table(new(User)).Where("ID = ? AND wechat_open_id =?", userId, oldWechatOpenID).Update(map[string]interface{}{"wechat_open_id": "", "wechat_bind_unix": nil}) if err != nil { log.Error("update wechat_open_id failed,e=%v", err) return err From a26a0d6795bbfde83ad671b6fb3e7ab997283b90 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Thu, 24 Feb 2022 09:36:19 +0800 Subject: [PATCH 38/47] fix issue --- templates/repo/wx_autorize.tmpl | 2 +- templates/user/settings/profile.tmpl | 75 +++++++++++++++------------- web_src/js/components/WxAutorize.vue | 1 + 3 files changed, 41 insertions(+), 37 deletions(-) diff --git a/templates/repo/wx_autorize.tmpl b/templates/repo/wx_autorize.tmpl index faf80203e..52b9f29bc 100644 --- a/templates/repo/wx_autorize.tmpl +++ b/templates/repo/wx_autorize.tmpl @@ -1,6 +1,6 @@ {{template "base/head" .}} -
+
{{template "repo/header" .}} {{template "base/alert" .}} diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl index eaf4c776b..097cd1031 100644 --- a/templates/user/settings/profile.tmpl +++ b/templates/user/settings/profile.tmpl @@ -1,6 +1,9 @@ {{template "base/head" .}} +
+ {{template "user/settings/navbar" .}} +
{{template "base/alert" .}}

@@ -111,44 +114,43 @@

{{else}}
- - - - - - - - - - - - - -
- 绑定账号信息 - - 详情 - - 绑定时间 - - 操作 -
- 微信 - - {{.SignedUser.Name}} - - 2022-02-23 14:48 - - -
-
+ + + + + + + + + + + + +
+ 绑定账号信息 + + 绑定时间 + + 操作 +
+ 微信 + + {{TimeSinceUnix1 .SignedUser.WechatBindTime}} + + +
+
{{end}}
-