Compare commits
1 Commits
master
...
feature/wi
Author | SHA1 | Date |
---|---|---|
![]() |
8011636a53 |
|
@ -1,42 +0,0 @@
|
|||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gitea.com/jonasfranz/staletea/config"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
func endpoint() oauth2.Endpoint {
|
||||
// Endpoint is Google's OAuth 2.0 endpoint.
|
||||
return oauth2.Endpoint{
|
||||
AuthURL: fmt.Sprintf("%s/login/oauth/authorize", config.GiteaURL.Get().(string)),
|
||||
TokenURL: fmt.Sprintf("%s/login/oauth/access_token", config.GiteaURL.Get().(string)),
|
||||
AuthStyle: oauth2.AuthStyleInParams,
|
||||
}
|
||||
}
|
||||
|
||||
// Config returns an oauth2 config
|
||||
func Config() *oauth2.Config {
|
||||
return &oauth2.Config{
|
||||
ClientID: config.GiteaClientID.Get().(string),
|
||||
ClientSecret: config.GiteaClientSecret.Get().(string),
|
||||
Endpoint: endpoint(),
|
||||
RedirectURL: fmt.Sprintf("%s/callback", config.BaseURL.Get().(string)),
|
||||
}
|
||||
}
|
16
cmd/run.go
16
cmd/run.go
|
@ -17,7 +17,8 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"gitea.com/jonasfranz/staletea/web"
|
||||
"gitea.com/jonasfranz/staletea/config"
|
||||
"gitea.com/jonasfranz/staletea/jobs"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
|
@ -25,14 +26,13 @@ import (
|
|||
var CmdRun = cli.Command{
|
||||
Action: run,
|
||||
Name: "run",
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "address",
|
||||
Value: ":3030",
|
||||
},
|
||||
},
|
||||
Flags: []cli.Flag{},
|
||||
}
|
||||
|
||||
func run(ctx *cli.Context) error {
|
||||
return web.StartServer(ctx.String("address"))
|
||||
println("Startup!")
|
||||
if err := config.SetupConfig(); err != nil {
|
||||
return err
|
||||
}
|
||||
return jobs.StartCronJobs()
|
||||
}
|
||||
|
|
|
@ -41,56 +41,40 @@ func (k Key) setDefault(defaultValue interface{}) {
|
|||
|
||||
// This block contains all config keys
|
||||
const (
|
||||
DaysUntilStale Key = "daysUntilStale"
|
||||
DaysUntilClose Key = "daysUntilClose"
|
||||
LabelBlacklist Key = "onlyLabels"
|
||||
LabelWhitelist Key = "exemptLabels"
|
||||
StaleLabel Key = "staleLabel"
|
||||
|
||||
MarkComment Key = "markComment"
|
||||
UnmarkComment Key = "unmarkComment"
|
||||
CloseComment Key = "closeComment"
|
||||
|
||||
TypeBlacklist Key = "only"
|
||||
|
||||
BaseURL Key = "host"
|
||||
|
||||
GiteaURL Key = "gitea.url"
|
||||
GiteaClientID Key = "gitea.client_id"
|
||||
GiteaClientSecret Key = "gitea.client_secret"
|
||||
GiteaURL Key = "gitea_url"
|
||||
BotAccessToken Key = "gitea_bot_access_token"
|
||||
|
||||
SessionSecret Key = "session_secret"
|
||||
DatabasePath Key = "./database_path"
|
||||
DatabaseDriver Key = "database_driver"
|
||||
DatabaseURI Key = "database_uri"
|
||||
|
||||
RepositoryScanInterval Key = "repository_scan_interval"
|
||||
IssueScanInterval Key = "issue_scan_interval"
|
||||
|
||||
RepositoryConfigFileName Key = "repository_config_file_name"
|
||||
)
|
||||
|
||||
// SetupConfig fills all default values, reads the config and/or writes the default config.
|
||||
func SetupConfig() error {
|
||||
DaysUntilStale.setDefault(60)
|
||||
DaysUntilClose.setDefault(7)
|
||||
LabelBlacklist.setDefault([]string{})
|
||||
LabelWhitelist.setDefault([]string{})
|
||||
StaleLabel.setDefault("wontfix")
|
||||
|
||||
MarkComment.setDefault(`This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed in %d days if no further activity occurs. Thank you
|
||||
for your contributions.`)
|
||||
UnmarkComment.setDefault("")
|
||||
CloseComment.setDefault("This issue was closed automatically since it was marked as stale and had no recent activity.")
|
||||
TypeBlacklist.setDefault([]string{})
|
||||
BaseURL.setDefault("http://localhost")
|
||||
GiteaURL.setDefault("https://gitea.com")
|
||||
GiteaClientID.setDefault("")
|
||||
GiteaClientSecret.setDefault("")
|
||||
BotAccessToken.setDefault("YOUR_BOT_TOKEN")
|
||||
|
||||
secret, err := utils.NewSecret(32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
SessionSecret.setDefault(secret)
|
||||
DatabasePath.setDefault("staletea.db")
|
||||
DatabaseDriver.setDefault("sqlite3")
|
||||
DatabaseURI.setDefault("staletea.db")
|
||||
|
||||
RepositoryScanInterval.setDefault("@every 30s")
|
||||
IssueScanInterval.setDefault("@every 2m")
|
||||
|
||||
RepositoryConfigFileName.setDefault(".stale.yml")
|
||||
|
||||
viper.SetConfigName("config")
|
||||
viper.SetConfigType("yml")
|
||||
viper.AutomaticEnv()
|
||||
viper.AddConfigPath(".")
|
||||
if err := viper.SafeWriteConfigAs("config.yml"); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
|
|
2
go.mod
2
go.mod
|
@ -12,6 +12,7 @@ require (
|
|||
github.com/lib/pq v1.1.0 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.10.0
|
||||
github.com/pkg/errors v0.8.1 // indirect
|
||||
github.com/robfig/cron v1.2.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
|
||||
|
@ -19,4 +20,5 @@ require (
|
|||
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
|
||||
gopkg.in/yaml.v2 v2.2.2
|
||||
)
|
||||
|
|
2
go.sum
2
go.sum
|
@ -137,6 +137,8 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R
|
|||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/quasoft/memstore v0.0.0-20180925164028-84a050167438/go.mod h1:wTPjTepVu7uJBYgZ0SdWHQlIas582j6cn2jgk4DDdlg=
|
||||
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
|
||||
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
// staletea
|
||||
// Copyright (C) 2020 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
package jobs
|
||||
|
||||
func syncIssues() error {
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
// staletea
|
||||
// Copyright (C) 2020 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
package jobs
|
||||
|
||||
import "github.com/robfig/cron"
|
||||
|
||||
import "gitea.com/jonasfranz/staletea/config"
|
||||
|
||||
type Job struct {
|
||||
Interval config.Key
|
||||
Action func() error
|
||||
}
|
||||
|
||||
var registeredCronJobs []Job = []Job{
|
||||
{Interval: config.RepositoryScanInterval, Action: syncRepositories},
|
||||
{Interval: config.IssueScanInterval, Action: syncIssues},
|
||||
}
|
||||
|
||||
func handleError(unsafeFunc func() error) func() {
|
||||
return func() {
|
||||
err := unsafeFunc()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func StartCronJobs() error {
|
||||
c := cron.New()
|
||||
for _, job := range registeredCronJobs {
|
||||
if err := c.AddFunc(job.Interval.Get().(string), handleError(job.Action)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
c.Run()
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
// staletea
|
||||
// Copyright (C) 2020 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
package jobs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gitea.com/jonasfranz/staletea/config"
|
||||
"gitea.com/jonasfranz/staletea/loader"
|
||||
"gitea.com/jonasfranz/staletea/models"
|
||||
)
|
||||
|
||||
func syncRepositories() error {
|
||||
savedRepos, err := models.FindAllRepositories()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
savedRepoIDs := make(map[int64]*models.Repository)
|
||||
for _, savedRepo := range savedRepos {
|
||||
savedRepoIDs[savedRepo.ID] = savedRepo
|
||||
}
|
||||
l := loader.NewGiteaLoader(config.GiteaURL.Get().(string), config.BotAccessToken.Get().(string))
|
||||
loadedRepos, err := l.LoadRepositories()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newRepos := make([]*models.Repository, 0)
|
||||
for _, loadedRepo := range loadedRepos {
|
||||
if _, ok := savedRepoIDs[loadedRepo.ID]; !ok {
|
||||
repoConfig, err := l.DownloadConfig(loadedRepo)
|
||||
if err != nil {
|
||||
fmt.Printf("cannot download config for repo %s/%s: %v\n", loadedRepo.Owner, loadedRepo.Name, err)
|
||||
continue
|
||||
}
|
||||
newRepos = append(newRepos, &models.Repository{
|
||||
ID: loadedRepo.ID,
|
||||
Config: repoConfig,
|
||||
Activated: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
return models.CreateRepositories(newRepos)
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
// staletea
|
||||
// Copyright (C) 2020 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
package loader
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"gitea.com/jonasfranz/staletea/config"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
func NewGiteaLoader(url, token string) Loader {
|
||||
return &GiteaLoader{
|
||||
client: gitea.NewClient(url, token),
|
||||
}
|
||||
}
|
||||
|
||||
type GiteaLoader struct {
|
||||
client *gitea.Client
|
||||
}
|
||||
|
||||
func (l *GiteaLoader) LoadRepositories() ([]*Repository, error) {
|
||||
repos, err := l.client.ListMyRepos()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
convertedRepos := make([]*Repository, len(repos))
|
||||
for index, repo := range repos {
|
||||
convertedRepos[index] = &Repository{
|
||||
ID: repo.ID,
|
||||
Owner: repo.Owner.UserName,
|
||||
Name: repo.Name,
|
||||
ConfigBranch: repo.DefaultBranch,
|
||||
}
|
||||
}
|
||||
return convertedRepos, nil
|
||||
}
|
||||
|
||||
func (l *GiteaLoader) DownloadConfig(repo *Repository) (*RepositoryConfig, error) {
|
||||
file, err := l.client.GetFile(repo.Owner, repo.Name, repo.ConfigBranch, config.RepositoryConfigFileName.Get().(string))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
repoConfig := new(RepositoryConfig)
|
||||
if err := yaml.NewDecoder(bytes.NewReader(file)).Decode(repoConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return repoConfig, nil
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
// staletea
|
||||
// Copyright (C) 2020 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
package loader
|
||||
|
||||
type Loader interface {
|
||||
LoadRepositories() ([]*Repository, error)
|
||||
DownloadConfig(repo *Repository) (*RepositoryConfig, error)
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
// staletea
|
||||
// Copyright (C) 2019 Jonas Franz
|
||||
// Copyright (C) 2020 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
|
||||
|
@ -14,26 +14,15 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package models
|
||||
package loader
|
||||
|
||||
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 {
|
||||
type Repository struct {
|
||||
ID int64
|
||||
Username string
|
||||
Token *oauth2.Token
|
||||
Owner string
|
||||
Name string
|
||||
ConfigBranch string
|
||||
}
|
||||
|
||||
// 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
|
||||
type RepositoryConfig struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
}
|
|
@ -30,7 +30,7 @@ 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))
|
||||
x, err = xorm.NewEngine("sqlite3", config.DatabaseURI.Get().(string))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
@ -16,24 +16,36 @@
|
|||
|
||||
package models
|
||||
|
||||
import "github.com/go-xorm/xorm"
|
||||
import (
|
||||
"gitea.com/jonasfranz/staletea/loader"
|
||||
"github.com/go-xorm/xorm"
|
||||
)
|
||||
|
||||
// Repository represents a Gitea repository indexed at the local database
|
||||
type Repository struct {
|
||||
ID int64 `xorm:"pk"`
|
||||
UserID int64 `xorm:"index"`
|
||||
Owner string `xorm:"unique(owner_name)"`
|
||||
Name string `xorm:"unique(owner_name)"`
|
||||
Config *loader.RepositoryConfig `xorm:"json"`
|
||||
|
||||
Activated bool
|
||||
}
|
||||
|
||||
// FindRepositoriesByUserID returns all repos of an user
|
||||
func FindRepositoriesByUserID(userID int64) ([]*Repository, error) {
|
||||
return findRepositoriesByUserID(x, userID)
|
||||
func FindAllRepositories() ([]*Repository, error) {
|
||||
return findAllRepositories(x)
|
||||
}
|
||||
|
||||
func findRepositoriesByUserID(e *xorm.Engine, userID int64) ([]*Repository, error) {
|
||||
func findAllRepositories(e *xorm.Engine) ([]*Repository, error) {
|
||||
repos := make([]*Repository, 0)
|
||||
return repos, e.Where("user_id = ?", userID).Find(&repos)
|
||||
if err := e.Find(&repos); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return repos, nil
|
||||
}
|
||||
|
||||
func CreateRepositories(repos []*Repository) error {
|
||||
return createRepositories(x, repos)
|
||||
}
|
||||
|
||||
func createRepositories(e *xorm.Engine, repos []*Repository) error {
|
||||
_, err := e.Insert(&repos)
|
||||
return err
|
||||
}
|
||||
|
|
83
web/auth.go
83
web/auth.go
|
@ -1,83 +0,0 @@
|
|||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
package web
|
||||
|
||||
import (
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"context"
|
||||
"gitea.com/jonasfranz/staletea/auth"
|
||||
"gitea.com/jonasfranz/staletea/config"
|
||||
"gitea.com/jonasfranz/staletea/models"
|
||||
"gitea.com/jonasfranz/staletea/utils"
|
||||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func handleLogin(ctx *gin.Context) {
|
||||
session := sessions.Default(ctx)
|
||||
state, err := utils.NewSecret(32)
|
||||
if err != nil {
|
||||
_ = ctx.AbortWithError(500, err)
|
||||
return
|
||||
}
|
||||
session.Set("state", state)
|
||||
if err := session.Save(); err != nil {
|
||||
_ = ctx.AbortWithError(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
redirectURL := auth.Config().AuthCodeURL(state)
|
||||
ctx.Redirect(http.StatusTemporaryRedirect, redirectURL)
|
||||
}
|
||||
|
||||
func handleCallback(ctx *gin.Context) {
|
||||
session := sessions.Default(ctx)
|
||||
state := ctx.Query("state")
|
||||
savedState := session.Get("state")
|
||||
if savedState == nil {
|
||||
ctx.String(http.StatusUnauthorized, "Invalid state")
|
||||
return
|
||||
}
|
||||
session.Delete("state")
|
||||
if parsedState, ok := savedState.(string); !ok || parsedState != state {
|
||||
ctx.String(http.StatusUnauthorized, "Invalid state")
|
||||
return
|
||||
}
|
||||
token, err := auth.Config().Exchange(ctx, ctx.Query("code"))
|
||||
if err != nil {
|
||||
_ = ctx.AbortWithError(http.StatusUnauthorized, err)
|
||||
return
|
||||
}
|
||||
client := gitea.NewClient(config.GiteaURL.Get().(string), "")
|
||||
client.SetHTTPClient(auth.Config().Client(context.Background(), token))
|
||||
user, err := client.GetMyUserInfo()
|
||||
if err != nil {
|
||||
_ = ctx.AbortWithError(http.StatusUnauthorized, err)
|
||||
return
|
||||
}
|
||||
storedUser := &models.User{
|
||||
ID: user.ID,
|
||||
Username: user.UserName,
|
||||
Token: token,
|
||||
}
|
||||
session.Set("user", storedUser)
|
||||
if err := session.Save(); err != nil {
|
||||
_ = ctx.AbortWithError(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
ctx.Redirect(http.StatusTemporaryRedirect, config.BaseURL.Get().(string))
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
package web
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gitea.com/jonasfranz/staletea/config"
|
||||
"gitea.com/jonasfranz/staletea/models"
|
||||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func showDashboard(ctx *gin.Context) {
|
||||
session := sessions.Default(ctx)
|
||||
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) {
|
||||
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
// 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)
|
||||
}
|
Loading…
Reference in New Issue