ability to manage tokens

This commit is contained in:
Brad Rydzewski 2015-04-13 01:22:51 -07:00
parent 701626881e
commit 57188ee4f2
5 changed files with 85 additions and 22 deletions

View file

@ -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
} }

View file

@ -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")

View file

@ -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)
}) })
} }

View file

@ -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")

View file

@ -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)
} }