From 950e4f4090efe8d6a42dd607cadfd91bc87b2789 Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Wed, 8 Apr 2015 22:18:25 -0700 Subject: [PATCH] storing user repos index inside users object, for now --- common/repo.go | 2 - common/user.go | 4 ++ datastore/bolt/repo.go | 40 +++++++++---------- datastore/bolt/user.go | 19 +++++---- datastore/datastore.go | 18 ++++----- drone.go | 1 - server/repos.go | 84 ++++++++++++++++++++++++--------------- server/session/session.go | 2 +- server/subscribe.go | 53 ++++-------------------- settings/settings.go | 2 +- 10 files changed, 106 insertions(+), 119 deletions(-) diff --git a/common/repo.go b/common/repo.go index 235599dd7..a54faa5e9 100644 --- a/common/repo.go +++ b/common/repo.go @@ -37,8 +37,6 @@ type Keypair struct { // is displayed on the user dashboard and in the user // event feed. type Subscriber struct { - Login string `json:"login,omitempty"` - // Determines if notifications should be // received from this repository. Subscribed bool `json:"subscribed"` diff --git a/common/user.go b/common/user.go index 22801e544..107c8562d 100644 --- a/common/user.go +++ b/common/user.go @@ -10,4 +10,8 @@ type User struct { Admin bool `json:"admin,omitempty"` Created int64 `json:"created_at,omitempty"` Updated int64 `json:"updated_at,omitempty"` + + // Repos contains a list of subscriptions + // to repositories the user is watching. + Repos map[string]struct{} `json:"-"` } diff --git a/datastore/bolt/repo.go b/datastore/bolt/repo.go index c35b2f478..37bd21263 100644 --- a/datastore/bolt/repo.go +++ b/datastore/bolt/repo.go @@ -84,25 +84,25 @@ func (db *DB) DeleteRepo(repo *common.Repo) error { return t.Commit() } -// GetSubscriber gets the subscriber by login for the -// named repository. -func (db *DB) GetSubscriber(repo string, login string) (*common.Subscriber, error) { - sub := &common.Subscriber{} - key := []byte(login + "/" + repo) - err := get(db, bucketUserRepos, key, sub) - return sub, err -} +// // GetSubscriber gets the subscriber by login for the +// // named repository. +// func (db *DB) GetSubscriber(repo string, login string) (*common.Subscriber, error) { +// sub := &common.Subscriber{} +// key := []byte(login + "/" + repo) +// err := get(db, bucketUserRepos, key, sub) +// return sub, err +// } -// InsertSubscriber inserts a subscriber for the named -// repository. -func (db *DB) InsertSubscriber(repo string, sub *common.Subscriber) error { - key := []byte(sub.Login + "/" + repo) - return insert(db, bucketUserRepos, key, sub) -} +// // InsertSubscriber inserts a subscriber for the named +// // repository. +// func (db *DB) InsertSubscriber(repo string, sub *common.Subscriber) error { +// key := []byte(sub.Login + "/" + repo) +// return insert(db, bucketUserRepos, key, sub) +// } -// DeleteSubscriber removes the subscriber by login for the -// named repository. -func (db *DB) DeleteSubscriber(repo string, sub *common.Subscriber) error { - key := []byte(sub.Login + "/" + repo) - return delete(db, bucketUserRepos, key) -} +// // DeleteSubscriber removes the subscriber by login for the +// // named repository. +// func (db *DB) DeleteSubscriber(repo string, sub *common.Subscriber) error { +// key := []byte(sub.Login + "/" + repo) +// return delete(db, bucketUserRepos, key) +// } diff --git a/datastore/bolt/user.go b/datastore/bolt/user.go index edbe9f095..6d7d62738 100644 --- a/datastore/bolt/user.go +++ b/datastore/bolt/user.go @@ -57,22 +57,27 @@ func (db *DB) GetUserRepos(login string) ([]*common.Repo, error) { } defer t.Rollback() repos := []*common.Repo{} + user := &common.User{} - // get the index of user repos and unmarshal - // to a string array. + // get the user struct from the database key := []byte(login) - raw := t.Bucket(bucketUserRepos).Get(key) - keys := [][]byte{} - err = decode(raw, &keys) + raw := t.Bucket(bucketUser).Get(key) + err = decode(raw, user) if err != nil { - return repos, err + return nil, err } // for each item in the index, get the repository // and append to the array - for _, key := range keys { + for repoName, _ := range user.Repos { repo := &common.Repo{} + key = []byte(repoName) raw = t.Bucket(bucketRepo).Get(key) + if raw == nil { + // this will happen when the repository has been deleted + // TODO we should probably upate the index in this case. + continue + } err = decode(raw, repo) if err != nil { break diff --git a/datastore/datastore.go b/datastore/datastore.go index abe574c9d..753913487 100644 --- a/datastore/datastore.go +++ b/datastore/datastore.go @@ -42,17 +42,17 @@ type Datastore interface { // DeleteUser deletes the token. DeleteToken(*common.Token) error - // GetSubscriber gets the subscriber by login for the - // named repository. - GetSubscriber(string, string) (*common.Subscriber, error) + // // GetSubscriber gets the subscriber by login for the + // // named repository. + // GetSubscriber(string, string) (*common.Subscriber, error) - // InsertSubscriber inserts a subscriber for the named - // repository. - InsertSubscriber(string, *common.Subscriber) error + // // InsertSubscriber inserts a subscriber for the named + // // repository. + // InsertSubscriber(string, *common.Subscriber) error - // DeleteSubscriber removes the subscriber by login for the - // named repository. - DeleteSubscriber(string, *common.Subscriber) error + // // DeleteSubscriber removes the subscriber by login for the + // // named repository. + // DeleteSubscriber(string, *common.Subscriber) error // GetRepo gets the repository by name. GetRepo(string) (*common.Repo, error) diff --git a/drone.go b/drone.go index ee847e7e6..063d22328 100644 --- a/drone.go +++ b/drone.go @@ -79,7 +79,6 @@ func main() { subscribers.Use(server.SetPerm()) subscribers.Use(server.CheckPull()) - subscribers.GET("", server.GetSubscribers) subscribers.POST("", server.Subscribe) subscribers.DELETE("", server.Unsubscribe) } diff --git a/server/repos.go b/server/repos.go index e0f1f60f5..61032fbd1 100644 --- a/server/repos.go +++ b/server/repos.go @@ -60,9 +60,15 @@ func GetRepo(c *gin.Context) { } // if the user is authenticated, we should display // if she is watching the current repository. - if user != nil { - data.Watch, _ = store.GetSubscriber(repo.FullName, user.Login) + if user == nil { + c.JSON(200, data) + return } + + // check to see if the user is subscribing to the repo + _, ok := user.Repos[repo.FullName] + data.Watch = &common.Subscriber{Subscribed: ok} + c.JSON(200, data) } @@ -75,8 +81,8 @@ func GetRepo(c *gin.Context) { func PutRepo(c *gin.Context) { store := ToDatastore(c) perm := ToPerm(c) - u := ToUser(c) - r := ToRepo(c) + user := ToUser(c) + repo := ToRepo(c) in := &repoReq{} if !c.BindWith(in, binding.JSON) { @@ -84,37 +90,41 @@ func PutRepo(c *gin.Context) { } if in.Params != nil { - err := store.UpsertRepoParams(r.FullName, *in.Params) + err := store.UpsertRepoParams(repo.FullName, *in.Params) if err != nil { c.Fail(400, err) return } } if in.Disabled != nil { - r.Disabled = *in.Disabled + repo.Disabled = *in.Disabled } if in.DisablePR != nil { - r.DisablePR = *in.DisablePR + repo.DisablePR = *in.DisablePR } if in.DisableTag != nil { - r.DisableTag = *in.DisableTag + repo.DisableTag = *in.DisableTag } - if in.Trusted != nil && u.Admin { - r.Trusted = *in.Trusted + if in.Trusted != nil && user.Admin { + repo.Trusted = *in.Trusted } - if in.Timeout != nil && u.Admin { - r.Timeout = *in.Timeout + if in.Timeout != nil && user.Admin { + repo.Timeout = *in.Timeout } - err := store.UpdateRepo(r) + err := store.UpdateRepo(repo) if err != nil { c.Fail(400, err) return } - data := repoResp{r, perm, nil, nil} - data.Params, _ = store.GetRepoParams(r.FullName) - data.Watch, _ = store.GetSubscriber(r.FullName, u.Login) + data := repoResp{repo, perm, nil, nil} + data.Params, _ = store.GetRepoParams(repo.FullName) + + // check to see if the user is subscribing to the repo + _, ok := user.Repos[repo.FullName] + data.Watch = &common.Subscriber{Subscribed: ok} + c.JSON(200, data) } @@ -194,30 +204,38 @@ func PostRepo(c *gin.Context) { keypair := &common.Keypair{} keypair.Public = sshutil.MarshalPublicKey(&key.PublicKey) keypair.Private = sshutil.MarshalPrivateKey(key) + + // activate the repository before we make any + // local changes to the database. + err = remote.Activate(user, r, keypair, link) + if err != nil { + c.Fail(500, err) + return + } + + // persist the repository + err = store.InsertRepo(user, r) + if err != nil { + c.Fail(500, err) + return + } + + // persisty the repository key pair err = store.UpsertRepoKeys(r.FullName, keypair) if err != nil { c.Fail(500, err) return } - // store the repository and the users' permissions - // in the datastore. - err = store.InsertRepo(user, r) - if err != nil { - c.Fail(500, err) - return - } - err = store.InsertSubscriber(r.FullName, &common.Subscriber{Subscribed: true}) - if err != nil { - c.Fail(500, err) - return - } - - err = remote.Activate(user, r, keypair, link) - if err != nil { - c.Fail(500, err) - return + // subscribe the user to the repository + // if this fails we'll ignore, since the user + // can just go click the "watch" button in the + // user interface. + if user.Repos == nil { + user.Repos = map[string]struct{}{} } + user.Repos[r.FullName] = struct{}{} + store.UpdateUser(user) c.JSON(200, r) } diff --git a/server/session/session.go b/server/session/session.go index 2e8afa3f0..c4e61ca32 100644 --- a/server/session/session.go +++ b/server/session/session.go @@ -24,7 +24,7 @@ type session struct { func New(s *settings.Session) Session { // TODO (bradrydzewski) hook up the Session.Expires - secret := s.Secret + secret := []byte(s.Secret) expire := time.Hour * 72 if len(secret) == 0 { securecookie.GenerateRandomKey(32) diff --git a/server/subscribe.go b/server/subscribe.go index a783a3eb3..e811f3f91 100644 --- a/server/subscribe.go +++ b/server/subscribe.go @@ -6,41 +6,6 @@ import ( "github.com/drone/drone/common" ) -// GetSubscriber accepts a request to retrieve a repository -// subscriber from the datastore for the given repository by -// user Login. -// -// GET /api/subscribers/:owner/:name/:login -// -func GetSubscriber(c *gin.Context) { - store := ToDatastore(c) - repo := ToRepo(c) - login := c.Params.ByName("login") - subsc, err := store.GetSubscriber(repo.FullName, login) - if err != nil { - c.Fail(404, err) - } else { - c.JSON(200, subsc) - } -} - -// GetSubscribers accepts a request to retrieve a repository -// watchers from the datastore for the given repository. -// -// GET /api/subscribers/:owner/:name -// -func GetSubscribers(c *gin.Context) { - // store := ToDatastore(c) - // repo := ToRepo(c) - // subs, err := store.GetSubscribers(repo.FullName) - // if err != nil { - // c.Fail(404, err) - // } else { - // c.JSON(200, subs) - // } - c.Writer.WriteHeader(501) -} - // Unubscribe accapets a request to unsubscribe the // currently authenticated user to the repository. // @@ -50,11 +15,9 @@ func Unsubscribe(c *gin.Context) { store := ToDatastore(c) repo := ToRepo(c) user := ToUser(c) - sub, err := store.GetSubscriber(repo.FullName, user.Login) - if err != nil { - c.Fail(404, err) - } - err = store.DeleteSubscriber(repo.FullName, sub) + + delete(user.Repos, repo.FullName) + err := store.UpdateUser(user) if err != nil { c.Fail(400, err) } else { @@ -71,14 +34,14 @@ func Subscribe(c *gin.Context) { store := ToDatastore(c) repo := ToRepo(c) user := ToUser(c) - subscriber := &common.Subscriber{ - Login: user.Login, - Subscribed: true, + if user.Repos == nil { + user.Repos = map[string]struct{}{} } - err := store.InsertSubscriber(repo.FullName, subscriber) + user.Repos[repo.FullName] = struct{}{} + err := store.UpdateUser(user) if err != nil { c.Fail(400, err) } else { - c.JSON(200, subscriber) + c.JSON(200, &common.Subscriber{Subscribed: true}) } } diff --git a/settings/settings.go b/settings/settings.go index 866bca97f..3361f1791 100644 --- a/settings/settings.go +++ b/settings/settings.go @@ -73,7 +73,7 @@ type Server struct { // used to generate, validate and expire authentication // sessions. type Session struct { - Secret []byte `toml:"secret"` + Secret string `toml:"secret"` Expires int64 `toml:"expires"` }