tokens, last build
This commit is contained in:
parent
840ea6d595
commit
087f92f41f
13 changed files with 127 additions and 58 deletions
|
@ -20,7 +20,7 @@ type Repo struct {
|
|||
Created int64 `json:"created_at"`
|
||||
Updated int64 `json:"updated_at"`
|
||||
|
||||
User *User `json:"user,omitempty"`
|
||||
User *Owner `json:"user,omitempty"`
|
||||
Last *Build `json:"last_build,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,11 @@ type Keypair struct {
|
|||
Private string `json:"-"`
|
||||
}
|
||||
|
||||
// Owner represents the owner of a repository.
|
||||
type Owner struct {
|
||||
Login string `json:"login"`
|
||||
}
|
||||
|
||||
// Subscriber represents a user's subscription
|
||||
// to a repository. This determines if the repository
|
||||
// is displayed on the user dashboard and in the user
|
||||
|
|
|
@ -14,4 +14,8 @@ type User struct {
|
|||
// Repos contains a list of subscriptions
|
||||
// to repositories the user is watching.
|
||||
Repos map[string]struct{} `json:"-"`
|
||||
|
||||
// Tokens contains a list of tokens for
|
||||
// the user account.
|
||||
Tokens map[string]struct{} `json:"-"`
|
||||
}
|
||||
|
|
|
@ -35,9 +35,15 @@ func (db *DB) GetBuildList(repo string) ([]*common.Build, error) {
|
|||
// GetBuildLast gets the last executed build for the
|
||||
// named repository.
|
||||
func (db *DB) GetBuildLast(repo string) (*common.Build, error) {
|
||||
// get the last build sequence number (stored in key in `bucketBuildSeq`)
|
||||
// return that build
|
||||
return nil, nil
|
||||
key := []byte(repo)
|
||||
build := &common.Build{}
|
||||
err := db.View(func(t *bolt.Tx) error {
|
||||
raw := t.Bucket(bucketBuildSeq).Get(key)
|
||||
num := binary.LittleEndian.Uint32(raw)
|
||||
key = []byte(repo + "/" + strconv.FormatUint(uint64(num), 10))
|
||||
return get(t, bucketBuild, key, build)
|
||||
})
|
||||
return build, err
|
||||
}
|
||||
|
||||
// GetBuildStatus gets the named build status for the
|
||||
|
@ -78,17 +84,17 @@ func (db *DB) GetBuildStatusList(repo string, build int) ([]*common.Status, erro
|
|||
func (db *DB) InsertBuild(repo string, build *common.Build) error {
|
||||
key := []byte(repo)
|
||||
|
||||
return db.Update(func (t *bolt.Tx) error {
|
||||
return db.Update(func(t *bolt.Tx) error {
|
||||
raw, err := raw(t, bucketBuildSeq, key)
|
||||
|
||||
var next_seq uint32
|
||||
switch err {
|
||||
case ErrKeyNotFound:
|
||||
next_seq = 1
|
||||
case nil:
|
||||
next_seq = 1 + binary.LittleEndian.Uint32(raw)
|
||||
default:
|
||||
return err
|
||||
case ErrKeyNotFound:
|
||||
next_seq = 1
|
||||
case nil:
|
||||
next_seq = 1 + binary.LittleEndian.Uint32(raw)
|
||||
default:
|
||||
return err
|
||||
}
|
||||
|
||||
// covert our seqno to raw value
|
||||
|
|
|
@ -42,5 +42,15 @@ func TestBuild(t *testing.T) {
|
|||
g.Assert(build.State).Equal("success")
|
||||
})
|
||||
|
||||
g.It("Should get the latest builds", func() {
|
||||
db.InsertBuild(repo, &common.Build{State: "success"})
|
||||
db.InsertBuild(repo, &common.Build{State: "success"})
|
||||
db.InsertBuild(repo, &common.Build{State: "pending"})
|
||||
|
||||
build, err := db.GetBuildLast(repo)
|
||||
g.Assert(err).Equal(nil)
|
||||
g.Assert(build.State).Equal("pending")
|
||||
g.Assert(build.Number).Equal(3)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -73,7 +73,13 @@ func TestUser(t *testing.T) {
|
|||
g.Assert(err).Equal(ErrKeyNotFound)
|
||||
})
|
||||
|
||||
g.It("Should list")
|
||||
g.It("Should list", func() {
|
||||
db.InsertUser(&common.User{Login: "bert"})
|
||||
db.InsertUser(&common.User{Login: "ernie"})
|
||||
users, err := db.GetUserList()
|
||||
g.Assert(err).Equal(nil)
|
||||
g.Assert(len(users)).Equal(2)
|
||||
})
|
||||
|
||||
g.It("Should count", func() {
|
||||
db.InsertUser(&common.User{Login: "bert"})
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package bolt
|
||||
|
||||
import (
|
||||
"github.com/youtube/vitess/go/bson"
|
||||
"github.com/boltdb/bolt"
|
||||
"github.com/youtube/vitess/go/bson"
|
||||
)
|
||||
|
||||
func encode(v interface{}) ([]byte, error) {
|
||||
|
@ -35,11 +35,7 @@ func update(t *bolt.Tx, bucket, key []byte, v interface{}) error {
|
|||
t.Rollback()
|
||||
return err
|
||||
}
|
||||
err = t.Bucket(bucket).Put(key, raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return t.Bucket(bucket).Put(key, raw)
|
||||
}
|
||||
|
||||
func insert(t *bolt.Tx, bucket, key []byte, v interface{}) error {
|
||||
|
@ -53,17 +49,9 @@ func insert(t *bolt.Tx, bucket, key []byte, v interface{}) error {
|
|||
if t.Bucket(bucket).Get(key) != nil {
|
||||
return ErrKeyExists
|
||||
}
|
||||
err = t.Bucket(bucket).Put(key, raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return t.Bucket(bucket).Put(key, raw)
|
||||
}
|
||||
|
||||
func delete(t *bolt.Tx, bucket, key []byte) error {
|
||||
err := t.Bucket(bucket).Delete(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return t.Bucket(bucket).Delete(key)
|
||||
}
|
||||
|
|
2
drone.go
2
drone.go
|
@ -114,7 +114,7 @@ func main() {
|
|||
logs.Use(server.CheckPull())
|
||||
logs.Use(server.CheckPush())
|
||||
|
||||
logs.GET("", server.GetLogs)
|
||||
logs.GET("", server.GetTaskLogs)
|
||||
}
|
||||
|
||||
status := api.Group("/status/:owner/:name/:number")
|
||||
|
|
|
@ -166,7 +166,7 @@ func getLoginBasic(c *gin.Context) {
|
|||
var (
|
||||
remote = ToRemote(c)
|
||||
username = c.Request.FormValue("username")
|
||||
password = c.Request.FormValue("username")
|
||||
password = c.Request.FormValue("password")
|
||||
)
|
||||
|
||||
// get user account
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// GetLogs accepts a request to retrieve logs from the
|
||||
// datastore for the given repository, build and task
|
||||
// number.
|
||||
//
|
||||
// GET /api/logs/:owner/:name/:number/:task
|
||||
//
|
||||
func GetLogs(c *gin.Context) {
|
||||
ds := ToDatastore(c)
|
||||
repo := ToRepo(c)
|
||||
build, _ := strconv.Atoi(c.Params.ByName("number"))
|
||||
task, _ := strconv.Atoi(c.Params.ByName("task"))
|
||||
|
||||
logs, err := ds.GetTaskLogs(repo.FullName, build, task)
|
||||
if err != nil {
|
||||
c.Fail(404, err)
|
||||
} else {
|
||||
c.Writer.Write(logs)
|
||||
}
|
||||
}
|
|
@ -193,7 +193,7 @@ func PostRepo(c *gin.Context) {
|
|||
|
||||
// set the repository owner to the
|
||||
// currently authenticated user.
|
||||
r.User = user
|
||||
r.User = &common.Owner{Login: user.Login}
|
||||
|
||||
// generate an RSA key and add to the repo
|
||||
key, err := sshutil.GeneratePrivateKey()
|
||||
|
|
|
@ -44,3 +44,23 @@ func GetTasks(c *gin.Context) {
|
|||
c.JSON(200, tasks)
|
||||
}
|
||||
}
|
||||
|
||||
// GetTaskLogs accepts a request to retrieve logs from the
|
||||
// datastore for the given repository, build and task
|
||||
// number.
|
||||
//
|
||||
// GET /api/logs/:owner/:name/:number/:task
|
||||
//
|
||||
func GetTaskLogs(c *gin.Context) {
|
||||
ds := ToDatastore(c)
|
||||
repo := ToRepo(c)
|
||||
build, _ := strconv.Atoi(c.Params.ByName("number"))
|
||||
task, _ := strconv.Atoi(c.Params.ByName("task"))
|
||||
|
||||
logs, err := ds.GetTaskLogs(repo.FullName, build, task)
|
||||
if err != nil {
|
||||
c.Fail(404, err)
|
||||
} else {
|
||||
c.Writer.Write(logs)
|
||||
}
|
||||
}
|
||||
|
|
40
server/token.go
Normal file
40
server/token.go
Normal file
|
@ -0,0 +1,40 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
// "github.com/drone/drone/common"
|
||||
)
|
||||
|
||||
// POST /api/user/tokens
|
||||
func PostToken(c *gin.Context) {
|
||||
// 1. generate a unique, random password
|
||||
// 2. take a hash of the password, and store in the database
|
||||
// 3. return the random password to the UI and instruct the user to copy it
|
||||
}
|
||||
|
||||
// DELETE /api/user/tokens/:sha
|
||||
func DelToken(c *gin.Context) {
|
||||
store := ToDatastore(c)
|
||||
user := ToUser(c)
|
||||
hash := c.Params.ByName("hash")
|
||||
token, err := store.GetToken(hash)
|
||||
if err != nil {
|
||||
c.Fail(404, err)
|
||||
}
|
||||
err = store.DeleteToken(token)
|
||||
if err != nil {
|
||||
c.Fail(400, err)
|
||||
}
|
||||
|
||||
// TODO(bradrydzewski) this should be encapsulated
|
||||
// in our database code, since this feels like a
|
||||
// database-specific implementation.
|
||||
delete(user.Tokens, token.Sha)
|
||||
err = store.UpdateUser(user)
|
||||
if err != nil {
|
||||
c.Fail(400, err)
|
||||
} else {
|
||||
c.Writer.WriteHeader(200)
|
||||
}
|
||||
}
|
|
@ -57,3 +57,20 @@ func GetUserRepos(c *gin.Context) {
|
|||
c.JSON(200, &repos)
|
||||
}
|
||||
}
|
||||
|
||||
// GetUserTokens accepts a request to get the currently
|
||||
// authenticated user's token list from the datastore,
|
||||
// encoded and returned in JSON format.
|
||||
//
|
||||
// GET /api/user/tokens
|
||||
//
|
||||
func GetUserTokens(c *gin.Context) {
|
||||
// ds := ToDatastore(c)
|
||||
// me := ToUser(c)
|
||||
// tokens, err := ds.GetUserTokens(me.Login)
|
||||
// if err != nil {
|
||||
// c.Fail(400, err)
|
||||
// } else {
|
||||
// c.JSON(200, &repos)
|
||||
// }
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue