diff --git a/cmd/dashboard/controller/common_page.go b/cmd/dashboard/controller/common_page.go index 031c923..d4bf537 100644 --- a/cmd/dashboard/controller/common_page.go +++ b/cmd/dashboard/controller/common_page.go @@ -26,18 +26,17 @@ func (cp *commonPage) serve() { } func (cp *commonPage) home(c *gin.Context) { - var admin *model.User - isLogin, ok := c.Get(model.CtxKeyIsUserLogin) - if ok && isLogin.(bool) { - admin = dao.Admin - } dao.ServerLock.RLock() defer dao.ServerLock.RUnlock() - c.HTML(http.StatusOK, "page/home", mygin.CommonEnvironment(c, gin.H{ - "Admin": admin, + data := gin.H{ "Domain": dao.Conf.Site.Domain, "Servers": dao.ServerList, - })) + } + u, ok := c.Get(model.CtxKeyAuthorizedUser) + if ok { + data["Admin"] = u + } + c.HTML(http.StatusOK, "page/home", mygin.CommonEnvironment(c, data)) } var upgrader = websocket.Upgrader{} diff --git a/cmd/dashboard/controller/member_api.go b/cmd/dashboard/controller/member_api.go index 93f8bac..8ce949c 100644 --- a/cmd/dashboard/controller/member_api.go +++ b/cmd/dashboard/controller/member_api.go @@ -28,14 +28,16 @@ func (ma *memberAPI) serve() { })) mr.POST("/logout", ma.logout) - mr.POST("/server", ma.addServer) + mr.POST("/server", ma.addOrEditServer) } type serverForm struct { + ID uint64 Name string `binding:"required"` } -func (ma *memberAPI) addServer(c *gin.Context) { +func (ma *memberAPI) addOrEditServer(c *gin.Context) { + admin := c.MustGet(model.CtxKeyAuthorizedUser).(*model.User) var sf serverForm var s model.Server err := c.ShouldBindJSON(&sf) @@ -43,9 +45,13 @@ func (ma *memberAPI) addServer(c *gin.Context) { dao.ServerLock.Lock() defer dao.ServerLock.Unlock() s.Name = sf.Name - s.Secret = com.MD5(fmt.Sprintf("%s%s%d", time.Now(), sf.Name, dao.Admin.ID)) + } + if sf.ID == 0 { + s.Secret = com.MD5(fmt.Sprintf("%s%s%d", time.Now(), sf.Name, admin.ID)) s.Secret = s.Secret[:10] err = dao.DB.Create(&s).Error + } else { + err = dao.DB.Save(&s).Error } if err != nil { c.JSON(http.StatusOK, model.Response{ @@ -65,6 +71,7 @@ type logoutForm struct { } func (ma *memberAPI) logout(c *gin.Context) { + admin := c.MustGet(model.CtxKeyAuthorizedUser).(*model.User) var lf logoutForm if err := c.ShouldBindJSON(&lf); err != nil { c.JSON(http.StatusOK, model.Response{ @@ -73,15 +80,17 @@ func (ma *memberAPI) logout(c *gin.Context) { }) return } - if lf.ID != dao.Admin.ID { + if lf.ID != admin.ID { c.JSON(http.StatusOK, model.Response{ Code: http.StatusBadRequest, Message: fmt.Sprintf("请求错误:%s", "用户ID不匹配"), }) return } - dao.Admin.Token = "" - dao.Admin.TokenExpired = time.Now() + dao.DB.Model(admin).UpdateColumns(model.User{ + Token: "", + TokenExpired: time.Now(), + }) c.JSON(http.StatusOK, model.Response{ Code: http.StatusOK, }) diff --git a/cmd/dashboard/controller/oauth2.go b/cmd/dashboard/controller/oauth2.go index b31a0b2..ea4d8d1 100644 --- a/cmd/dashboard/controller/oauth2.go +++ b/cmd/dashboard/controller/oauth2.go @@ -75,9 +75,9 @@ func (oa *oauth2controller) callback(c *gin.Context) { return } user := model.NewUserFromGitHub(gu) - dao.Admin = &user - dao.Admin.IssueNewToken() - c.SetCookie(dao.Conf.Site.CookieName, dao.Admin.Token, 60*60*24*14, "", "", false, false) + user.IssueNewToken() + dao.DB.Save(&user) + c.SetCookie(dao.Conf.Site.CookieName, user.Token, 60*60*24*14, "", "", false, false) c.Status(http.StatusOK) c.Writer.WriteString("") } diff --git a/cmd/dashboard/main.go b/cmd/dashboard/main.go index daf2ccd..0a504e3 100644 --- a/cmd/dashboard/main.go +++ b/cmd/dashboard/main.go @@ -17,13 +17,11 @@ import ( func init() { var err error dao.ServerList = make(map[string]*model.Server) - dao.Conf, err = model.ReadInConfig("data/config.yaml") + dao.Conf = &model.Config{} + err = dao.Conf.Read("data/config.yaml") if err != nil { panic(err) } - dao.Admin = &model.User{ - Login: dao.Conf.GitHub.Admin, - } dao.DB, err = gorm.Open("sqlite3", "data/sqlite.db") if err != nil { panic(err) @@ -36,7 +34,7 @@ func init() { } func initDB() { - dao.DB.AutoMigrate(model.Server{}) + dao.DB.AutoMigrate(model.Server{}, model.User{}) // load cache var servers []model.Server dao.DB.Find(&servers) diff --git a/go.mod b/go.mod index a3855a4..912e532 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,5 @@ require ( github.com/spf13/viper v1.6.1 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 // indirect - golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 // indirect google.golang.org/grpc v1.25.1 - honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc // indirect ) diff --git a/model/common.go b/model/common.go index 4602bfb..ada327d 100644 --- a/model/common.go +++ b/model/common.go @@ -2,8 +2,8 @@ package model import "time" -// CtxKeyIsUserLogin .. -const CtxKeyIsUserLogin = "ckiul" +// CtxKeyAuthorizedUser .. +const CtxKeyAuthorizedUser = "ckau" // CtxKeyOauth2State .. const CtxKeyOauth2State = "cko2s" diff --git a/model/config.go b/model/config.go index 80f88da..6586d59 100644 --- a/model/config.go +++ b/model/config.go @@ -1,6 +1,8 @@ package model import ( + "fmt" + "github.com/fsnotify/fsnotify" "github.com/spf13/viper" ) @@ -18,26 +20,29 @@ type Config struct { ClientID string ClientSecret string } + + v *viper.Viper } // ReadInConfig .. -func ReadInConfig(path string) (*Config, error) { - viper.SetConfigFile(path) - err := viper.ReadInConfig() +func (c *Config) Read(path string) error { + c.v = viper.New() + c.v.SetConfigFile(path) + err := c.v.ReadInConfig() if err != nil { - return nil, err - } - var c Config - - err = viper.Unmarshal(&c) - if err != nil { - return nil, err + return err } - viper.OnConfigChange(func(in fsnotify.Event) { - viper.Unmarshal(&c) + err = c.v.Unmarshal(c) + if err != nil { + return err + } + + c.v.OnConfigChange(func(in fsnotify.Event) { + fmt.Println("配置文件更新,重载配置") + c.v.Unmarshal(c) }) - go viper.WatchConfig() - return &c, nil + go c.v.WatchConfig() + return nil } diff --git a/model/user.go b/model/user.go index f31a456..190f23a 100644 --- a/model/user.go +++ b/model/user.go @@ -48,5 +48,5 @@ func NewUserFromGitHub(gu *github.User) User { // IssueNewToken ... func (u *User) IssueNewToken() { u.Token = com.MD5(fmt.Sprintf("%d%d%s", time.Now().UnixNano(), u.ID, u.Login)) - u.TokenExpired = time.Now().AddDate(0, 0, 14) + u.TokenExpired = time.Now().AddDate(0, 2, 0) } diff --git a/pkg/mygin/auth.go b/pkg/mygin/auth.go index cf13d17..6938886 100644 --- a/pkg/mygin/auth.go +++ b/pkg/mygin/auth.go @@ -2,6 +2,7 @@ package mygin import ( "net/http" + "strings" "time" "github.com/gin-gonic/gin" @@ -24,6 +25,7 @@ type AuthorizeOption struct { func Authorize(opt AuthorizeOption) func(*gin.Context) { return func(c *gin.Context) { token, err := c.Cookie(dao.Conf.Site.CookieName) + token = strings.TrimSpace(token) var code uint64 = http.StatusForbidden if opt.Guest { code = http.StatusBadRequest @@ -35,12 +37,18 @@ func Authorize(opt AuthorizeOption) func(*gin.Context) { Link: opt.Redirect, Btn: opt.Btn, } - var isLogin bool - if err == nil { - isLogin = token == dao.Admin.Token && dao.Admin.Token != "" && - dao.Admin.TokenExpired.After(time.Now()) + if token != "" { + + } + var isLogin bool + var u model.User + err = dao.DB.Where("token = ?", token).First(&u).Error + if err == nil { + isLogin = u.TokenExpired.After(time.Now()) + } + if isLogin { + c.Set(model.CtxKeyAuthorizedUser, &u) } - c.Set(model.CtxKeyIsUserLogin, isLogin) // 已登录且只能游客访问 if isLogin && opt.Guest { ShowErrorPage(c, commonErr, opt.IsPage) diff --git a/pkg/mygin/mygin.go b/pkg/mygin/mygin.go index 033df7a..2dc89e2 100644 --- a/pkg/mygin/mygin.go +++ b/pkg/mygin/mygin.go @@ -20,9 +20,9 @@ func CommonEnvironment(c *gin.Context, data map[string]interface{}) gin.H { } else { data["Title"] = fmt.Sprintf("%s - %s", t, dao.Conf.Site.Brand) } - isLogin, ok := c.Get(model.CtxKeyIsUserLogin) - if ok && isLogin.(bool) { - data["Admin"] = dao.Admin + u, ok := c.Get(model.CtxKeyAuthorizedUser) + if ok { + data["Admin"] = u } return data } diff --git a/resource/template/page/home.html b/resource/template/page/home.html index 5d412d7..03583ba 100644 --- a/resource/template/page/home.html +++ b/resource/template/page/home.html @@ -153,8 +153,10 @@ } // 刷新进度条 bars.forEach((b, i) => { - b.progress('set total', i == 0 ? 100 : b[0].dataset.total); - b.progress('update progress', b[0].dataset.value); + if (b[0] && b[0].dataset) { + b.progress('set total', i == 0 ? 100 : b[0].dataset.total); + b.progress('update progress', b[0].dataset.value); + } }) } } diff --git a/resource/template/page/server.html b/resource/template/page/server.html index 3ec34fd..6c414d7 100644 --- a/resource/template/page/server.html +++ b/resource/template/page/server.html @@ -3,7 +3,7 @@ {{template "common/menu" .}}
- @@ -11,6 +11,7 @@ + @@ -19,6 +20,16 @@ + {{end}} diff --git a/service/dao/dao.go b/service/dao/dao.go index 47d2006..aa188ae 100644 --- a/service/dao/dao.go +++ b/service/dao/dao.go @@ -19,9 +19,6 @@ var Cache *cache.Cache // DB .. var DB *gorm.DB -// Admin .. -var Admin *model.User - // ServerList .. var ServerList map[string]*model.Server
ID 备注 密钥管理
{{$server.ID}} {{$server.Name}} {{$server.Secret}} +
+ + +
+