diff --git a/config/config.go b/config/config.go index adaf32b..ee1358b 100644 --- a/config/config.go +++ b/config/config.go @@ -60,6 +60,7 @@ const ( GiteaClientSecret Key = "gitea.client_secret" SessionSecret Key = "session_secret" + DatabasePath Key = "./database_path" ) // SetupConfig fills all default values, reads the config and/or writes the default config. @@ -86,6 +87,7 @@ func SetupConfig() error { return err } SessionSecret.setDefault(secret) + DatabasePath.setDefault("staletea.db") viper.SetConfigName("config") viper.SetConfigType("yml") diff --git a/go.mod b/go.mod index fbb82a3..f274952 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,16 @@ require ( code.gitea.io/sdk/gitea v0.0.0-20190602153954-7e711e06b588 github.com/gin-contrib/sessions v0.0.0-20190512062852-3cb4c4f2d615 github.com/gin-gonic/gin v1.4.0 + github.com/go-xorm/core v0.6.0 + github.com/go-xorm/xorm v0.7.1 + github.com/mattn/go-sqlite3 v1.10.0 github.com/spf13/viper v1.4.0 github.com/urfave/cli v1.20.0 + golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5 // indirect + golang.org/x/lint v0.0.0-20190409202823-959b441ac422 // indirect + golang.org/x/net v0.0.0-20190603091049-60506f45cf65 // indirect golang.org/x/oauth2 v0.0.0-20190523182746-aaccbc9213b0 + golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed // indirect + golang.org/x/text v0.3.2 // indirect + golang.org/x/tools v0.0.0-20190603231351-8aaa1484dc10 // indirect ) diff --git a/go.sum b/go.sum index 787dee4..9f4dfbe 100644 --- a/go.sum +++ b/go.sum @@ -99,10 +99,14 @@ github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8w github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-xorm/builder v0.3.2/go.mod h1:v8mE3MFBgtL+RGFNfUnAMUqqfk/Y4W5KuwCFQIEpQLk= +github.com/go-xorm/builder v0.3.3 h1:v8grgrwOGv/iHXIEhIvOwHZIPLrpxRKSX8yWSMLFn/4= github.com/go-xorm/builder v0.3.3/go.mod h1:v8mE3MFBgtL+RGFNfUnAMUqqfk/Y4W5KuwCFQIEpQLk= +github.com/go-xorm/core v0.6.0 h1:tp6hX+ku4OD9khFZS8VGBDRY3kfVCtelPfmkgCyHxL0= github.com/go-xorm/core v0.6.0/go.mod h1:d8FJ9Br8OGyQl12MCclmYBuBqqxsyeedpXciV5Myih8= github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM= github.com/go-xorm/xorm v0.0.0-20190116032649-a6300f2a45e0/go.mod h1:EHS1htMQFptzMaIHKyzqpHGw6C9Rtug75nsq6DA9unI= +github.com/go-xorm/xorm v0.7.1 h1:Kj7mfuqctPdX60zuxP6EoEut0f3E6K66H6hcoxiHUMc= +github.com/go-xorm/xorm v0.7.1/go.mod h1:EHS1htMQFptzMaIHKyzqpHGw6C9Rtug75nsq6DA9unI= github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561/go.mod h1:YgYOrVn3Nj9Tq0EvjmFbphRytDj7JNRoWSStJZWDJTQ= github.com/gogits/cron v0.0.0-20160810035002-7f3990acf183/go.mod h1:pX+V62FFmklia2fhP3P4YSY6iJdPO5jIDKFQ5fEd5QE= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -180,6 +184,7 @@ github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-oci8 v0.0.0-20190320171441-14ba190cf52d/go.mod h1:/M9VLO+lUPmxvoOK2PfWRZ8mTtB4q1Hy9lEGijv9Nr8= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o= github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75/go.mod h1:76rfSfYPWj01Z85hUf/ituArm797mNKcvINh1OlsZKo= @@ -271,8 +276,11 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422 h1:QzoH/1pFpZguR8NrRHLcO6jKqfv2zpuSqZLgdm7ZmjI= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -281,9 +289,11 @@ golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65 h1:+rhAzEzT3f4JtomfC371qB+0Ola2caSKcY69NUBZrRQ= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/oauth2 v0.0.0-20180620175406-ef147856a6dd/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181101160152-c453e0c75759/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -292,6 +302,7 @@ golang.org/x/oauth2 v0.0.0-20190523182746-aaccbc9213b0/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180824143301-4910a1d54f87/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -299,16 +310,21 @@ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed h1:uPxWBzB3+mlnjy9W58qY1j/cjyFjutgw/Vhan2zLy/A= +golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190603231351-8aaa1484dc10 h1:9LyHDLeGJwq8p/x0xbF8aG63cLC6EDjlNbGYc7dacDc= +golang.org/x/tools v0.0.0-20190603231351-8aaa1484dc10/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= diff --git a/main.go b/main.go index 9ce5ffe..e184c4b 100644 --- a/main.go +++ b/main.go @@ -19,6 +19,7 @@ package main import ( "gitea.com/jonasfranz/staletea/cmd" "gitea.com/jonasfranz/staletea/config" + "gitea.com/jonasfranz/staletea/models" "github.com/urfave/cli" "os" ) @@ -28,6 +29,8 @@ func main() { panic(err) } + models.SetupDatabase() + app := cli.NewApp() app.Commands = []cli.Command{cmd.CmdRun} if err := app.Run(os.Args); err != nil { diff --git a/models/models.go b/models/models.go new file mode 100644 index 0000000..6543f20 --- /dev/null +++ b/models/models.go @@ -0,0 +1,44 @@ +// staletea +// Copyright (C) 2019 Jonas Franz +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +package models + +import ( + "gitea.com/jonasfranz/staletea/config" + "github.com/go-xorm/core" + "github.com/go-xorm/xorm" + + //use sqlite + _ "github.com/mattn/go-sqlite3" +) + +var x *xorm.Engine + +// SetupDatabase will init a sqlite3 database and sync all models +func SetupDatabase() { + var err error + x, err = xorm.NewEngine("sqlite3", config.DatabasePath.Get().(string)) + if err != nil { + panic(err) + } + x.SetMapper(core.GonicMapper{}) + syncModels() +} + +func syncModels() { + _ = x.Sync2(new(Issue)) + _ = x.Sync2(new(Repository)) +} diff --git a/models/repository.go b/models/repository.go index 77048f9..265c807 100644 --- a/models/repository.go +++ b/models/repository.go @@ -16,9 +16,24 @@ package models +import "github.com/go-xorm/xorm" + // Repository represents a Gitea repository indexed at the local database type Repository struct { - ID int64 `xorm:"pk"` - Owner string `xorm:"unique(owner_name)"` - Name string `xorm:"unique(owner_name"` + ID int64 `xorm:"pk"` + UserID int64 `xorm:"index"` + Owner string `xorm:"unique(owner_name)"` + Name string `xorm:"unique(owner_name)"` + + Activated bool +} + +// FindRepositoriesByUserID returns all repos of an user +func FindRepositoriesByUserID(userID int64) ([]*Repository, error) { + return findRepositoriesByUserID(x, userID) +} + +func findRepositoriesByUserID(e *xorm.Engine, userID int64) ([]*Repository, error) { + repos := make([]*Repository, 0) + return repos, e.Where("user_id = ?", userID).Find(&repos) } diff --git a/models/user.go b/models/user.go index a815f6f..356423d 100644 --- a/models/user.go +++ b/models/user.go @@ -16,7 +16,13 @@ package models -import "golang.org/x/oauth2" +import ( + "code.gitea.io/sdk/gitea" + "context" + "gitea.com/jonasfranz/staletea/auth" + "gitea.com/jonasfranz/staletea/config" + "golang.org/x/oauth2" +) // User represents a signed in oauth2 gitea user saved in a session type User struct { @@ -24,3 +30,10 @@ type User struct { Username string Token *oauth2.Token } + +// GiteaClient will return a gitea client with authentication of the user +func (user *User) GiteaClient() *gitea.Client { + client := gitea.NewClient(config.GiteaURL.Get().(string), "") + client.SetHTTPClient(auth.Config().Client(context.Background(), user.Token)) + return client +} diff --git a/templates/dashboard.tmpl b/templates/dashboard.tmpl new file mode 100644 index 0000000..fe5505f --- /dev/null +++ b/templates/dashboard.tmpl @@ -0,0 +1,15 @@ + + + Dashboard + + +
+ + +
+ + \ No newline at end of file diff --git a/web/auth.go b/web/auth.go index 38fc3fd..697eaa3 100644 --- a/web/auth.go +++ b/web/auth.go @@ -75,5 +75,9 @@ func handleCallback(ctx *gin.Context) { Token: token, } session.Set("user", storedUser) - ctx.String(200, user.FullName) + if err := session.Save(); err != nil { + _ = ctx.AbortWithError(http.StatusInternalServerError, err) + return + } + ctx.Redirect(http.StatusTemporaryRedirect, config.BaseURL.Get().(string)) } diff --git a/web/dashboard.go b/web/dashboard.go index f263e0e..8ee0091 100644 --- a/web/dashboard.go +++ b/web/dashboard.go @@ -27,9 +27,45 @@ import ( func showDashboard(ctx *gin.Context) { session := sessions.Default(ctx) - user := session.Get("user").(*models.User) - if user == nil { + user, ok := session.Get("user").(*models.User) + if !ok || user == nil { ctx.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("%s/login", config.BaseURL.Get().(string))) return } + activatedRepos, err := models.FindRepositoriesByUserID(user.ID) + if err != nil { + _ = ctx.AbortWithError(500, err) + return + } + remoteRepos, err := user.GiteaClient().ListMyRepos() + if err != nil { + _ = ctx.AbortWithError(500, err) + return + } + combinedRepos := make(map[int64]*models.Repository, len(activatedRepos)) + + for _, repo := range activatedRepos { + combinedRepos[repo.ID] = repo + } + + for _, repo := range remoteRepos { + combinedRepos[repo.ID] = &models.Repository{ + ID: repo.ID, + UserID: user.ID, + Owner: repo.Owner.UserName, + Name: repo.Name, + Activated: false, + } + } + + data := map[string]interface{}{ + "repos": combinedRepos, + "user": user, + } + + ctx.HTML(200, "dashboard.tmpl", data) +} + +func handleActivate(ctx *gin.Context) { + } diff --git a/web/router.go b/web/router.go index 48b2239..c789d33 100644 --- a/web/router.go +++ b/web/router.go @@ -17,7 +17,9 @@ package web import ( + "encoding/gob" "gitea.com/jonasfranz/staletea/config" + "gitea.com/jonasfranz/staletea/models" "github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions/cookie" "github.com/gin-gonic/gin" @@ -26,14 +28,17 @@ import ( // StartServer will start the webserver at the given addresses func StartServer(addr ...string) error { r := gin.Default() + gob.Register(new(models.User)) store := cookie.NewStore([]byte(config.SessionSecret.Get().(string))) r.Use(sessions.Sessions("sessions", store)) + r.LoadHTMLFiles("templates/dashboard.tmpl") setupRoutes(r) return r.Run(addr...) } func setupRoutes(r *gin.Engine) { r.GET("/", showDashboard) + r.POST("/", handleActivate) r.GET("/login", handleLogin) r.GET("/callback", handleCallback) }