ability to manage tokens
This commit is contained in:
parent
701626881e
commit
57188ee4f2
5 changed files with 85 additions and 22 deletions
|
@ -1,6 +1,8 @@
|
|||
package bolt
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/boltdb/bolt"
|
||||
"github.com/drone/drone/common"
|
||||
)
|
||||
|
@ -22,16 +24,44 @@ func (db *DB) GetToken(user, label string) (*common.Token, error) {
|
|||
func (db *DB) InsertToken(token *common.Token) error {
|
||||
key := []byte(token.Login + "/" + token.Label)
|
||||
return db.Update(func(t *bolt.Tx) error {
|
||||
// gets an index
|
||||
var idx [][]byte
|
||||
err := get(t, bucketUserTokens, []byte(token.Login), &idx)
|
||||
if err != nil && err != ErrKeyNotFound {
|
||||
return err
|
||||
}
|
||||
// pushes to the index
|
||||
idx = append(idx, key)
|
||||
err = update(t, bucketUserTokens, []byte(token.Login), &idx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return insert(t, bucketTokens, key, token)
|
||||
})
|
||||
// TODO(bradrydzewski) add token to users_token index
|
||||
}
|
||||
|
||||
// DeleteUser deletes the token.
|
||||
func (db *DB) DeleteToken(token *common.Token) error {
|
||||
key := []byte(token.Login + "/" + token.Label)
|
||||
return db.Update(func(t *bolt.Tx) error {
|
||||
// gets an index
|
||||
var idx [][]byte
|
||||
err := get(t, bucketUserTokens, []byte(token.Login), &idx)
|
||||
if err != nil && err != ErrKeyNotFound {
|
||||
return err
|
||||
}
|
||||
// pushes to the index
|
||||
for i, val := range idx {
|
||||
if bytes.Equal(val, key) {
|
||||
idx = idx[:i+copy(idx[i:], idx[i+1:])]
|
||||
break
|
||||
}
|
||||
}
|
||||
err = update(t, bucketUserTokens, []byte(token.Login), &idx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return delete(t, bucketUser, key)
|
||||
})
|
||||
// TODO(bradrydzewski) remove token from users_token index
|
||||
}
|
||||
|
|
|
@ -1,17 +1,39 @@
|
|||
package bolt
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/drone/drone/common"
|
||||
. "github.com/franela/goblin"
|
||||
)
|
||||
|
||||
func TestToken(t *testing.T) {
|
||||
g := Goblin(t)
|
||||
g.Describe("Tokens", func() {
|
||||
var db *DB // temporary database
|
||||
|
||||
g.It("Should find by sha")
|
||||
g.It("Should list for user")
|
||||
// create a new database before each unit
|
||||
// test and destroy afterwards.
|
||||
g.BeforeEach(func() {
|
||||
db = Must("/tmp/drone.test.db")
|
||||
})
|
||||
g.AfterEach(func() {
|
||||
os.Remove(db.Path())
|
||||
})
|
||||
|
||||
g.It("Should find by label")
|
||||
g.It("Should list for user", func() {
|
||||
db.InsertUser(&common.User{Login: "octocat"})
|
||||
err1 := db.InsertToken(&common.Token{Login: "octocat", Label: "gist"})
|
||||
err2 := db.InsertToken(&common.Token{Login: "octocat", Label: "github"})
|
||||
g.Assert(err1).Equal(nil)
|
||||
g.Assert(err2).Equal(nil)
|
||||
|
||||
list, err := db.GetUserTokens("octocat")
|
||||
g.Assert(err).Equal(nil)
|
||||
g.Assert(len(list)).Equal(2)
|
||||
})
|
||||
g.It("Should delete")
|
||||
g.It("Should insert")
|
||||
g.It("Should not insert if exists")
|
||||
|
|
|
@ -3,8 +3,8 @@ package bolt
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/drone/drone/common"
|
||||
"github.com/boltdb/bolt"
|
||||
"github.com/drone/drone/common"
|
||||
)
|
||||
|
||||
// GetUser gets a user by user login.
|
||||
|
@ -31,26 +31,24 @@ func (db *DB) GetUserTokens(login string) ([]*common.Token, error) {
|
|||
|
||||
// get the index of user tokens and unmarshal
|
||||
// to a string array.
|
||||
key := []byte(login)
|
||||
raw := t.Bucket(bucketUserTokens).Get(key)
|
||||
keys := [][]byte{}
|
||||
err = decode(raw, &keys)
|
||||
if err != nil {
|
||||
return tokens, err
|
||||
var keys [][]byte
|
||||
err = get(t, bucketUserTokens, []byte(login), &keys)
|
||||
if err != nil && err != ErrKeyNotFound {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// for each item in the index, get the repository
|
||||
// and append to the array
|
||||
for _, key := range keys {
|
||||
token := &common.Token{}
|
||||
raw = t.Bucket(bucketTokens).Get(key)
|
||||
raw := t.Bucket(bucketTokens).Get(key)
|
||||
err = decode(raw, token)
|
||||
if err != nil {
|
||||
break
|
||||
return nil, err
|
||||
}
|
||||
tokens = append(tokens, token)
|
||||
}
|
||||
return tokens, err
|
||||
return tokens, nil
|
||||
}
|
||||
|
||||
// GetUserRepos gets a list of repositories for the
|
||||
|
|
3
drone.go
3
drone.go
|
@ -43,6 +43,9 @@ func main() {
|
|||
user.GET("", server.GetUserCurr)
|
||||
user.PUT("", server.PutUserCurr)
|
||||
user.GET("/repos", server.GetUserRepos)
|
||||
user.GET("/tokens", server.GetUserTokens)
|
||||
user.POST("/tokens", server.PostToken)
|
||||
user.DELETE("/tokens", server.DelToken)
|
||||
}
|
||||
|
||||
users := api.Group("/users")
|
||||
|
|
|
@ -2,19 +2,26 @@ package server
|
|||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
|
||||
"github.com/drone/drone/common"
|
||||
)
|
||||
|
||||
// POST /api/user/tokens/:label
|
||||
// POST /api/user/tokens
|
||||
func PostToken(c *gin.Context) {
|
||||
store := ToDatastore(c)
|
||||
sess := ToSession(c)
|
||||
user := ToUser(c)
|
||||
label := c.Params.ByName("label")
|
||||
|
||||
in := &common.Token{}
|
||||
if !c.BindWith(in, binding.JSON) {
|
||||
return
|
||||
}
|
||||
|
||||
token := &common.Token{}
|
||||
token.Label = label
|
||||
token.Label = in.Label
|
||||
token.Repos = in.Repos
|
||||
token.Scopes = in.Scopes
|
||||
token.Login = user.Login
|
||||
token.Kind = common.TokenUser
|
||||
|
||||
|
@ -30,11 +37,12 @@ func PostToken(c *gin.Context) {
|
|||
c.String(200, jwt)
|
||||
}
|
||||
|
||||
// DELETE /api/user/tokens/:label
|
||||
// DELETE /api/user/tokens
|
||||
func DelToken(c *gin.Context) {
|
||||
store := ToDatastore(c)
|
||||
user := ToUser(c)
|
||||
label := c.Params.ByName("label")
|
||||
|
||||
token, err := store.GetToken(user.Login, label)
|
||||
if err != nil {
|
||||
c.Fail(404, err)
|
||||
|
@ -43,4 +51,6 @@ func DelToken(c *gin.Context) {
|
|||
if err != nil {
|
||||
c.Fail(400, err)
|
||||
}
|
||||
|
||||
c.Writer.WriteHeader(200)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue