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

View file

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

View file

@ -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.
@ -12,7 +12,7 @@ func (db *DB) GetUser(login string) (*common.User, error) {
user := &common.User{}
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)
})
@ -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
@ -126,7 +124,7 @@ func (db *DB) UpdateUser(user *common.User) error {
key := []byte(user.Login)
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)
})
}
@ -138,7 +136,7 @@ func (db *DB) InsertUser(user *common.User) error {
user.Created = 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)
})
}
@ -149,7 +147,7 @@ func (db *DB) DeleteUser(user *common.User) error {
// TODO(bradrydzewski) delete user subscriptions
// 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)
})
}

View file

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

View file

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