mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-12-22 16:36:30 +00:00
improve and simplify repository caching
This commit is contained in:
parent
6769eed65d
commit
3dd0260b69
15 changed files with 444 additions and 364 deletions
10
cache/cache.go
vendored
10
cache/cache.go
vendored
|
@ -1,5 +1,7 @@
|
||||||
package cache
|
package cache
|
||||||
|
|
||||||
|
//go:generate mockery -name Cache -output mock -case=underscore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -23,7 +25,7 @@ func Set(c context.Context, key string, value interface{}) error {
|
||||||
// Default creates an in-memory cache with the default
|
// Default creates an in-memory cache with the default
|
||||||
// 30 minute expiration period.
|
// 30 minute expiration period.
|
||||||
func Default() Cache {
|
func Default() Cache {
|
||||||
return cache.NewMemoryWithTTL(time.Minute * 30)
|
return NewTTL(time.Minute * 30)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTTL returns an in-memory cache with the specified
|
// NewTTL returns an in-memory cache with the specified
|
||||||
|
@ -31,9 +33,3 @@ func Default() Cache {
|
||||||
func NewTTL(t time.Duration) Cache {
|
func NewTTL(t time.Duration) Cache {
|
||||||
return cache.NewMemoryWithTTL(t)
|
return cache.NewMemoryWithTTL(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTTL returns an in-memory cache with the specified
|
|
||||||
// ttl expiration period.
|
|
||||||
func NewLRU(size int) Cache {
|
|
||||||
return cache.NewLRU(size)
|
|
||||||
}
|
|
||||||
|
|
79
cache/helper.go
vendored
79
cache/helper.go
vendored
|
@ -4,72 +4,51 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/drone/drone/model"
|
"github.com/drone/drone/model"
|
||||||
|
"github.com/drone/drone/remote"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetRepos returns the user permissions to the named repository
|
// GetPerm returns the user permissions repositories from the cache
|
||||||
// from the cache associated with the current context.
|
// associated with the current repository.
|
||||||
func GetPerms(c context.Context, user *model.User, owner, name string) *model.Perm {
|
func GetPerms(c context.Context, user *model.User, owner, name string) (*model.Perm, error) {
|
||||||
key := fmt.Sprintf("perms:%s:%s/%s",
|
key := fmt.Sprintf("perms:%s:%s/%s",
|
||||||
user.Login,
|
user.Login,
|
||||||
owner,
|
owner,
|
||||||
name,
|
name,
|
||||||
)
|
)
|
||||||
val, err := FromContext(c).Get(key)
|
// if we fetch from the cache we can return immediately
|
||||||
if err != nil {
|
val, err := Get(c, key)
|
||||||
return nil
|
if err == nil {
|
||||||
|
return val.(*model.Perm), nil
|
||||||
}
|
}
|
||||||
return val.(*model.Perm)
|
// else we try to grab from the remote system and
|
||||||
}
|
// populate our cache.
|
||||||
|
perm, err := remote.Perm(c, user, owner, name)
|
||||||
// SetRepos adds the listof user permissions to the named repsotiory
|
if err != nil {
|
||||||
// to the cache assocaited with the current context.
|
return nil, err
|
||||||
func SetPerms(c context.Context, user *model.User, perm *model.Perm, owner, name string) {
|
}
|
||||||
key := fmt.Sprintf("perms:%s:%s/%s",
|
Set(c, key, perm)
|
||||||
user.Login,
|
return perm, nil
|
||||||
owner,
|
|
||||||
name,
|
|
||||||
)
|
|
||||||
FromContext(c).Set(key, perm)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRepos returns the list of user repositories from the cache
|
// GetRepos returns the list of user repositories from the cache
|
||||||
// associated with the current context.
|
// associated with the current context.
|
||||||
func GetRepos(c context.Context, user *model.User) []*model.RepoLite {
|
func GetRepos(c context.Context, user *model.User) ([]*model.RepoLite, error) {
|
||||||
key := fmt.Sprintf("repos:%s",
|
key := fmt.Sprintf("repos:%s",
|
||||||
user.Login,
|
user.Login,
|
||||||
)
|
)
|
||||||
val, err := FromContext(c).Get(key)
|
// if we fetch from the cache we can return immediately
|
||||||
if err != nil {
|
val, err := Get(c, key)
|
||||||
return nil
|
if err == nil {
|
||||||
|
return val.([]*model.RepoLite), nil
|
||||||
|
}
|
||||||
|
// else we try to grab from the remote system and
|
||||||
|
// populate our cache.
|
||||||
|
repos, err := remote.Repos(c, user)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
return val.([]*model.RepoLite)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetRepos adds the listof user repositories to the cache assocaited
|
Set(c, key, repos)
|
||||||
// with the current context.
|
return repos, nil
|
||||||
func SetRepos(c context.Context, user *model.User, repos []*model.RepoLite) {
|
|
||||||
key := fmt.Sprintf("repos:%s",
|
|
||||||
user.Login,
|
|
||||||
)
|
|
||||||
FromContext(c).Set(key, repos)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSetRepos is a helper function that attempts to get the
|
|
||||||
// repository list from the cache first. If no data is in the
|
|
||||||
// cache or it is expired, it will remotely fetch the list of
|
|
||||||
// repositories and populate the cache.
|
|
||||||
// func GetSetRepos(c context.Context, user *model.User) ([]*model.RepoLite, error) {
|
|
||||||
// cache := FromContext(c).Repos()
|
|
||||||
// repos := FromContext(c).Repos().Get(user)
|
|
||||||
// if repos != nil {
|
|
||||||
// return repos, nil
|
|
||||||
// }
|
|
||||||
// var err error
|
|
||||||
// repos, err = remote.FromContext(c).Repos(user)
|
|
||||||
// if err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
// cache.Set(user, repos)
|
|
||||||
// return repos, nil
|
|
||||||
// }
|
|
||||||
|
|
74
cache/helper_test.go
vendored
74
cache/helper_test.go
vendored
|
@ -1,9 +1,13 @@
|
||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/drone/drone/model"
|
"github.com/drone/drone/model"
|
||||||
|
"github.com/drone/drone/remote"
|
||||||
|
"github.com/drone/drone/remote/mock"
|
||||||
"github.com/franela/goblin"
|
"github.com/franela/goblin"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
@ -11,43 +15,83 @@ import (
|
||||||
func TestHelper(t *testing.T) {
|
func TestHelper(t *testing.T) {
|
||||||
|
|
||||||
g := goblin.Goblin(t)
|
g := goblin.Goblin(t)
|
||||||
|
|
||||||
g.Describe("Cache helpers", func() {
|
g.Describe("Cache helpers", func() {
|
||||||
|
|
||||||
var c *gin.Context
|
var c *gin.Context
|
||||||
|
var r *mock.Remote
|
||||||
|
|
||||||
g.BeforeEach(func() {
|
g.BeforeEach(func() {
|
||||||
c = new(gin.Context)
|
c = new(gin.Context)
|
||||||
ToContext(c, Default())
|
ToContext(c, Default())
|
||||||
|
|
||||||
|
r = new(mock.Remote)
|
||||||
|
remote.ToContext(c, r)
|
||||||
})
|
})
|
||||||
|
|
||||||
g.It("Should set and get permissions", func() {
|
g.It("Should get permissions from remote", func() {
|
||||||
SetPerms(c, fakeUser, fakePerm, "octocat", "Spoon-Knife")
|
r.On("Perm", fakeUser, fakeRepo.Owner, fakeRepo.Name).Return(fakePerm, nil).Once()
|
||||||
|
p, err := GetPerms(c, fakeUser, fakeRepo.Owner, fakeRepo.Name)
|
||||||
|
g.Assert(p).Equal(fakePerm)
|
||||||
|
g.Assert(err).Equal(nil)
|
||||||
|
|
||||||
v := GetPerms(c, fakeUser, "octocat", "Spoon-Knife")
|
|
||||||
g.Assert(v).Equal(fakePerm)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
g.It("Should return nil if permissions if not found", func() {
|
g.It("Should get permissions from cache", func() {
|
||||||
v := GetPerms(c, fakeUser, "octocat", "Spoon-Knife")
|
key := fmt.Sprintf("perms:%s:%s/%s",
|
||||||
g.Assert(v == nil).IsTrue()
|
fakeUser.Login,
|
||||||
|
fakeRepo.Owner,
|
||||||
|
fakeRepo.Name,
|
||||||
|
)
|
||||||
|
|
||||||
|
Set(c, key, fakePerm)
|
||||||
|
r.On("Perm", fakeUser, fakeRepo.Owner, fakeRepo.Name).Return(nil, fakeErr).Once()
|
||||||
|
p, err := GetPerms(c, fakeUser, fakeRepo.Owner, fakeRepo.Name)
|
||||||
|
g.Assert(p).Equal(fakePerm)
|
||||||
|
g.Assert(err).Equal(nil)
|
||||||
})
|
})
|
||||||
|
|
||||||
g.It("Should set and get repositories", func() {
|
g.It("Should get permissions error", func() {
|
||||||
SetRepos(c, fakeUser, fakeRepos)
|
r.On("Perm", fakeUser, fakeRepo.Owner, fakeRepo.Name).Return(nil, fakeErr).Once()
|
||||||
|
p, err := GetPerms(c, fakeUser, fakeRepo.Owner, fakeRepo.Name)
|
||||||
v := GetRepos(c, fakeUser)
|
g.Assert(p == nil).IsTrue()
|
||||||
g.Assert(v).Equal(fakeRepos)
|
g.Assert(err).Equal(fakeErr)
|
||||||
})
|
})
|
||||||
|
|
||||||
g.It("Should return nil if repositories not found", func() {
|
g.It("Should set and get repos", func() {
|
||||||
v := GetRepos(c, fakeUser)
|
|
||||||
g.Assert(v == nil).IsTrue()
|
r.On("Repos", fakeUser).Return(fakeRepos, nil).Once()
|
||||||
|
p, err := GetRepos(c, fakeUser)
|
||||||
|
g.Assert(p).Equal(fakeRepos)
|
||||||
|
g.Assert(err).Equal(nil)
|
||||||
|
})
|
||||||
|
|
||||||
|
g.It("Should get repos", func() {
|
||||||
|
key := fmt.Sprintf("repos:%s",
|
||||||
|
fakeUser.Login,
|
||||||
|
)
|
||||||
|
|
||||||
|
Set(c, key, fakeRepos)
|
||||||
|
r.On("Repos", fakeUser).Return(nil, fakeErr).Once()
|
||||||
|
p, err := GetRepos(c, fakeUser)
|
||||||
|
g.Assert(p).Equal(fakeRepos)
|
||||||
|
g.Assert(err).Equal(nil)
|
||||||
|
})
|
||||||
|
|
||||||
|
g.It("Should get repos error", func() {
|
||||||
|
r.On("Repos", fakeUser).Return(nil, fakeErr).Once()
|
||||||
|
p, err := GetRepos(c, fakeUser)
|
||||||
|
g.Assert(p == nil).IsTrue()
|
||||||
|
g.Assert(err).Equal(fakeErr)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
fakeErr = errors.New("Not Found")
|
||||||
fakeUser = &model.User{Login: "octocat"}
|
fakeUser = &model.User{Login: "octocat"}
|
||||||
fakePerm = &model.Perm{true, true, true}
|
fakePerm = &model.Perm{true, true, true}
|
||||||
|
fakeRepo = &model.RepoLite{Owner: "octocat", Name: "Hello-World"}
|
||||||
fakeRepos = []*model.RepoLite{
|
fakeRepos = []*model.RepoLite{
|
||||||
{Owner: "octocat", Name: "Hello-World"},
|
{Owner: "octocat", Name: "Hello-World"},
|
||||||
{Owner: "octocat", Name: "hello-world"},
|
{Owner: "octocat", Name: "hello-world"},
|
||||||
|
|
|
@ -5,11 +5,10 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
|
"github.com/drone/drone/cache"
|
||||||
"github.com/drone/drone/model"
|
"github.com/drone/drone/model"
|
||||||
"github.com/drone/drone/remote"
|
|
||||||
"github.com/drone/drone/router/middleware/session"
|
"github.com/drone/drone/router/middleware/session"
|
||||||
"github.com/drone/drone/shared/httputil"
|
"github.com/drone/drone/shared/httputil"
|
||||||
"github.com/drone/drone/shared/token"
|
"github.com/drone/drone/shared/token"
|
||||||
|
@ -17,38 +16,19 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func ShowIndex(c *gin.Context) {
|
func ShowIndex(c *gin.Context) {
|
||||||
remote := remote.FromContext(c)
|
|
||||||
user := session.User(c)
|
user := session.User(c)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
c.Redirect(http.StatusSeeOther, "/login")
|
c.Redirect(http.StatusSeeOther, "/login")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
|
||||||
var repos []*model.RepoLite
|
|
||||||
|
|
||||||
// get the repository list from the cache
|
// get the repository list from the cache
|
||||||
reposv, ok := c.Get("repos")
|
repos, err := cache.GetRepos(c, user)
|
||||||
if ok {
|
if err != nil {
|
||||||
repos = reposv.([]*model.RepoLite)
|
c.String(400, err.Error())
|
||||||
} else {
|
return
|
||||||
repos, err = remote.Repos(user)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Failure to get remote repositories for %s. %s.",
|
|
||||||
user.Login, err)
|
|
||||||
} else {
|
|
||||||
c.Set("repos", repos)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// for each repository in the remote system we get
|
|
||||||
// the intersection of those repostiories in Drone
|
|
||||||
// repos_, err := store.GetRepoListOf(c, repos)
|
|
||||||
// if err != nil {
|
|
||||||
// log.Errorf("Failure to get repository list for %s. %s.",
|
|
||||||
// user.Login, err)
|
|
||||||
// }
|
|
||||||
|
|
||||||
c.HTML(200, "repos.html", gin.H{
|
c.HTML(200, "repos.html", gin.H{
|
||||||
"User": user,
|
"User": user,
|
||||||
"Repos": repos,
|
"Repos": repos,
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
|
|
||||||
|
"github.com/drone/drone/cache"
|
||||||
"github.com/drone/drone/model"
|
"github.com/drone/drone/model"
|
||||||
"github.com/drone/drone/remote"
|
"github.com/drone/drone/remote"
|
||||||
"github.com/drone/drone/router/middleware/session"
|
"github.com/drone/drone/router/middleware/session"
|
||||||
|
@ -34,7 +35,7 @@ func PostRepo(c *gin.Context) {
|
||||||
c.String(404, err.Error())
|
c.String(404, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
m, err := remote.Perm(user, owner, name)
|
m, err := cache.GetPerms(c, user, owner, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(404, err.Error())
|
c.String(404, err.Error())
|
||||||
return
|
return
|
||||||
|
@ -176,7 +177,7 @@ func PostRepoKey(c *gin.Context) {
|
||||||
body, err := ioutil.ReadAll(c.Request.Body)
|
body, err := ioutil.ReadAll(c.Request.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(500, "Error reading private key from body. %s", err)
|
c.String(500, "Error reading private key from body. %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
pkey := crypto.UnmarshalPrivateKey(body)
|
pkey := crypto.UnmarshalPrivateKey(body)
|
||||||
if pkey == nil {
|
if pkey == nil {
|
||||||
|
|
|
@ -5,8 +5,7 @@ import (
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
"github.com/drone/drone/model"
|
"github.com/drone/drone/cache"
|
||||||
"github.com/drone/drone/remote"
|
|
||||||
"github.com/drone/drone/router/middleware/session"
|
"github.com/drone/drone/router/middleware/session"
|
||||||
"github.com/drone/drone/shared/token"
|
"github.com/drone/drone/shared/token"
|
||||||
"github.com/drone/drone/store"
|
"github.com/drone/drone/store"
|
||||||
|
@ -18,20 +17,12 @@ func GetSelf(c *gin.Context) {
|
||||||
|
|
||||||
func GetFeed(c *gin.Context) {
|
func GetFeed(c *gin.Context) {
|
||||||
user := session.User(c)
|
user := session.User(c)
|
||||||
remote := remote.FromContext(c)
|
|
||||||
var repos []*model.RepoLite
|
|
||||||
|
|
||||||
// get the repository list from the cache
|
// get the repository list from the cache
|
||||||
reposv, ok := c.Get("repos")
|
repos, err := cache.GetRepos(c, user)
|
||||||
if ok {
|
if err != nil {
|
||||||
repos = reposv.([]*model.RepoLite)
|
c.String(400, err.Error())
|
||||||
} else {
|
return
|
||||||
var err error
|
|
||||||
repos, err = remote.Repos(user)
|
|
||||||
if err != nil {
|
|
||||||
c.String(400, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
feed, err := store.GetUserFeed(c, repos)
|
feed, err := store.GetUserFeed(c, repos)
|
||||||
|
@ -44,20 +35,11 @@ func GetFeed(c *gin.Context) {
|
||||||
|
|
||||||
func GetRepos(c *gin.Context) {
|
func GetRepos(c *gin.Context) {
|
||||||
user := session.User(c)
|
user := session.User(c)
|
||||||
remote := remote.FromContext(c)
|
|
||||||
var repos []*model.RepoLite
|
|
||||||
|
|
||||||
// get the repository list from the cache
|
repos, err := cache.GetRepos(c, user)
|
||||||
reposv, ok := c.Get("repos")
|
if err != nil {
|
||||||
if ok {
|
c.AbortWithStatus(http.StatusInternalServerError)
|
||||||
repos = reposv.([]*model.RepoLite)
|
return
|
||||||
} else {
|
|
||||||
var err error
|
|
||||||
repos, err = remote.Repos(user)
|
|
||||||
if err != nil {
|
|
||||||
c.AbortWithStatus(http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// for each repository in the remote system we get
|
// for each repository in the remote system we get
|
||||||
|
@ -68,27 +50,18 @@ func GetRepos(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Set("repos", repos)
|
|
||||||
c.IndentedJSON(http.StatusOK, repos_)
|
c.IndentedJSON(http.StatusOK, repos_)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetRemoteRepos(c *gin.Context) {
|
func GetRemoteRepos(c *gin.Context) {
|
||||||
user := session.User(c)
|
user := session.User(c)
|
||||||
remote := remote.FromContext(c)
|
|
||||||
|
|
||||||
reposv, ok := c.Get("repos")
|
repos, err := cache.GetRepos(c, user)
|
||||||
if ok {
|
|
||||||
c.IndentedJSON(http.StatusOK, reposv)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
repos, err := remote.Repos(user)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.AbortWithStatus(http.StatusInternalServerError)
|
c.AbortWithStatus(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Set("repos", repos)
|
|
||||||
c.IndentedJSON(http.StatusOK, repos)
|
c.IndentedJSON(http.StatusOK, repos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DefaultURL = "https://github.com"
|
DefaultURL = "https://github.com"
|
||||||
DefaultAPI = "https://api.github.com"
|
DefaultAPI = "https://api.github.com"
|
||||||
DefaultScope = "repo,repo:status,user:email"
|
DefaultScope = "repo,repo:status,user:email"
|
||||||
|
DefaultMergeRef = "merge"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Github struct {
|
type Github struct {
|
||||||
|
@ -29,6 +30,7 @@ type Github struct {
|
||||||
API string
|
API string
|
||||||
Client string
|
Client string
|
||||||
Secret string
|
Secret string
|
||||||
|
MergeRef string
|
||||||
Orgs []string
|
Orgs []string
|
||||||
Open bool
|
Open bool
|
||||||
PrivateMode bool
|
PrivateMode bool
|
||||||
|
@ -59,6 +61,7 @@ func Load(env envconfig.Env) *Github {
|
||||||
github.SkipVerify, _ = strconv.ParseBool(params.Get("skip_verify"))
|
github.SkipVerify, _ = strconv.ParseBool(params.Get("skip_verify"))
|
||||||
github.Open, _ = strconv.ParseBool(params.Get("open"))
|
github.Open, _ = strconv.ParseBool(params.Get("open"))
|
||||||
github.GitSSH, _ = strconv.ParseBool(params.Get("ssh"))
|
github.GitSSH, _ = strconv.ParseBool(params.Get("ssh"))
|
||||||
|
github.MergeRef = params.Get("merge_ref")
|
||||||
|
|
||||||
if github.URL == DefaultURL {
|
if github.URL == DefaultURL {
|
||||||
github.API = DefaultAPI
|
github.API = DefaultAPI
|
||||||
|
@ -66,6 +69,10 @@ func Load(env envconfig.Env) *Github {
|
||||||
github.API = github.URL + "/api/v3/"
|
github.API = github.URL + "/api/v3/"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if github.MergeRef == "" {
|
||||||
|
github.MergeRef = DefaultMergeRef
|
||||||
|
}
|
||||||
|
|
||||||
return &github
|
return &github
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,7 +409,7 @@ func (g *Github) pullRequest(r *http.Request) (*model.Repo, *model.Build, error)
|
||||||
build := &model.Build{}
|
build := &model.Build{}
|
||||||
build.Event = model.EventPull
|
build.Event = model.EventPull
|
||||||
build.Commit = *hook.PullRequest.Head.SHA
|
build.Commit = *hook.PullRequest.Head.SHA
|
||||||
build.Ref = fmt.Sprintf("refs/pull/%d/merge", *hook.PullRequest.Number)
|
build.Ref = fmt.Sprintf("refs/pull/%d/%s", *hook.PullRequest.Number, g.MergeRef)
|
||||||
build.Link = *hook.PullRequest.HTMLURL
|
build.Link = *hook.PullRequest.HTMLURL
|
||||||
build.Branch = *hook.PullRequest.Head.Ref
|
build.Branch = *hook.PullRequest.Head.Ref
|
||||||
build.Message = *hook.PullRequest.Title
|
build.Message = *hook.PullRequest.Title
|
||||||
|
|
238
remote/mock/remote.go
Normal file
238
remote/mock/remote.go
Normal file
|
@ -0,0 +1,238 @@
|
||||||
|
package mock
|
||||||
|
|
||||||
|
import "github.com/stretchr/testify/mock"
|
||||||
|
|
||||||
|
import "net/http"
|
||||||
|
import "github.com/drone/drone/model"
|
||||||
|
|
||||||
|
type Remote struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_m *Remote) Login(w http.ResponseWriter, r *http.Request) (*model.User, bool, error) {
|
||||||
|
ret := _m.Called(w, r)
|
||||||
|
|
||||||
|
var r0 *model.User
|
||||||
|
if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request) *model.User); ok {
|
||||||
|
r0 = rf(w, r)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*model.User)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 bool
|
||||||
|
if rf, ok := ret.Get(1).(func(http.ResponseWriter, *http.Request) bool); ok {
|
||||||
|
r1 = rf(w, r)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Get(1).(bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
var r2 error
|
||||||
|
if rf, ok := ret.Get(2).(func(http.ResponseWriter, *http.Request) error); ok {
|
||||||
|
r2 = rf(w, r)
|
||||||
|
} else {
|
||||||
|
r2 = ret.Error(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1, r2
|
||||||
|
}
|
||||||
|
func (_m *Remote) Auth(token string, secret string) (string, error) {
|
||||||
|
ret := _m.Called(token, secret)
|
||||||
|
|
||||||
|
var r0 string
|
||||||
|
if rf, ok := ret.Get(0).(func(string, string) string); ok {
|
||||||
|
r0 = rf(token, secret)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Get(0).(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func(string, string) error); ok {
|
||||||
|
r1 = rf(token, secret)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
func (_m *Remote) Repo(u *model.User, owner string, repo string) (*model.Repo, error) {
|
||||||
|
ret := _m.Called(u, owner, repo)
|
||||||
|
|
||||||
|
var r0 *model.Repo
|
||||||
|
if rf, ok := ret.Get(0).(func(*model.User, string, string) *model.Repo); ok {
|
||||||
|
r0 = rf(u, owner, repo)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*model.Repo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func(*model.User, string, string) error); ok {
|
||||||
|
r1 = rf(u, owner, repo)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
func (_m *Remote) Repos(u *model.User) ([]*model.RepoLite, error) {
|
||||||
|
ret := _m.Called(u)
|
||||||
|
|
||||||
|
var r0 []*model.RepoLite
|
||||||
|
if rf, ok := ret.Get(0).(func(*model.User) []*model.RepoLite); ok {
|
||||||
|
r0 = rf(u)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).([]*model.RepoLite)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func(*model.User) error); ok {
|
||||||
|
r1 = rf(u)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
func (_m *Remote) Perm(u *model.User, owner string, repo string) (*model.Perm, error) {
|
||||||
|
ret := _m.Called(u, owner, repo)
|
||||||
|
|
||||||
|
var r0 *model.Perm
|
||||||
|
if rf, ok := ret.Get(0).(func(*model.User, string, string) *model.Perm); ok {
|
||||||
|
r0 = rf(u, owner, repo)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*model.Perm)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func(*model.User, string, string) error); ok {
|
||||||
|
r1 = rf(u, owner, repo)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
func (_m *Remote) Script(u *model.User, r *model.Repo, b *model.Build) ([]byte, []byte, error) {
|
||||||
|
ret := _m.Called(u, r, b)
|
||||||
|
|
||||||
|
var r0 []byte
|
||||||
|
if rf, ok := ret.Get(0).(func(*model.User, *model.Repo, *model.Build) []byte); ok {
|
||||||
|
r0 = rf(u, r, b)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).([]byte)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 []byte
|
||||||
|
if rf, ok := ret.Get(1).(func(*model.User, *model.Repo, *model.Build) []byte); ok {
|
||||||
|
r1 = rf(u, r, b)
|
||||||
|
} else {
|
||||||
|
if ret.Get(1) != nil {
|
||||||
|
r1 = ret.Get(1).([]byte)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r2 error
|
||||||
|
if rf, ok := ret.Get(2).(func(*model.User, *model.Repo, *model.Build) error); ok {
|
||||||
|
r2 = rf(u, r, b)
|
||||||
|
} else {
|
||||||
|
r2 = ret.Error(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1, r2
|
||||||
|
}
|
||||||
|
func (_m *Remote) Status(u *model.User, r *model.Repo, b *model.Build, link string) error {
|
||||||
|
ret := _m.Called(u, r, b, link)
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(*model.User, *model.Repo, *model.Build, string) error); ok {
|
||||||
|
r0 = rf(u, r, b, link)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
func (_m *Remote) Netrc(u *model.User, r *model.Repo) (*model.Netrc, error) {
|
||||||
|
ret := _m.Called(u, r)
|
||||||
|
|
||||||
|
var r0 *model.Netrc
|
||||||
|
if rf, ok := ret.Get(0).(func(*model.User, *model.Repo) *model.Netrc); ok {
|
||||||
|
r0 = rf(u, r)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*model.Netrc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func(*model.User, *model.Repo) error); ok {
|
||||||
|
r1 = rf(u, r)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
func (_m *Remote) Activate(u *model.User, r *model.Repo, k *model.Key, link string) error {
|
||||||
|
ret := _m.Called(u, r, k, link)
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(*model.User, *model.Repo, *model.Key, string) error); ok {
|
||||||
|
r0 = rf(u, r, k, link)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
func (_m *Remote) Deactivate(u *model.User, r *model.Repo, link string) error {
|
||||||
|
ret := _m.Called(u, r, link)
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(*model.User, *model.Repo, string) error); ok {
|
||||||
|
r0 = rf(u, r, link)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
func (_m *Remote) Hook(r *http.Request) (*model.Repo, *model.Build, error) {
|
||||||
|
ret := _m.Called(r)
|
||||||
|
|
||||||
|
var r0 *model.Repo
|
||||||
|
if rf, ok := ret.Get(0).(func(*http.Request) *model.Repo); ok {
|
||||||
|
r0 = rf(r)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*model.Repo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 *model.Build
|
||||||
|
if rf, ok := ret.Get(1).(func(*http.Request) *model.Build); ok {
|
||||||
|
r1 = rf(r)
|
||||||
|
} else {
|
||||||
|
if ret.Get(1) != nil {
|
||||||
|
r1 = ret.Get(1).(*model.Build)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r2 error
|
||||||
|
if rf, ok := ret.Get(2).(func(*http.Request) error); ok {
|
||||||
|
r2 = rf(r)
|
||||||
|
} else {
|
||||||
|
r2 = ret.Error(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1, r2
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
package remote
|
package remote
|
||||||
|
|
||||||
|
//go:generate mockery -name Remote -output mock -case=underscore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
@ -10,7 +12,8 @@ import (
|
||||||
"github.com/drone/drone/remote/gogs"
|
"github.com/drone/drone/remote/gogs"
|
||||||
"github.com/drone/drone/shared/envconfig"
|
"github.com/drone/drone/shared/envconfig"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Load(env envconfig.Env) Remote {
|
func Load(env envconfig.Env) Remote {
|
||||||
|
@ -27,7 +30,7 @@ func Load(env envconfig.Env) Remote {
|
||||||
return gogs.Load(env)
|
return gogs.Load(env)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
log.Fatalf("unknown remote driver %s", driver)
|
logrus.Fatalf("unknown remote driver %s", driver)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -83,3 +86,79 @@ type Refresher interface {
|
||||||
// token was not refreshed, and error if it failed to refersh.
|
// token was not refreshed, and error if it failed to refersh.
|
||||||
Refresh(*model.User) (bool, error)
|
Refresh(*model.User) (bool, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Login authenticates the session and returns the
|
||||||
|
// remote user details.
|
||||||
|
func Login(c context.Context, w http.ResponseWriter, r *http.Request) (*model.User, bool, error) {
|
||||||
|
return FromContext(c).Login(w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auth authenticates the session and returns the remote user
|
||||||
|
// login for the given token and secret
|
||||||
|
func Auth(c context.Context, token, secret string) (string, error) {
|
||||||
|
return FromContext(c).Auth(token, secret)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Repo fetches the named repository from the remote system.
|
||||||
|
func Repo(c context.Context, u *model.User, owner, repo string) (*model.Repo, error) {
|
||||||
|
return FromContext(c).Repo(u, owner, repo)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Repos fetches a list of repos from the remote system.
|
||||||
|
func Repos(c context.Context, u *model.User) ([]*model.RepoLite, error) {
|
||||||
|
return FromContext(c).Repos(u)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perm fetches the named repository permissions from
|
||||||
|
// the remote system for the specified user.
|
||||||
|
func Perm(c context.Context, u *model.User, owner, repo string) (*model.Perm, error) {
|
||||||
|
return FromContext(c).Perm(u, owner, repo)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Script fetches the build script (.drone.yml) from the remote
|
||||||
|
// repository and returns in string format.
|
||||||
|
func Script(c context.Context, u *model.User, r *model.Repo, b *model.Build) ([]byte, []byte, error) {
|
||||||
|
return FromContext(c).Script(u, r, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Status sends the commit status to the remote system.
|
||||||
|
// An example would be the GitHub pull request status.
|
||||||
|
func Status(c context.Context, u *model.User, r *model.Repo, b *model.Build, link string) error {
|
||||||
|
return FromContext(c).Status(u, r, b, link)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Netrc returns a .netrc file that can be used to clone
|
||||||
|
// private repositories from a remote system.
|
||||||
|
func Netrc(c context.Context, u *model.User, r *model.Repo) (*model.Netrc, error) {
|
||||||
|
return FromContext(c).Netrc(u, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Activate activates a repository by creating the post-commit hook and
|
||||||
|
// adding the SSH deploy key, if applicable.
|
||||||
|
func Activate(c context.Context, u *model.User, r *model.Repo, k *model.Key, link string) error {
|
||||||
|
return FromContext(c).Activate(u, r, k, link)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deactivate removes a repository by removing all the post-commit hooks
|
||||||
|
// which are equal to link and removing the SSH deploy key.
|
||||||
|
func Deactivate(c context.Context, u *model.User, r *model.Repo, link string) error {
|
||||||
|
return FromContext(c).Deactivate(u, r, link)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hook parses the post-commit hook from the Request body
|
||||||
|
// and returns the required data in a standard format.
|
||||||
|
func Hook(c context.Context, r *http.Request) (*model.Repo, *model.Build, error) {
|
||||||
|
return FromContext(c).Hook(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh refreshes an oauth token and expiration for the given
|
||||||
|
// user. It returns true if the token was refreshed, false if the
|
||||||
|
// token was not refreshed, and error if it failed to refersh.
|
||||||
|
func Refresh(c context.Context, u *model.User) (bool, error) {
|
||||||
|
remote := FromContext(c)
|
||||||
|
refresher, ok := remote.(Refresher)
|
||||||
|
if !ok {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return refresher.Refresh(u)
|
||||||
|
}
|
||||||
|
|
54
router/middleware/cache/perms.go
vendored
54
router/middleware/cache/perms.go
vendored
|
@ -1,54 +0,0 @@
|
||||||
package cache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/drone/drone/cache"
|
|
||||||
"github.com/drone/drone/model"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
const permKey = "perm"
|
|
||||||
|
|
||||||
// Perms is a middleware function that attempts to cache the
|
|
||||||
// user's remote repository permissions (ie in GitHub) to minimize
|
|
||||||
// remote calls that might be expensive, slow or rate-limited.
|
|
||||||
func Perms(c *gin.Context) {
|
|
||||||
var (
|
|
||||||
owner = c.Param("owner")
|
|
||||||
name = c.Param("name")
|
|
||||||
user, _ = c.Get("user")
|
|
||||||
)
|
|
||||||
|
|
||||||
if user == nil {
|
|
||||||
c.Next()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the item already exists in the cache
|
|
||||||
// we can continue the middleware chain and
|
|
||||||
// exit afterwards.
|
|
||||||
v := cache.GetPerms(c,
|
|
||||||
user.(*model.User),
|
|
||||||
owner,
|
|
||||||
name,
|
|
||||||
)
|
|
||||||
if v != nil {
|
|
||||||
c.Set("perm", v)
|
|
||||||
c.Next()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise, if the item isn't cached we execute
|
|
||||||
// the middleware chain and then cache the permissions
|
|
||||||
// after the request is processed.
|
|
||||||
c.Next()
|
|
||||||
|
|
||||||
perm, ok := c.Get("perm")
|
|
||||||
if ok {
|
|
||||||
cache.SetPerms(c,
|
|
||||||
user.(*model.User),
|
|
||||||
perm.(*model.Perm),
|
|
||||||
owner,
|
|
||||||
name,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
61
router/middleware/cache/perms_test.go
vendored
61
router/middleware/cache/perms_test.go
vendored
|
@ -1,61 +0,0 @@
|
||||||
package cache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/drone/drone/cache"
|
|
||||||
"github.com/drone/drone/model"
|
|
||||||
"github.com/franela/goblin"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPermCache(t *testing.T) {
|
|
||||||
|
|
||||||
g := goblin.Goblin(t)
|
|
||||||
g.Describe("Perm Cache", func() {
|
|
||||||
|
|
||||||
var c *gin.Context
|
|
||||||
g.BeforeEach(func() {
|
|
||||||
c = new(gin.Context)
|
|
||||||
cache.ToContext(c, cache.Default())
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("should skip when no user session", func() {
|
|
||||||
c.Params = gin.Params{
|
|
||||||
gin.Param{Key: "owner", Value: "octocat"},
|
|
||||||
gin.Param{Key: "name", Value: "hello-world"},
|
|
||||||
}
|
|
||||||
|
|
||||||
Perms(c)
|
|
||||||
|
|
||||||
_, ok := c.Get("perm")
|
|
||||||
g.Assert(ok).IsFalse()
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("should get perms from cache", func() {
|
|
||||||
c.Params = gin.Params{
|
|
||||||
gin.Param{Key: "owner", Value: "octocat"},
|
|
||||||
gin.Param{Key: "name", Value: "hello-world"},
|
|
||||||
}
|
|
||||||
c.Set("user", fakeUser)
|
|
||||||
cache.SetPerms(c, fakeUser, fakePerm, "octocat", "hello-world")
|
|
||||||
|
|
||||||
Perms(c)
|
|
||||||
|
|
||||||
perm, ok := c.Get("perm")
|
|
||||||
g.Assert(ok).IsTrue()
|
|
||||||
g.Assert(perm).Equal(fakePerm)
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var fakePerm = &model.Perm{
|
|
||||||
Pull: true,
|
|
||||||
Push: true,
|
|
||||||
Admin: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
var fakeUser = &model.User{
|
|
||||||
Login: "octocat",
|
|
||||||
}
|
|
42
router/middleware/cache/repos.go
vendored
42
router/middleware/cache/repos.go
vendored
|
@ -1,42 +0,0 @@
|
||||||
package cache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/drone/drone/cache"
|
|
||||||
"github.com/drone/drone/model"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Repos is a middleware function that attempts to cache the
|
|
||||||
// user's list of remote repositories (ie in GitHub) to minimize
|
|
||||||
// remote calls that might be expensive, slow or rate-limited.
|
|
||||||
func Repos(c *gin.Context) {
|
|
||||||
var user, _ = c.Get("user")
|
|
||||||
|
|
||||||
if user == nil {
|
|
||||||
c.Next()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the item already exists in the cache
|
|
||||||
// we can continue the middleware chain and
|
|
||||||
// exit afterwards.
|
|
||||||
v := cache.GetRepos(c, user.(*model.User))
|
|
||||||
if v != nil {
|
|
||||||
c.Set("repos", v)
|
|
||||||
c.Next()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise, if the item isn't cached we execute
|
|
||||||
// the middleware chain and then cache the permissions
|
|
||||||
// after the request is processed.
|
|
||||||
c.Next()
|
|
||||||
|
|
||||||
repos, ok := c.Get("repos")
|
|
||||||
if ok {
|
|
||||||
cache.SetRepos(c,
|
|
||||||
user.(*model.User),
|
|
||||||
repos.([]*model.RepoLite),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
46
router/middleware/cache/repos_test.go
vendored
46
router/middleware/cache/repos_test.go
vendored
|
@ -1,46 +0,0 @@
|
||||||
package cache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/drone/drone/cache"
|
|
||||||
"github.com/drone/drone/model"
|
|
||||||
"github.com/franela/goblin"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestReposCache(t *testing.T) {
|
|
||||||
|
|
||||||
g := goblin.Goblin(t)
|
|
||||||
g.Describe("Repo List Cache", func() {
|
|
||||||
|
|
||||||
var c *gin.Context
|
|
||||||
g.BeforeEach(func() {
|
|
||||||
c = new(gin.Context)
|
|
||||||
cache.ToContext(c, cache.Default())
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("should skip when no user session", func() {
|
|
||||||
Perms(c)
|
|
||||||
|
|
||||||
_, ok := c.Get("perm")
|
|
||||||
g.Assert(ok).IsFalse()
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("should get repos from cache", func() {
|
|
||||||
c.Set("user", fakeUser)
|
|
||||||
cache.SetRepos(c, fakeUser, fakeRepos)
|
|
||||||
|
|
||||||
Repos(c)
|
|
||||||
|
|
||||||
repos, ok := c.Get("repos")
|
|
||||||
g.Assert(ok).IsTrue()
|
|
||||||
g.Assert(repos).Equal(fakeRepos)
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var fakeRepos = []*model.RepoLite{
|
|
||||||
{Owner: "octocat", Name: "hello-world"},
|
|
||||||
}
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/drone/drone/cache"
|
||||||
"github.com/drone/drone/model"
|
"github.com/drone/drone/model"
|
||||||
"github.com/drone/drone/remote"
|
"github.com/drone/drone/remote"
|
||||||
"github.com/drone/drone/shared/token"
|
"github.com/drone/drone/shared/token"
|
||||||
|
@ -112,19 +113,6 @@ func SetPerm() gin.HandlerFunc {
|
||||||
repo := Repo(c)
|
repo := Repo(c)
|
||||||
perm := &model.Perm{}
|
perm := &model.Perm{}
|
||||||
|
|
||||||
if user != nil {
|
|
||||||
// attempt to get the permissions from a local cache
|
|
||||||
// just to avoid excess API calls to GitHub
|
|
||||||
val, ok := c.Get("perm")
|
|
||||||
if ok {
|
|
||||||
c.Next()
|
|
||||||
|
|
||||||
log.Debugf("%s using cached %+v permission to %s",
|
|
||||||
user.Login, val, repo.FullName)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
// if the user is not authenticated, and the
|
// if the user is not authenticated, and the
|
||||||
// repository is private, the user has NO permission
|
// repository is private, the user has NO permission
|
||||||
|
@ -150,7 +138,7 @@ func SetPerm() gin.HandlerFunc {
|
||||||
// check the remote system to get the users permissiosn.
|
// check the remote system to get the users permissiosn.
|
||||||
default:
|
default:
|
||||||
var err error
|
var err error
|
||||||
perm, err = remote.FromContext(c).Perm(user, repo.Owner, repo.Name)
|
perm, err = cache.GetPerms(c, user, repo.Owner, repo.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
perm.Pull = false
|
perm.Pull = false
|
||||||
perm.Push = false
|
perm.Push = false
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
"github.com/drone/drone/controller"
|
"github.com/drone/drone/controller"
|
||||||
"github.com/drone/drone/router/middleware/cache"
|
|
||||||
"github.com/drone/drone/router/middleware/header"
|
"github.com/drone/drone/router/middleware/header"
|
||||||
"github.com/drone/drone/router/middleware/location"
|
"github.com/drone/drone/router/middleware/location"
|
||||||
"github.com/drone/drone/router/middleware/session"
|
"github.com/drone/drone/router/middleware/session"
|
||||||
|
@ -27,10 +26,9 @@ func Load(middleware ...gin.HandlerFunc) http.Handler {
|
||||||
e.Use(header.Secure)
|
e.Use(header.Secure)
|
||||||
e.Use(middleware...)
|
e.Use(middleware...)
|
||||||
e.Use(session.SetUser())
|
e.Use(session.SetUser())
|
||||||
e.Use(cache.Perms)
|
|
||||||
e.Use(token.Refresh)
|
e.Use(token.Refresh)
|
||||||
|
|
||||||
e.GET("/", cache.Repos, controller.ShowIndex)
|
e.GET("/", controller.ShowIndex)
|
||||||
e.GET("/login", controller.ShowLogin)
|
e.GET("/login", controller.ShowLogin)
|
||||||
e.GET("/login/form", controller.ShowLoginForm)
|
e.GET("/login/form", controller.ShowLoginForm)
|
||||||
e.GET("/logout", controller.GetLogout)
|
e.GET("/logout", controller.GetLogout)
|
||||||
|
@ -64,8 +62,8 @@ func Load(middleware ...gin.HandlerFunc) http.Handler {
|
||||||
user.Use(session.MustUser())
|
user.Use(session.MustUser())
|
||||||
user.GET("", controller.GetSelf)
|
user.GET("", controller.GetSelf)
|
||||||
user.GET("/feed", controller.GetFeed)
|
user.GET("/feed", controller.GetFeed)
|
||||||
user.GET("/repos", cache.Repos, controller.GetRepos)
|
user.GET("/repos", controller.GetRepos)
|
||||||
user.GET("/repos/remote", cache.Repos, controller.GetRemoteRepos)
|
user.GET("/repos/remote", controller.GetRemoteRepos)
|
||||||
user.POST("/token", controller.PostToken)
|
user.POST("/token", controller.PostToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue