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
|
package bolt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
|
||||||
"github.com/boltdb/bolt"
|
"github.com/boltdb/bolt"
|
||||||
"github.com/drone/drone/common"
|
"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 {
|
func (db *DB) InsertToken(token *common.Token) error {
|
||||||
key := []byte(token.Login + "/" + token.Label)
|
key := []byte(token.Login + "/" + token.Label)
|
||||||
return db.Update(func(t *bolt.Tx) error {
|
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)
|
return insert(t, bucketTokens, key, token)
|
||||||
})
|
})
|
||||||
// TODO(bradrydzewski) add token to users_token index
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteUser deletes the token.
|
// DeleteUser deletes the token.
|
||||||
func (db *DB) DeleteToken(token *common.Token) error {
|
func (db *DB) DeleteToken(token *common.Token) error {
|
||||||
key := []byte(token.Login + "/" + token.Label)
|
key := []byte(token.Login + "/" + token.Label)
|
||||||
return db.Update(func(t *bolt.Tx) error {
|
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)
|
return delete(t, bucketUser, key)
|
||||||
})
|
})
|
||||||
// TODO(bradrydzewski) remove token from users_token index
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,39 @@
|
||||||
package bolt
|
package bolt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/drone/drone/common"
|
||||||
. "github.com/franela/goblin"
|
. "github.com/franela/goblin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestToken(t *testing.T) {
|
func TestToken(t *testing.T) {
|
||||||
g := Goblin(t)
|
g := Goblin(t)
|
||||||
g.Describe("Tokens", func() {
|
g.Describe("Tokens", func() {
|
||||||
|
var db *DB // temporary database
|
||||||
|
|
||||||
g.It("Should find by sha")
|
// create a new database before each unit
|
||||||
g.It("Should list for user")
|
// 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 delete")
|
||||||
g.It("Should insert")
|
g.It("Should insert")
|
||||||
g.It("Should not insert if exists")
|
g.It("Should not insert if exists")
|
||||||
|
|
|
@ -3,8 +3,8 @@ package bolt
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/drone/drone/common"
|
|
||||||
"github.com/boltdb/bolt"
|
"github.com/boltdb/bolt"
|
||||||
|
"github.com/drone/drone/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetUser gets a user by user login.
|
// GetUser gets a user by user login.
|
||||||
|
@ -12,7 +12,7 @@ func (db *DB) GetUser(login string) (*common.User, error) {
|
||||||
user := &common.User{}
|
user := &common.User{}
|
||||||
key := []byte(login)
|
key := []byte(login)
|
||||||
|
|
||||||
err := db.View(func (t *bolt.Tx) error {
|
err := db.View(func(t *bolt.Tx) error {
|
||||||
return get(t, bucketUser, key, user)
|
return get(t, bucketUser, key, user)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -31,26 +31,24 @@ func (db *DB) GetUserTokens(login string) ([]*common.Token, error) {
|
||||||
|
|
||||||
// get the index of user tokens and unmarshal
|
// get the index of user tokens and unmarshal
|
||||||
// to a string array.
|
// to a string array.
|
||||||
key := []byte(login)
|
var keys [][]byte
|
||||||
raw := t.Bucket(bucketUserTokens).Get(key)
|
err = get(t, bucketUserTokens, []byte(login), &keys)
|
||||||
keys := [][]byte{}
|
if err != nil && err != ErrKeyNotFound {
|
||||||
err = decode(raw, &keys)
|
return nil, err
|
||||||
if err != nil {
|
|
||||||
return tokens, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// for each item in the index, get the repository
|
// for each item in the index, get the repository
|
||||||
// and append to the array
|
// and append to the array
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
token := &common.Token{}
|
token := &common.Token{}
|
||||||
raw = t.Bucket(bucketTokens).Get(key)
|
raw := t.Bucket(bucketTokens).Get(key)
|
||||||
err = decode(raw, token)
|
err = decode(raw, token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
return nil, err
|
||||||
}
|
}
|
||||||
tokens = append(tokens, token)
|
tokens = append(tokens, token)
|
||||||
}
|
}
|
||||||
return tokens, err
|
return tokens, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserRepos gets a list of repositories for the
|
// GetUserRepos gets a list of repositories for the
|
||||||
|
@ -126,7 +124,7 @@ func (db *DB) UpdateUser(user *common.User) error {
|
||||||
key := []byte(user.Login)
|
key := []byte(user.Login)
|
||||||
user.Updated = time.Now().UTC().Unix()
|
user.Updated = time.Now().UTC().Unix()
|
||||||
|
|
||||||
return db.Update(func (t *bolt.Tx) error {
|
return db.Update(func(t *bolt.Tx) error {
|
||||||
return update(t, bucketUser, key, user)
|
return update(t, bucketUser, key, user)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -138,7 +136,7 @@ func (db *DB) InsertUser(user *common.User) error {
|
||||||
user.Created = time.Now().UTC().Unix()
|
user.Created = time.Now().UTC().Unix()
|
||||||
user.Updated = time.Now().UTC().Unix()
|
user.Updated = time.Now().UTC().Unix()
|
||||||
|
|
||||||
return db.Update(func (t *bolt.Tx) error {
|
return db.Update(func(t *bolt.Tx) error {
|
||||||
return insert(t, bucketUser, key, user)
|
return insert(t, bucketUser, key, user)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -149,7 +147,7 @@ func (db *DB) DeleteUser(user *common.User) error {
|
||||||
// TODO(bradrydzewski) delete user subscriptions
|
// TODO(bradrydzewski) delete user subscriptions
|
||||||
// TODO(bradrydzewski) delete user tokens
|
// TODO(bradrydzewski) delete user tokens
|
||||||
|
|
||||||
return db.Update(func (t *bolt.Tx) error {
|
return db.Update(func(t *bolt.Tx) error {
|
||||||
return delete(t, bucketUser, key)
|
return delete(t, bucketUser, key)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
3
drone.go
3
drone.go
|
@ -43,6 +43,9 @@ func main() {
|
||||||
user.GET("", server.GetUserCurr)
|
user.GET("", server.GetUserCurr)
|
||||||
user.PUT("", server.PutUserCurr)
|
user.PUT("", server.PutUserCurr)
|
||||||
user.GET("/repos", server.GetUserRepos)
|
user.GET("/repos", server.GetUserRepos)
|
||||||
|
user.GET("/tokens", server.GetUserTokens)
|
||||||
|
user.POST("/tokens", server.PostToken)
|
||||||
|
user.DELETE("/tokens", server.DelToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
users := api.Group("/users")
|
users := api.Group("/users")
|
||||||
|
|
|
@ -2,19 +2,26 @@ package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/gin-gonic/gin/binding"
|
||||||
|
|
||||||
"github.com/drone/drone/common"
|
"github.com/drone/drone/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
// POST /api/user/tokens/:label
|
// POST /api/user/tokens
|
||||||
func PostToken(c *gin.Context) {
|
func PostToken(c *gin.Context) {
|
||||||
store := ToDatastore(c)
|
store := ToDatastore(c)
|
||||||
sess := ToSession(c)
|
sess := ToSession(c)
|
||||||
user := ToUser(c)
|
user := ToUser(c)
|
||||||
label := c.Params.ByName("label")
|
|
||||||
|
in := &common.Token{}
|
||||||
|
if !c.BindWith(in, binding.JSON) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
token := &common.Token{}
|
token := &common.Token{}
|
||||||
token.Label = label
|
token.Label = in.Label
|
||||||
|
token.Repos = in.Repos
|
||||||
|
token.Scopes = in.Scopes
|
||||||
token.Login = user.Login
|
token.Login = user.Login
|
||||||
token.Kind = common.TokenUser
|
token.Kind = common.TokenUser
|
||||||
|
|
||||||
|
@ -30,11 +37,12 @@ func PostToken(c *gin.Context) {
|
||||||
c.String(200, jwt)
|
c.String(200, jwt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DELETE /api/user/tokens/:label
|
// DELETE /api/user/tokens
|
||||||
func DelToken(c *gin.Context) {
|
func DelToken(c *gin.Context) {
|
||||||
store := ToDatastore(c)
|
store := ToDatastore(c)
|
||||||
user := ToUser(c)
|
user := ToUser(c)
|
||||||
label := c.Params.ByName("label")
|
label := c.Params.ByName("label")
|
||||||
|
|
||||||
token, err := store.GetToken(user.Login, label)
|
token, err := store.GetToken(user.Login, label)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Fail(404, err)
|
c.Fail(404, err)
|
||||||
|
@ -43,4 +51,6 @@ func DelToken(c *gin.Context) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Fail(400, err)
|
c.Fail(400, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.Writer.WriteHeader(200)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue