Refactored to use Model and Database folders

This commit is contained in:
Brad Rydzewski 2014-06-12 16:41:04 -07:00
parent 554276de05
commit 36b01512c0
32 changed files with 407 additions and 477 deletions

View File

@ -1,9 +1,7 @@
package notify package notify
import ( import (
"github.com/drone/drone/server/resource/commit" "github.com/drone/drone/shared/model"
"github.com/drone/drone/server/resource/repo"
"github.com/drone/drone/server/resource/user"
) )
// Context represents the context of an // Context represents the context of an
@ -13,13 +11,13 @@ type Context struct {
Host string Host string
// User that owns the repository // User that owns the repository
User *user.User User *model.User
// Repository being built. // Repository being built.
Repo *repo.Repo Repo *model.Repo
// Commit being built // Commit being built
Commit *commit.Commit Commit *model.Commit
} }
type Sender interface { type Sender interface {

View File

@ -1,20 +1,19 @@
package notify package notify
import ( import (
"github.com/drone/drone/server/resource/commit" "github.com/drone/drone/shared/model"
"github.com/drone/drone/server/resource/repo"
"testing" "testing"
) )
func Test_getBuildUrl(t *testing.T) { func Test_getBuildUrl(t *testing.T) {
c := &Context{ c := &Context{
Host: "http://examplehost.com", Host: "http://examplehost.com",
Repo: &repo.Repo{ Repo: &model.Repo{
Host: "examplegit.com", Host: "examplegit.com",
Owner: "owner", Owner: "owner",
Name: "repo", Name: "repo",
}, },
Commit: &commit.Commit{ Commit: &model.Commit{
Sha: "abc", Sha: "abc",
Branch: "example", Branch: "example",
}, },

View File

@ -5,9 +5,7 @@ import (
"encoding/json" "encoding/json"
"net/http" "net/http"
"github.com/drone/drone/server/resource/commit" "github.com/drone/drone/shared/model"
"github.com/drone/drone/server/resource/repo"
"github.com/drone/drone/server/resource/user"
) )
type Webhook struct { type Webhook struct {
@ -31,9 +29,9 @@ func (w *Webhook) Send(context *Context) error {
func (w *Webhook) send(context *Context) error { func (w *Webhook) send(context *Context) error {
// data will get posted in this format // data will get posted in this format
data := struct { data := struct {
Owner *user.User `json:"owner"` Owner *model.User `json:"owner"`
Repo *repo.Repo `json:"repository"` Repo *model.Repo `json:"repository"`
Commit *commit.Commit `json:"commit"` Commit *model.Commit `json:"commit"`
}{context.User, context.Repo, context.Commit} }{context.User, context.Repo, context.Commit}
// data json encoded // data json encoded

View File

@ -1,48 +1,49 @@
package commit package database
import ( import (
"database/sql" "database/sql"
"time" "time"
"github.com/drone/drone/shared/model"
"github.com/russross/meddler" "github.com/russross/meddler"
) )
type CommitManager interface { type CommitManager interface {
// Find finds the commit by ID. // Find finds the commit by ID.
Find(id int64) (*Commit, error) Find(id int64) (*model.Commit, error)
// FindSha finds the commit for the branch and sha. // FindSha finds the commit for the branch and sha.
FindSha(repo int64, branch, sha string) (*Commit, error) FindSha(repo int64, branch, sha string) (*model.Commit, error)
// FindLatest finds the most recent commit for the branch. // FindLatest finds the most recent commit for the branch.
FindLatest(repo int64, branch string) (*Commit, error) FindLatest(repo int64, branch string) (*model.Commit, error)
// FindOutput finds the commit's output. // FindOutput finds the commit's output.
FindOutput(commit int64) ([]byte, error) FindOutput(commit int64) ([]byte, error)
// List finds recent commits for the repository // List finds recent commits for the repository
List(repo int64) ([]*Commit, error) List(repo int64) ([]*model.Commit, error)
// ListBranch finds recent commits for the repository and branch. // ListBranch finds recent commits for the repository and branch.
ListBranch(repo int64, branch string) ([]*Commit, error) ListBranch(repo int64, branch string) ([]*model.Commit, error)
// ListBranches finds most recent commit for each branch. // ListBranches finds most recent commit for each branch.
ListBranches(repo int64) ([]*Commit, error) ListBranches(repo int64) ([]*model.Commit, error)
// ListUser finds most recent commits for a user. // ListUser finds most recent commits for a user.
ListUser(repo int64) ([]*CommitRepo, error) ListUser(repo int64) ([]*model.CommitRepo, error)
// Insert persists the commit to the datastore. // Insert persists the commit to the datastore.
Insert(commit *Commit) error Insert(commit *model.Commit) error
// Update persists changes to the commit to the datastore. // Update persists changes to the commit to the datastore.
Update(commit *Commit) error Update(commit *model.Commit) error
// UpdateOutput persists a commit's stdout to the datastore. // UpdateOutput persists a commit's stdout to the datastore.
UpdateOutput(commit *Commit, out []byte) error UpdateOutput(commit *model.Commit, out []byte) error
// Delete removes the commit from the datastore. // Delete removes the commit from the datastore.
Delete(commit *Commit) error Delete(commit *model.Commit) error
// CancelAll will update the status of all Started or Pending // CancelAll will update the status of all Started or Pending
// builds to a status of Killed (cancelled). // builds to a status of Killed (cancelled).
@ -54,9 +55,9 @@ type commitManager struct {
*sql.DB *sql.DB
} }
// NewManager initiales a new CommitManager intended to // NewCommitManager initiales a new CommitManager intended to
// manage and persist commits. // manage and persist commits.
func NewManager(db *sql.DB) CommitManager { func NewCommitManager(db *sql.DB) CommitManager {
return &commitManager{db} return &commitManager{db}
} }
@ -84,7 +85,7 @@ LIMIT 20
` `
// SQL query to retrieve the latest Commits for a user's repositories. // SQL query to retrieve the latest Commits for a user's repositories.
const listUserQuery = ` const listUserCommitsQuery = `
SELECT r.repo_remote, r.repo_host, r.repo_owner, r.repo_name, c.* SELECT r.repo_remote, r.repo_host, r.repo_owner, r.repo_name, c.*
FROM commits c, repos r, perms p FROM commits c, repos r, perms p
WHERE c.repo_id=r.repo_id WHERE c.repo_id=r.repo_id
@ -96,7 +97,7 @@ LIMIT 20
` `
// SQL query to retrieve the latest Commits across all branches. // SQL query to retrieve the latest Commits across all branches.
const listQuery = ` const listCommitsQuery = `
SELECT * SELECT *
FROM commits FROM commits
WHERE repo_id=? WHERE repo_id=?
@ -105,7 +106,7 @@ LIMIT 20
` `
// SQL query to retrieve a Commit by branch and sha. // SQL query to retrieve a Commit by branch and sha.
const findQuery = ` const findCommitQuery = `
SELECT * SELECT *
FROM commits FROM commits
WHERE repo_id=? WHERE repo_id=?
@ -115,7 +116,7 @@ LIMIT 1
` `
// SQL query to retrieve the most recent Commit for a branch. // SQL query to retrieve the most recent Commit for a branch.
const findLatestQuery = ` const findLatestCommitQuery = `
SELECT * SELECT *
FROM commits FROM commits
WHERE commit_id IN ( WHERE commit_id IN (
@ -143,12 +144,12 @@ UPDATE output SET output_raw = ? WHERE commit_id = ?;
` `
// SQL statement to delete a Commit by ID. // SQL statement to delete a Commit by ID.
const deleteStmt = ` const deleteCommitStmt = `
DELETE FROM commits WHERE commit_id = ?; DELETE FROM commits WHERE commit_id = ?;
` `
// SQL statement to cancel all running Commits. // SQL statement to cancel all running Commits.
const cancelStmt = ` const cancelCommitStmt = `
UPDATE commits SET UPDATE commits SET
commit_status = ?, commit_status = ?,
commit_started = ?, commit_started = ?,
@ -156,21 +157,21 @@ commit_finished = ?
WHERE commit_status IN ('Started', 'Pending'); WHERE commit_status IN ('Started', 'Pending');
` `
func (db *commitManager) Find(id int64) (*Commit, error) { func (db *commitManager) Find(id int64) (*model.Commit, error) {
dst := Commit{} dst := model.Commit{}
err := meddler.Load(db, "commits", &dst, id) err := meddler.Load(db, "commits", &dst, id)
return &dst, err return &dst, err
} }
func (db *commitManager) FindSha(repo int64, branch, sha string) (*Commit, error) { func (db *commitManager) FindSha(repo int64, branch, sha string) (*model.Commit, error) {
dst := Commit{} dst := model.Commit{}
err := meddler.QueryRow(db, &dst, findQuery, repo, branch, sha) err := meddler.QueryRow(db, &dst, findCommitQuery, repo, branch, sha)
return &dst, err return &dst, err
} }
func (db *commitManager) FindLatest(repo int64, branch string) (*Commit, error) { func (db *commitManager) FindLatest(repo int64, branch string) (*model.Commit, error) {
dst := Commit{} dst := model.Commit{}
err := meddler.QueryRow(db, &dst, findLatestQuery, repo, branch) err := meddler.QueryRow(db, &dst, findLatestCommitQuery, repo, branch)
return &dst, err return &dst, err
} }
@ -180,42 +181,42 @@ func (db *commitManager) FindOutput(commit int64) ([]byte, error) {
return []byte(dst), err return []byte(dst), err
} }
func (db *commitManager) List(repo int64) ([]*Commit, error) { func (db *commitManager) List(repo int64) ([]*model.Commit, error) {
var dst []*Commit var dst []*model.Commit
err := meddler.QueryAll(db, &dst, listQuery, repo) err := meddler.QueryAll(db, &dst, listCommitsQuery, repo)
return dst, err return dst, err
} }
func (db *commitManager) ListBranch(repo int64, branch string) ([]*Commit, error) { func (db *commitManager) ListBranch(repo int64, branch string) ([]*model.Commit, error) {
var dst []*Commit var dst []*model.Commit
err := meddler.QueryAll(db, &dst, listBranchQuery, repo, branch) err := meddler.QueryAll(db, &dst, listBranchQuery, repo, branch)
return dst, err return dst, err
} }
func (db *commitManager) ListBranches(repo int64) ([]*Commit, error) { func (db *commitManager) ListBranches(repo int64) ([]*model.Commit, error) {
var dst []*Commit var dst []*model.Commit
err := meddler.QueryAll(db, &dst, listBranchesQuery, repo) err := meddler.QueryAll(db, &dst, listBranchesQuery, repo)
return dst, err return dst, err
} }
func (db *commitManager) ListUser(user int64) ([]*CommitRepo, error) { func (db *commitManager) ListUser(user int64) ([]*model.CommitRepo, error) {
var dst []*CommitRepo var dst []*model.CommitRepo
err := meddler.QueryAll(db, &dst, listUserQuery, user) err := meddler.QueryAll(db, &dst, listUserCommitsQuery, user)
return dst, err return dst, err
} }
func (db *commitManager) Insert(commit *Commit) error { func (db *commitManager) Insert(commit *model.Commit) error {
commit.Created = time.Now().Unix() commit.Created = time.Now().Unix()
commit.Updated = time.Now().Unix() commit.Updated = time.Now().Unix()
return meddler.Insert(db, "commits", commit) return meddler.Insert(db, "commits", commit)
} }
func (db *commitManager) Update(commit *Commit) error { func (db *commitManager) Update(commit *model.Commit) error {
commit.Updated = time.Now().Unix() commit.Updated = time.Now().Unix()
return meddler.Update(db, "commits", commit) return meddler.Update(db, "commits", commit)
} }
func (db *commitManager) UpdateOutput(commit *Commit, out []byte) error { func (db *commitManager) UpdateOutput(commit *model.Commit, out []byte) error {
_, err := db.Exec(insertOutputStmt, commit.ID, out) _, err := db.Exec(insertOutputStmt, commit.ID, out)
if err != nil { if err != nil {
return nil return nil
@ -224,12 +225,12 @@ func (db *commitManager) UpdateOutput(commit *Commit, out []byte) error {
return err return err
} }
func (db *commitManager) Delete(commit *Commit) error { func (db *commitManager) Delete(commit *model.Commit) error {
_, err := db.Exec(deleteStmt, commit.ID) _, err := db.Exec(deleteCommitStmt, commit.ID)
return err return err
} }
func (db *commitManager) CancelAll() error { func (db *commitManager) CancelAll() error {
_, err := db.Exec(cancelStmt, StatusKilled, time.Now().Unix(), time.Now().Unix()) _, err := db.Exec(cancelCommitStmt, model.StatusKilled, time.Now().Unix(), time.Now().Unix())
return err return err
} }

View File

@ -1,35 +1,18 @@
package commit package database
import ( import (
"database/sql" "database/sql"
"testing" "testing"
"time" "time"
"github.com/drone/drone/server/database/schema" "github.com/drone/drone/shared/model"
"github.com/drone/drone/server/database/testdata"
"github.com/drone/drone/server/database/testdatabase"
) )
// in-memory database instance for unit testing func TestCommitFind(t *testing.T) {
var db *sql.DB
// setup the test database and test fixtures
func setup() {
db, _ = testdatabase.Open()
schema.Load(db)
testdata.Load(db)
}
// teardown the test database
func teardown() {
db.Close()
}
func TestFind(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
commits := NewManager(db) commits := NewCommitManager(db)
commit, err := commits.Find(3) commit, err := commits.Find(3)
if err != nil { if err != nil {
t.Errorf("Want Commit from ID, got %s", err) t.Errorf("Want Commit from ID, got %s", err)
@ -38,11 +21,11 @@ func TestFind(t *testing.T) {
testCommit(t, commit) testCommit(t, commit)
} }
func TestFindSha(t *testing.T) { func TestCommitFindSha(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
commits := NewManager(db) commits := NewCommitManager(db)
commit, err := commits.FindSha(2, "master", "7253f6545caed41fb8f5a6fcdb3abc0b81fa9dbf") commit, err := commits.FindSha(2, "master", "7253f6545caed41fb8f5a6fcdb3abc0b81fa9dbf")
if err != nil { if err != nil {
t.Errorf("Want Commit from SHA, got %s", err) t.Errorf("Want Commit from SHA, got %s", err)
@ -51,11 +34,11 @@ func TestFindSha(t *testing.T) {
testCommit(t, commit) testCommit(t, commit)
} }
func TestFindLatest(t *testing.T) { func TestCommitFindLatest(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
commits := NewManager(db) commits := NewCommitManager(db)
commit, err := commits.FindLatest(2, "master") commit, err := commits.FindLatest(2, "master")
if err != nil { if err != nil {
t.Errorf("Want Latest Commit, got %s", err) t.Errorf("Want Latest Commit, got %s", err)
@ -64,11 +47,11 @@ func TestFindLatest(t *testing.T) {
testCommit(t, commit) testCommit(t, commit)
} }
func TestFindOutput(t *testing.T) { func TestCommitFindOutput(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
commits := NewManager(db) commits := NewCommitManager(db)
out, err := commits.FindOutput(1) out, err := commits.FindOutput(1)
if err != nil { if err != nil {
t.Errorf("Want Commit stdout, got %s", err) t.Errorf("Want Commit stdout, got %s", err)
@ -80,11 +63,11 @@ func TestFindOutput(t *testing.T) {
} }
} }
func TestList(t *testing.T) { func TestCommitList(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
commits := NewManager(db) commits := NewCommitManager(db)
list, err := commits.List(2) list, err := commits.List(2)
if err != nil { if err != nil {
t.Errorf("Want List from RepoID, got %s", err) t.Errorf("Want List from RepoID, got %s", err)
@ -98,11 +81,11 @@ func TestList(t *testing.T) {
testCommit(t, list[0]) testCommit(t, list[0])
} }
func TestListBranch(t *testing.T) { func TestCommitListBranch(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
commits := NewManager(db) commits := NewCommitManager(db)
list, err := commits.ListBranch(2, "master") list, err := commits.ListBranch(2, "master")
if err != nil { if err != nil {
t.Errorf("Want List from RepoID, got %s", err) t.Errorf("Want List from RepoID, got %s", err)
@ -116,11 +99,11 @@ func TestListBranch(t *testing.T) {
testCommit(t, list[0]) testCommit(t, list[0])
} }
func TestListBranches(t *testing.T) { func TestCommitListBranches(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
commits := NewManager(db) commits := NewCommitManager(db)
list, err := commits.ListBranches(2) list, err := commits.ListBranches(2)
if err != nil { if err != nil {
t.Errorf("Want Branch List from RepoID, got %s", err) t.Errorf("Want Branch List from RepoID, got %s", err)
@ -134,35 +117,35 @@ func TestListBranches(t *testing.T) {
testCommit(t, list[1]) testCommit(t, list[1])
} }
func TestInsert(t *testing.T) { func TestCommitInsert(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
commit := Commit{RepoID: 3, Branch: "foo", Sha: "85f8c029b902ed9400bc600bac301a0aadb144ac"} commit := model.Commit{RepoID: 3, Branch: "foo", Sha: "85f8c029b902ed9400bc600bac301a0aadb144ac"}
commits := NewManager(db) commits := NewCommitManager(db)
if err := commits.Insert(&commit); err != nil { if err := commits.Insert(&commit); err != nil {
t.Errorf("Want Commit created, got %s", err) t.Errorf("Want Commit created, got %s", err)
} }
// verify that it is ok to add same sha for different branch // verify that it is ok to add same sha for different branch
var err = commits.Insert(&Commit{RepoID: 3, Branch: "bar", Sha: "85f8c029b902ed9400bc600bac301a0aadb144ac"}) var err = commits.Insert(&model.Commit{RepoID: 3, Branch: "bar", Sha: "85f8c029b902ed9400bc600bac301a0aadb144ac"})
if err != nil { if err != nil {
t.Errorf("Want Commit created, got %s", err) t.Errorf("Want Commit created, got %s", err)
} }
// verify unique remote + remote id constraint // verify unique remote + remote id constraint
err = commits.Insert(&Commit{RepoID: 3, Branch: "bar", Sha: "85f8c029b902ed9400bc600bac301a0aadb144ac"}) err = commits.Insert(&model.Commit{RepoID: 3, Branch: "bar", Sha: "85f8c029b902ed9400bc600bac301a0aadb144ac"})
if err == nil { if err == nil {
t.Error("Want unique constraint violated") t.Error("Want unique constraint violated")
} }
} }
func TestUpdate(t *testing.T) { func TestCommitUpdate(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
commits := NewManager(db) commits := NewCommitManager(db)
commit, err := commits.Find(5) commit, err := commits.Find(5)
if err != nil { if err != nil {
t.Errorf("Want Commit from ID, got %s", err) t.Errorf("Want Commit from ID, got %s", err)
@ -198,11 +181,11 @@ func TestUpdate(t *testing.T) {
} }
} }
func TestDelete(t *testing.T) { func TestCommitDelete(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
commits := NewManager(db) commits := NewCommitManager(db)
commit, err := commits.Find(1) commit, err := commits.Find(1)
if err != nil { if err != nil {
t.Errorf("Want Commit from ID, got %s", err) t.Errorf("Want Commit from ID, got %s", err)
@ -221,7 +204,7 @@ func TestDelete(t *testing.T) {
// testCommit is a helper function that compares the commit // testCommit is a helper function that compares the commit
// to an expected set of fixed field values. // to an expected set of fixed field values.
func testCommit(t *testing.T, commit *Commit) { func testCommit(t *testing.T, commit *model.Commit) {
var got, want = commit.Status, "Success" var got, want = commit.Status, "Success"
if got != want { if got != want {
t.Errorf("Want Status %v, got %v", want, got) t.Errorf("Want Status %v, got %v", want, got)

View File

@ -1,33 +1,32 @@
package perm package database
import ( import (
"database/sql" "database/sql"
"time" "time"
"github.com/drone/drone/server/resource/repo" "github.com/drone/drone/shared/model"
"github.com/drone/drone/server/resource/user"
"github.com/russross/meddler" "github.com/russross/meddler"
) )
type PermManager interface { type PermManager interface {
// Grant will grant the user read, write and admin persmissions // Grant will grant the user read, write and admin persmissions
// to the specified repository. // to the specified repository.
Grant(u *user.User, r *repo.Repo, read, write, admin bool) error Grant(u *model.User, r *model.Repo, read, write, admin bool) error
// Revoke will revoke all user permissions to the specified repository. // Revoke will revoke all user permissions to the specified repository.
Revoke(u *user.User, r *repo.Repo) error Revoke(u *model.User, r *model.Repo) error
// Read returns true if the specified user has read // Read returns true if the specified user has read
// access to the repository. // access to the repository.
Read(u *user.User, r *repo.Repo) (bool, error) Read(u *model.User, r *model.Repo) (bool, error)
// Write returns true if the specified user has write // Write returns true if the specified user has write
// access to the repository. // access to the repository.
Write(u *user.User, r *repo.Repo) (bool, error) Write(u *model.User, r *model.Repo) (bool, error)
// Admin returns true if the specified user is an // Admin returns true if the specified user is an
// administrator of the repository. // administrator of the repository.
Admin(u *user.User, r *repo.Repo) (bool, error) Admin(u *model.User, r *model.Repo) (bool, error)
} }
// permManager manages user permissions to access repositories. // permManager manages user permissions to access repositories.
@ -37,7 +36,7 @@ type permManager struct {
// SQL query to retrieve a user's permission to // SQL query to retrieve a user's permission to
// access a repository. // access a repository.
const findQuery = ` const findPermQuery = `
SELECT * SELECT *
FROM perms FROM perms
WHERE user_id=? WHERE user_id=?
@ -46,19 +45,30 @@ LIMIT 1
` `
// SQL statement to delete a permission. // SQL statement to delete a permission.
const deleteStmt = ` const deletePermStmt = `
DELETE FROM perms WHERE user_id=? AND repo_id=? DELETE FROM perms WHERE user_id=? AND repo_id=?
` `
type perm struct {
ID int64 `meddler:"perm_id,pk"`
UserID int64 `meddler:"user_id"`
RepoID int64 `meddler:"repo_id"`
Read bool `meddler:"perm_read"`
Write bool `meddler:"perm_write"`
Admin bool `meddler:"perm_admin"`
Created int64 `meddler:"perm_created"`
Updated int64 `meddler:"perm_updated"`
}
// NewManager initiales a new PermManager intended to // NewManager initiales a new PermManager intended to
// manage user permission and access control. // manage user permission and access control.
func NewManager(db *sql.DB) PermManager { func NewPermManager(db *sql.DB) PermManager {
return &permManager{db} return &permManager{db}
} }
// Grant will grant the user read, write and admin persmissions // Grant will grant the user read, write and admin persmissions
// to the specified repository. // to the specified repository.
func (db *permManager) Grant(u *user.User, r *repo.Repo, read, write, admin bool) error { func (db *permManager) Grant(u *model.User, r *model.Repo, read, write, admin bool) error {
// attempt to get existing permissions from the database // attempt to get existing permissions from the database
perm, err := db.find(u, r) perm, err := db.find(u, r)
if err != nil && err != sql.ErrNoRows { if err != nil && err != sql.ErrNoRows {
@ -84,12 +94,12 @@ func (db *permManager) Grant(u *user.User, r *repo.Repo, read, write, admin bool
} }
// Revoke will revoke all user permissions to the specified repository. // Revoke will revoke all user permissions to the specified repository.
func (db *permManager) Revoke(u *user.User, r *repo.Repo) error { func (db *permManager) Revoke(u *model.User, r *model.Repo) error {
_, err := db.Exec(deleteStmt, u.ID, r.ID) _, err := db.Exec(deletePermStmt, u.ID, r.ID)
return err return err
} }
func (db *permManager) Read(u *user.User, r *repo.Repo) (bool, error) { func (db *permManager) Read(u *model.User, r *model.Repo) (bool, error) {
switch { switch {
// if the repo is public, grant access. // if the repo is public, grant access.
case r.Private == false: case r.Private == false:
@ -107,7 +117,7 @@ func (db *permManager) Read(u *user.User, r *repo.Repo) (bool, error) {
return perm.Read, err return perm.Read, err
} }
func (db *permManager) Write(u *user.User, r *repo.Repo) (bool, error) { func (db *permManager) Write(u *model.User, r *model.Repo) (bool, error) {
switch { switch {
// if the user is nil, deny access // if the user is nil, deny access
case u == nil: case u == nil:
@ -122,7 +132,7 @@ func (db *permManager) Write(u *user.User, r *repo.Repo) (bool, error) {
return perm.Write, err return perm.Write, err
} }
func (db *permManager) Admin(u *user.User, r *repo.Repo) (bool, error) { func (db *permManager) Admin(u *model.User, r *model.Repo) (bool, error) {
switch { switch {
// if the user is nil, deny access // if the user is nil, deny access
case u == nil: case u == nil:
@ -137,8 +147,8 @@ func (db *permManager) Admin(u *user.User, r *repo.Repo) (bool, error) {
return perm.Admin, err return perm.Admin, err
} }
func (db *permManager) find(u *user.User, r *repo.Repo) (*perm, error) { func (db *permManager) find(u *model.User, r *model.Repo) (*perm, error) {
var dst = perm{} var dst = perm{}
var err = meddler.QueryRow(db, &dst, findQuery, u.ID, r.ID) var err = meddler.QueryRow(db, &dst, findPermQuery, u.ID, r.ID)
return &dst, err return &dst, err
} }

View File

@ -1,37 +1,18 @@
package perm package database
import ( import (
"database/sql" "database/sql"
"testing" "testing"
"github.com/drone/drone/server/database/schema" "github.com/drone/drone/shared/model"
"github.com/drone/drone/server/database/testdata"
"github.com/drone/drone/server/database/testdatabase"
"github.com/drone/drone/server/resource/repo"
"github.com/drone/drone/server/resource/user"
) )
// in-memory database instance for unit testing
var db *sql.DB
// setup the test database and test fixtures
func setup() {
db, _ = testdatabase.Open()
schema.Load(db)
testdata.Load(db)
}
// teardown the test database
func teardown() {
db.Close()
}
func Test_find(t *testing.T) { func Test_find(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
manager := NewManager(db).(*permManager) manager := NewPermManager(db).(*permManager)
perm, err := manager.find(&user.User{ID: 101}, &repo.Repo{ID: 200}) perm, err := manager.find(&model.User{ID: 101}, &model.Repo{ID: 200})
if err != nil { if err != nil {
t.Errorf("Want permission, got %s", err) t.Errorf("Want permission, got %s", err)
} }
@ -78,20 +59,20 @@ func Test_find(t *testing.T) {
// test that we get the appropriate error message when // test that we get the appropriate error message when
// no permissions are found in the database. // no permissions are found in the database.
_, err = manager.find(&user.User{ID: 102}, &repo.Repo{ID: 201}) _, err = manager.find(&model.User{ID: 102}, &model.Repo{ID: 201})
if err != sql.ErrNoRows { if err != sql.ErrNoRows {
t.Errorf("Want ErrNoRows, got %s", err) t.Errorf("Want ErrNoRows, got %s", err)
} }
} }
func TestRead(t *testing.T) { func TestPermRead(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
var manager = NewManager(db) var manager = NewPermManager(db)
// dummy admin and repo // dummy admin and repo
u := user.User{ID: 101, Admin: false} u := model.User{ID: 101, Admin: false}
r := repo.Repo{ID: 201, Private: false} r := model.Repo{ID: 201, Private: false}
// public repos should always be accessible // public repos should always be accessible
if read, err := manager.Read(&u, &r); !read || err != nil { if read, err := manager.Read(&u, &r); !read || err != nil {
@ -131,14 +112,14 @@ func TestRead(t *testing.T) {
} }
} }
func TestWrite(t *testing.T) { func TestPermWrite(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
var manager = NewManager(db) var manager = NewPermManager(db)
// dummy admin and repo // dummy admin and repo
u := user.User{ID: 101, Admin: false} u := model.User{ID: 101, Admin: false}
r := repo.Repo{ID: 201, Private: false} r := model.Repo{ID: 201, Private: false}
// repos should not be accessible to nil users // repos should not be accessible to nil users
r.Private = true r.Private = true
@ -172,14 +153,14 @@ func TestWrite(t *testing.T) {
} }
} }
func TestAdmin(t *testing.T) { func TestPermAdmin(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
var manager = NewManager(db) var manager = NewPermManager(db)
// dummy admin and repo // dummy admin and repo
u := user.User{ID: 101, Admin: false} u := model.User{ID: 101, Admin: false}
r := repo.Repo{ID: 201, Private: false} r := model.Repo{ID: 201, Private: false}
// repos should not be accessible to nil users // repos should not be accessible to nil users
r.Private = true r.Private = true
@ -213,15 +194,15 @@ func TestAdmin(t *testing.T) {
} }
} }
func TestRevoke(t *testing.T) { func TestPermRevoke(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
// dummy admin and repo // dummy admin and repo
u := user.User{ID: 101} u := model.User{ID: 101}
r := repo.Repo{ID: 200} r := model.Repo{ID: 200}
manager := NewManager(db) manager := NewPermManager(db)
admin, err := manager.Admin(&u, &r) admin, err := manager.Admin(&u, &r)
if !admin || err != nil { if !admin || err != nil {
t.Errorf("Want Admin permission, got Admin %v, error %s", admin, err) t.Errorf("Want Admin permission, got Admin %v, error %s", admin, err)
@ -238,15 +219,15 @@ func TestRevoke(t *testing.T) {
} }
} }
func TestGrant(t *testing.T) { func TestPermGrant(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
// dummy admin and repo // dummy admin and repo
u := user.User{ID: 104} u := model.User{ID: 104}
r := repo.Repo{ID: 200} r := model.Repo{ID: 200}
manager := NewManager(db).(*permManager) manager := NewPermManager(db).(*permManager)
if err := manager.Grant(&u, &r, true, true, true); err != nil { if err := manager.Grant(&u, &r, true, true, true); err != nil {
t.Errorf("Want permissions granted, got %s", err) t.Errorf("Want permissions granted, got %s", err)
} }

View File

@ -1,36 +1,37 @@
package repo package database
import ( import (
"database/sql" "database/sql"
"time" "time"
"github.com/drone/drone/shared/model"
"github.com/russross/meddler" "github.com/russross/meddler"
) )
type RepoManager interface { type RepoManager interface {
// Find retrieves the Repo by ID. // Find retrieves the Repo by ID.
Find(id int64) (*Repo, error) Find(id int64) (*model.Repo, error)
// FindName retrieves the Repo by the remote, owner and name. // FindName retrieves the Repo by the remote, owner and name.
FindName(remote, owner, name string) (*Repo, error) FindName(remote, owner, name string) (*model.Repo, error)
// Insert persists a new Repo to the datastore. // Insert persists a new Repo to the datastore.
Insert(repo *Repo) error Insert(repo *model.Repo) error
// Insert persists a modified Repo to the datastore. // Insert persists a modified Repo to the datastore.
Update(repo *Repo) error Update(repo *model.Repo) error
// Delete removes a Repo from the datastore. // Delete removes a Repo from the datastore.
Delete(repo *Repo) error Delete(repo *model.Repo) error
// List retrieves all repositories from the datastore. // List retrieves all repositories from the datastore.
List(user int64) ([]*Repo, error) List(user int64) ([]*model.Repo, error)
// List retrieves all public repositories from the datastore. // List retrieves all public repositories from the datastore.
//ListPublic(user int64) ([]*Repo, error) //ListPublic(user int64) ([]*Repo, error)
} }
func NewManager(db *sql.DB) RepoManager { func NewRepoManager(db *sql.DB) RepoManager {
return &repoManager{db} return &repoManager{db}
} }
@ -38,46 +39,39 @@ type repoManager struct {
*sql.DB *sql.DB
} }
func (db *repoManager) Find(id int64) (*Repo, error) { func (db *repoManager) Find(id int64) (*model.Repo, error) {
const query = "select * from repos where repo_id = ?" const query = "select * from repos where repo_id = ?"
var repo = Repo{} var repo = model.Repo{}
var err = meddler.QueryRow(db, &repo, query, id) var err = meddler.QueryRow(db, &repo, query, id)
return &repo, err return &repo, err
} }
func (db *repoManager) FindName(remote, owner, name string) (*Repo, error) { func (db *repoManager) FindName(remote, owner, name string) (*model.Repo, error) {
const query = "select * from repos where repo_host = ? and repo_owner = ? and repo_name = ?" const query = "select * from repos where repo_host = ? and repo_owner = ? and repo_name = ?"
var repo = Repo{} var repo = model.Repo{}
var err = meddler.QueryRow(db, &repo, query, remote, owner, name) var err = meddler.QueryRow(db, &repo, query, remote, owner, name)
return &repo, err return &repo, err
} }
func (db *repoManager) List(user int64) ([]*Repo, error) { func (db *repoManager) List(user int64) ([]*model.Repo, error) {
const query = "select * from repos where repo_id IN (select repo_id from perms where user_id = ?)" const query = "select * from repos where repo_id IN (select repo_id from perms where user_id = ?)"
var repos []*Repo var repos []*model.Repo
err := meddler.QueryAll(db, &repos, query, user) err := meddler.QueryAll(db, &repos, query, user)
return repos, err return repos, err
} }
//func (db *repoManager) ListPublic(user int64) ([]*Repo, error) { func (db *repoManager) Insert(repo *model.Repo) error {
// const query = "select * from repos where repo_id IN (select repo_id from perms where user_id = ?) AND repo_private=0"
// var repos []*Repo
// err := meddler.QueryAll(db, &repos, query, user)
// return repos, err
//}
func (db *repoManager) Insert(repo *Repo) error {
repo.Created = time.Now().Unix() repo.Created = time.Now().Unix()
repo.Updated = time.Now().Unix() repo.Updated = time.Now().Unix()
return meddler.Insert(db, "repos", repo) return meddler.Insert(db, "repos", repo)
} }
func (db *repoManager) Update(repo *Repo) error { func (db *repoManager) Update(repo *model.Repo) error {
repo.Updated = time.Now().Unix() repo.Updated = time.Now().Unix()
return meddler.Update(db, "repos", repo) return meddler.Update(db, "repos", repo)
} }
func (db *repoManager) Delete(repo *Repo) error { func (db *repoManager) Delete(repo *model.Repo) error {
const stmt = "delete from repos where repo_id = ?" const stmt = "delete from repos where repo_id = ?"
_, err := db.Exec(stmt, repo.ID) _, err := db.Exec(stmt, repo.ID)
return err return err

View File

@ -1,34 +1,17 @@
package repo package database
import ( import (
"database/sql" "database/sql"
"testing" "testing"
"github.com/drone/drone/server/database/schema" "github.com/drone/drone/shared/model"
"github.com/drone/drone/server/database/testdata"
"github.com/drone/drone/server/database/testdatabase"
) )
// in-memory database instance for unit testing func TestRepoFind(t *testing.T) {
var db *sql.DB
// setup the test database and test fixtures
func setup() {
db, _ = testdatabase.Open()
schema.Load(db)
testdata.Load(db)
}
// teardown the test database
func teardown() {
db.Close()
}
func TestFind(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
repos := NewManager(db) repos := NewRepoManager(db)
repo, err := repos.Find(1) repo, err := repos.Find(1)
if err != nil { if err != nil {
t.Errorf("Want Repo from ID, got %s", err) t.Errorf("Want Repo from ID, got %s", err)
@ -37,11 +20,11 @@ func TestFind(t *testing.T) {
testRepo(t, repo) testRepo(t, repo)
} }
func TestName(t *testing.T) { func TestRepoFindName(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
repos := NewManager(db) repos := NewRepoManager(db)
user, err := repos.FindName("github.com", "lhofstadter", "lenwoloppali") user, err := repos.FindName("github.com", "lhofstadter", "lenwoloppali")
if err != nil { if err != nil {
t.Errorf("Want Repo by Name, got %s", err) t.Errorf("Want Repo by Name, got %s", err)
@ -50,11 +33,11 @@ func TestName(t *testing.T) {
testRepo(t, user) testRepo(t, user)
} }
func TestList(t *testing.T) { func TestRepoList(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
repos := NewManager(db) repos := NewRepoManager(db)
all, err := repos.List(1) all, err := repos.List(1)
if err != nil { if err != nil {
t.Errorf("Want Repos, got %s", err) t.Errorf("Want Repos, got %s", err)
@ -68,28 +51,28 @@ func TestList(t *testing.T) {
testRepo(t, all[0]) testRepo(t, all[0])
} }
func TestInsert(t *testing.T) { func TestRepoInsert(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
repo, _ := New("github.com", "mrwolowitz", "lenwoloppali") repo, _ := model.NewRepo("github.com", "mrwolowitz", "lenwoloppali")
repos := NewManager(db) repos := NewRepoManager(db)
if err := repos.Insert(repo); err != nil { if err := repos.Insert(repo); err != nil {
t.Errorf("Want Repo created, got %s", err) t.Errorf("Want Repo created, got %s", err)
} }
// verify unique remote + owner + name login constraint // verify unique remote + owner + name login constraint
var err = repos.Insert(&Repo{Host: repo.Host, Owner: repo.Owner, Name: repo.Name}) var err = repos.Insert(&model.Repo{Host: repo.Host, Owner: repo.Owner, Name: repo.Name})
if err == nil { if err == nil {
t.Error("Want unique constraint violated") t.Error("Want unique constraint violated")
} }
} }
func TestUpdate(t *testing.T) { func TestRepoUpdate(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
repos := NewManager(db) repos := NewRepoManager(db)
repo, err := repos.Find(1) repo, err := repos.Find(1)
if err != nil { if err != nil {
t.Errorf("Want Repo from ID, got %s", err) t.Errorf("Want Repo from ID, got %s", err)
@ -132,11 +115,11 @@ func TestUpdate(t *testing.T) {
} }
} }
func TestDelete(t *testing.T) { func TestRepoDelete(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
repos := NewManager(db) repos := NewRepoManager(db)
repo, err := repos.Find(1) repo, err := repos.Find(1)
if err != nil { if err != nil {
t.Errorf("Want Repo from ID, got %s", err) t.Errorf("Want Repo from ID, got %s", err)
@ -155,7 +138,7 @@ func TestDelete(t *testing.T) {
// testRepo is a helper function that compares the repo // testRepo is a helper function that compares the repo
// to an expected set of fixed field values. // to an expected set of fixed field values.
func testRepo(t *testing.T, repo *Repo) { func testRepo(t *testing.T, repo *model.Repo) {
var got, want = repo.Remote, "github.com" var got, want = repo.Remote, "github.com"
if got != want { if got != want {
t.Errorf("Want Remote %v, got %v", want, got) t.Errorf("Want Remote %v, got %v", want, got)

View File

@ -1,33 +1,34 @@
package user package database
import ( import (
"database/sql" "database/sql"
"time" "time"
"github.com/drone/drone/shared/model"
"github.com/russross/meddler" "github.com/russross/meddler"
) )
type UserManager interface { type UserManager interface {
// Find finds the User by ID. // Find finds the User by ID.
Find(id int64) (*User, error) Find(id int64) (*model.User, error)
// FindLogin finds the User by remote login. // FindLogin finds the User by remote login.
FindLogin(remote, login string) (*User, error) FindLogin(remote, login string) (*model.User, error)
// FindToken finds the User by token. // FindToken finds the User by token.
FindToken(token string) (*User, error) FindToken(token string) (*model.User, error)
// List finds all registered users of the system. // List finds all registered users of the system.
List() ([]*User, error) List() ([]*model.User, error)
// Insert persists the User to the datastore. // Insert persists the User to the datastore.
Insert(user *User) error Insert(user *model.User) error
// Update persists changes to the User to the datastore. // Update persists changes to the User to the datastore.
Update(user *User) error Update(user *model.User) error
// Delete removes the User from the datastore. // Delete removes the User from the datastore.
Delete(user *User) error Delete(user *model.User) error
} }
// userManager manages a list of users in a SQL database. // userManager manages a list of users in a SQL database.
@ -36,7 +37,7 @@ type userManager struct {
} }
// SQL query to retrieve a User by remote login. // SQL query to retrieve a User by remote login.
const findLoginQuery = ` const findUserLoginQuery = `
SELECT * SELECT *
FROM users FROM users
WHERE user_remote=? WHERE user_remote=?
@ -45,7 +46,7 @@ LIMIT 1
` `
// SQL query to retrieve a User by remote login. // SQL query to retrieve a User by remote login.
const findTokenQuery = ` const findUserTokenQuery = `
SELECT * SELECT *
FROM users FROM users
WHERE user_token=? WHERE user_token=?
@ -53,59 +54,59 @@ LIMIT 1
` `
// SQL query to retrieve a list of all users. // SQL query to retrieve a list of all users.
const listQuery = ` const listUserQuery = `
SELECT * SELECT *
FROM users FROM users
ORDER BY user_name ASC ORDER BY user_name ASC
` `
// SQL statement to delete a User by ID. // SQL statement to delete a User by ID.
const deleteStmt = ` const deleteUserStmt = `
DELETE FROM users WHERE user_id=? DELETE FROM users WHERE user_id=?
` `
// NewManager initiales a new UserManager intended to // NewUserManager initiales a new UserManager intended to
// manage and persist commits. // manage and persist commits.
func NewManager(db *sql.DB) UserManager { func NewUserManager(db *sql.DB) UserManager {
return &userManager{db} return &userManager{db}
} }
func (db *userManager) Find(id int64) (*User, error) { func (db *userManager) Find(id int64) (*model.User, error) {
dst := User{} dst := model.User{}
err := meddler.Load(db, "users", &dst, id) err := meddler.Load(db, "users", &dst, id)
return &dst, err return &dst, err
} }
func (db *userManager) FindLogin(remote, login string) (*User, error) { func (db *userManager) FindLogin(remote, login string) (*model.User, error) {
dst := User{} dst := model.User{}
err := meddler.QueryRow(db, &dst, findLoginQuery, remote, login) err := meddler.QueryRow(db, &dst, findUserLoginQuery, remote, login)
return &dst, err return &dst, err
} }
func (db *userManager) FindToken(token string) (*User, error) { func (db *userManager) FindToken(token string) (*model.User, error) {
dst := User{} dst := model.User{}
err := meddler.QueryRow(db, &dst, findTokenQuery, token) err := meddler.QueryRow(db, &dst, findUserTokenQuery, token)
return &dst, err return &dst, err
} }
func (db *userManager) List() ([]*User, error) { func (db *userManager) List() ([]*model.User, error) {
var dst []*User var dst []*model.User
err := meddler.QueryAll(db, &dst, listQuery) err := meddler.QueryAll(db, &dst, listUserQuery)
return dst, err return dst, err
} }
func (db *userManager) Insert(user *User) error { func (db *userManager) Insert(user *model.User) error {
user.Created = time.Now().Unix() user.Created = time.Now().Unix()
user.Updated = time.Now().Unix() user.Updated = time.Now().Unix()
return meddler.Insert(db, "users", user) return meddler.Insert(db, "users", user)
} }
func (db *userManager) Update(user *User) error { func (db *userManager) Update(user *model.User) error {
user.Updated = time.Now().Unix() user.Updated = time.Now().Unix()
return meddler.Update(db, "users", user) return meddler.Update(db, "users", user)
} }
func (db *userManager) Delete(user *User) error { func (db *userManager) Delete(user *model.User) error {
_, err := db.Exec(deleteStmt, user.ID) _, err := db.Exec(deleteUserStmt, user.ID)
return err return err
} }

View File

@ -1,4 +1,4 @@
package user package database
import ( import (
"database/sql" "database/sql"
@ -7,6 +7,7 @@ import (
"github.com/drone/drone/server/database/schema" "github.com/drone/drone/server/database/schema"
"github.com/drone/drone/server/database/testdata" "github.com/drone/drone/server/database/testdata"
"github.com/drone/drone/server/database/testdatabase" "github.com/drone/drone/server/database/testdatabase"
"github.com/drone/drone/shared/model"
) )
// in-memory database instance for unit testing // in-memory database instance for unit testing
@ -24,11 +25,11 @@ func teardown() {
db.Close() db.Close()
} }
func TestFind(t *testing.T) { func TestUserFind(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
users := NewManager(db) users := NewUserManager(db)
user, err := users.Find(1) user, err := users.Find(1)
if err != nil { if err != nil {
t.Errorf("Want User from ID, got %s", err) t.Errorf("Want User from ID, got %s", err)
@ -37,11 +38,11 @@ func TestFind(t *testing.T) {
testUser(t, user) testUser(t, user)
} }
func TestFindLogin(t *testing.T) { func TestUserFindLogin(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
users := NewManager(db) users := NewUserManager(db)
user, err := users.FindLogin("github.com", "smellypooper") user, err := users.FindLogin("github.com", "smellypooper")
if err != nil { if err != nil {
t.Errorf("Want User from Login, got %s", err) t.Errorf("Want User from Login, got %s", err)
@ -50,11 +51,11 @@ func TestFindLogin(t *testing.T) {
testUser(t, user) testUser(t, user)
} }
func TestFindToken(t *testing.T) { func TestUserFindToken(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
users := NewManager(db) users := NewUserManager(db)
user, err := users.FindToken("e42080dddf012c718e476da161d21ad5") user, err := users.FindToken("e42080dddf012c718e476da161d21ad5")
if err != nil { if err != nil {
t.Errorf("Want User from Token, got %s", err) t.Errorf("Want User from Token, got %s", err)
@ -63,11 +64,11 @@ func TestFindToken(t *testing.T) {
testUser(t, user) testUser(t, user)
} }
func TestList(t *testing.T) { func TestUserList(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
users := NewManager(db) users := NewUserManager(db)
all, err := users.List() all, err := users.List()
if err != nil { if err != nil {
t.Errorf("Want Users, got %s", err) t.Errorf("Want Users, got %s", err)
@ -81,12 +82,12 @@ func TestList(t *testing.T) {
testUser(t, all[0]) testUser(t, all[0])
} }
func TestInsert(t *testing.T) { func TestUserInsert(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
user := New("github.com", "winkle", "winkle@caltech.edu") user := model.NewUser("github.com", "winkle", "winkle@caltech.edu")
users := NewManager(db) users := NewUserManager(db)
if err := users.Insert(user); err != nil { if err := users.Insert(user); err != nil {
t.Errorf("Want User created, got %s", err) t.Errorf("Want User created, got %s", err)
} }
@ -97,23 +98,23 @@ func TestInsert(t *testing.T) {
} }
// verify unique remote + remote login constraint // verify unique remote + remote login constraint
var err = users.Insert(&User{Remote: user.Remote, Login: user.Login, Token: "f71eb4a81a2cca56035dd7f6f2942e41"}) var err = users.Insert(&model.User{Remote: user.Remote, Login: user.Login, Token: "f71eb4a81a2cca56035dd7f6f2942e41"})
if err == nil { if err == nil {
t.Error("Want Token unique constraint violated") t.Error("Want Token unique constraint violated")
} }
// verify unique token constraint // verify unique token constraint
err = users.Insert(&User{Remote: "gitlab.com", Login: user.Login, Token: user.Token}) err = users.Insert(&model.User{Remote: "gitlab.com", Login: user.Login, Token: user.Token})
if err == nil { if err == nil {
t.Error("Want Token unique constraint violated") t.Error("Want Token unique constraint violated")
} }
} }
func TestUpdate(t *testing.T) { func TestUserUpdate(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
users := NewManager(db) users := NewUserManager(db)
user, err := users.Find(4) user, err := users.Find(4)
if err != nil { if err != nil {
t.Errorf("Want User from ID, got %s", err) t.Errorf("Want User from ID, got %s", err)
@ -138,11 +139,11 @@ func TestUpdate(t *testing.T) {
} }
} }
func TestDelete(t *testing.T) { func TestUserDelete(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
users := NewManager(db) users := NewUserManager(db)
user, err := users.Find(1) user, err := users.Find(1)
if err != nil { if err != nil {
t.Errorf("Want User from ID, got %s", err) t.Errorf("Want User from ID, got %s", err)
@ -161,7 +162,7 @@ func TestDelete(t *testing.T) {
// testUser is a helper function that compares the user // testUser is a helper function that compares the user
// to an expected set of fixed field values. // to an expected set of fixed field values.
func testUser(t *testing.T, user *User) { func testUser(t *testing.T, user *model.User) {
var got, want = user.Login, "smellypooper" var got, want = user.Login, "smellypooper"
if got != want { if got != want {
t.Errorf("Want Token %v, got %v", want, got) t.Errorf("Want Token %v, got %v", want, got)

View File

@ -4,8 +4,8 @@ import (
"net/http" "net/http"
"time" "time"
"github.com/drone/drone/server/resource/commit" "github.com/drone/drone/server/database"
"github.com/drone/drone/server/resource/repo" "github.com/drone/drone/shared/model"
"github.com/gorilla/pat" "github.com/gorilla/pat"
) )
@ -20,11 +20,11 @@ var (
) )
type BadgeHandler struct { type BadgeHandler struct {
commits commit.CommitManager commits database.CommitManager
repos repo.RepoManager repos database.RepoManager
} }
func NewBadgeHandler(repos repo.RepoManager, commits commit.CommitManager) *BadgeHandler { func NewBadgeHandler(repos database.RepoManager, commits database.CommitManager) *BadgeHandler {
return &BadgeHandler{commits, repos} return &BadgeHandler{commits, repos}
} }
@ -54,7 +54,7 @@ func (h *BadgeHandler) GetStatus(w http.ResponseWriter, r *http.Request) error {
// if no branch, use the default // if no branch, use the default
if len(branch) == 0 { if len(branch) == 0 {
branch = repo.DefaultBranch branch = model.DefaultBranch
} }
// get the latest commit // get the latest commit
@ -69,13 +69,13 @@ func (h *BadgeHandler) GetStatus(w http.ResponseWriter, r *http.Request) error {
// determine which badge to load // determine which badge to load
switch c.Status { switch c.Status {
case commit.StatusSuccess: case model.StatusSuccess:
w.Write(badgeSuccess) w.Write(badgeSuccess)
case commit.StatusFailure: case model.StatusFailure:
w.Write(badgeFailure) w.Write(badgeFailure)
case commit.StatusError: case model.StatusError:
w.Write(badgeError) w.Write(badgeError)
case commit.StatusEnqueue, commit.StatusStarted: case model.StatusEnqueue, model.StatusStarted:
w.Write(badgeStarted) w.Write(badgeStarted)
default: default:
w.Write(badgeNone) w.Write(badgeNone)

View File

@ -4,21 +4,19 @@ import (
"encoding/json" "encoding/json"
"net/http" "net/http"
"github.com/drone/drone/server/resource/commit" "github.com/drone/drone/server/database"
"github.com/drone/drone/server/resource/perm"
"github.com/drone/drone/server/resource/repo"
"github.com/drone/drone/server/session" "github.com/drone/drone/server/session"
"github.com/gorilla/pat" "github.com/gorilla/pat"
) )
type BranchHandler struct { type BranchHandler struct {
perms perm.PermManager perms database.PermManager
repos repo.RepoManager repos database.RepoManager
commits commit.CommitManager commits database.CommitManager
sess session.Session sess session.Session
} }
func NewBranchHandler(repos repo.RepoManager, commits commit.CommitManager, perms perm.PermManager, sess session.Session) *BranchHandler { func NewBranchHandler(repos database.RepoManager, commits database.CommitManager, perms database.PermManager, sess session.Session) *BranchHandler {
return &BranchHandler{perms, repos, commits, sess} return &BranchHandler{perms, repos, commits, sess}
} }

View File

@ -4,23 +4,22 @@ import (
"encoding/json" "encoding/json"
"net/http" "net/http"
"github.com/drone/drone/server/database"
"github.com/drone/drone/server/queue" "github.com/drone/drone/server/queue"
"github.com/drone/drone/server/resource/commit"
"github.com/drone/drone/server/resource/perm"
"github.com/drone/drone/server/resource/repo"
"github.com/drone/drone/server/session" "github.com/drone/drone/server/session"
"github.com/drone/drone/shared/model"
"github.com/gorilla/pat" "github.com/gorilla/pat"
) )
type CommitHandler struct { type CommitHandler struct {
perms perm.PermManager perms database.PermManager
repos repo.RepoManager repos database.RepoManager
commits commit.CommitManager commits database.CommitManager
sess session.Session sess session.Session
queue *queue.Queue queue *queue.Queue
} }
func NewCommitHandler(repos repo.RepoManager, commits commit.CommitManager, perms perm.PermManager, sess session.Session, queue *queue.Queue) *CommitHandler { func NewCommitHandler(repos database.RepoManager, commits database.CommitManager, perms database.PermManager, sess session.Session, queue *queue.Queue) *CommitHandler {
return &CommitHandler{perms, repos, commits, sess, queue} return &CommitHandler{perms, repos, commits, sess, queue}
} }
@ -146,11 +145,11 @@ func (h *CommitHandler) PostCommit(w http.ResponseWriter, r *http.Request) error
} }
// we can't start an already started build // we can't start an already started build
if c.Status == commit.StatusStarted || c.Status == commit.StatusEnqueue { if c.Status == model.StatusStarted || c.Status == model.StatusEnqueue {
return badRequest{} return badRequest{}
} }
c.Status = commit.StatusEnqueue c.Status = model.StatusEnqueue
c.Started = 0 c.Started = 0
c.Finished = 0 c.Finished = 0
c.Duration = 0 c.Duration = 0

View File

@ -3,23 +3,22 @@ package handler
import ( import (
"net/http" "net/http"
"github.com/drone/drone/server/database"
"github.com/drone/drone/server/queue" "github.com/drone/drone/server/queue"
"github.com/drone/drone/server/resource/commit"
"github.com/drone/drone/server/resource/config" "github.com/drone/drone/server/resource/config"
"github.com/drone/drone/server/resource/repo" "github.com/drone/drone/shared/model"
"github.com/drone/drone/server/resource/user"
"github.com/gorilla/pat" "github.com/gorilla/pat"
) )
type HookHandler struct { type HookHandler struct {
users user.UserManager users database.UserManager
repos repo.RepoManager repos database.RepoManager
commits commit.CommitManager commits database.CommitManager
queue *queue.Queue queue *queue.Queue
conf *config.Config conf *config.Config
} }
func NewHookHandler(users user.UserManager, repos repo.RepoManager, commits commit.CommitManager, conf *config.Config, queue *queue.Queue) *HookHandler { func NewHookHandler(users database.UserManager, repos database.RepoManager, commits database.CommitManager, conf *config.Config, queue *queue.Queue) *HookHandler {
return &HookHandler{users, repos, commits, queue, conf} return &HookHandler{users, repos, commits, queue, conf}
} }
@ -76,9 +75,9 @@ func (h *HookHandler) PostHook(w http.ResponseWriter, r *http.Request) error {
return badRequest{err} return badRequest{err}
} }
c := commit.Commit{ c := model.Commit{
RepoID: repo.ID, RepoID: repo.ID,
Status: commit.StatusEnqueue, Status: model.StatusEnqueue,
Sha: hook.Sha, Sha: hook.Sha,
Branch: hook.Branch, Branch: hook.Branch,
PullRequest: hook.PullRequest, PullRequest: hook.PullRequest,

View File

@ -5,23 +5,22 @@ import (
"net/http" "net/http"
"time" "time"
"github.com/drone/drone/server/database"
"github.com/drone/drone/server/resource/config" "github.com/drone/drone/server/resource/config"
"github.com/drone/drone/server/resource/perm"
"github.com/drone/drone/server/resource/repo"
"github.com/drone/drone/server/resource/user"
"github.com/drone/drone/server/session" "github.com/drone/drone/server/session"
"github.com/drone/drone/shared/model"
"github.com/gorilla/pat" "github.com/gorilla/pat"
) )
type LoginHandler struct { type LoginHandler struct {
users user.UserManager users database.UserManager
repos repo.RepoManager repos database.RepoManager
perms perm.PermManager perms database.PermManager
sess session.Session sess session.Session
conf *config.Config conf *config.Config
} }
func NewLoginHandler(users user.UserManager, repos repo.RepoManager, perms perm.PermManager, sess session.Session, conf *config.Config) *LoginHandler { func NewLoginHandler(users database.UserManager, repos database.RepoManager, perms database.PermManager, sess session.Session, conf *config.Config) *LoginHandler {
return &LoginHandler{users, repos, perms, sess, conf} return &LoginHandler{users, repos, perms, sess, conf}
} }
@ -56,7 +55,7 @@ func (h *LoginHandler) GetLogin(w http.ResponseWriter, r *http.Request) error {
} }
// create the user account // create the user account
u = user.New(remote.GetName(), login.Login, login.Email) u = model.NewUser(remote.GetName(), login.Login, login.Email)
u.Name = login.Name u.Name = login.Name
u.SetEmail(login.Email) u.SetEmail(login.Email)
@ -86,7 +85,7 @@ func (h *LoginHandler) GetLogin(w http.ResponseWriter, r *http.Request) error {
// TODO this should move to a server/sync package and // TODO this should move to a server/sync package and
// should be injected into this struct, just like // should be injected into this struct, just like
// the database code. // the database code.
if u.Stale() { if u.IsStale() {
log.Println("sync user account.", u.Login) log.Println("sync user account.", u.Login)
// sync inside a goroutine. This should eventually be moved to // sync inside a goroutine. This should eventually be moved to
@ -109,7 +108,7 @@ func (h *LoginHandler) GetLogin(w http.ResponseWriter, r *http.Request) error {
// insert all repositories // insert all repositories
for _, remoteRepo := range repos { for _, remoteRepo := range repos {
repo, _ := repo.New(remote.GetName(), remoteRepo.Owner, remoteRepo.Name) repo, _ := model.NewRepo(remote.GetName(), remoteRepo.Owner, remoteRepo.Name)
repo.Private = remoteRepo.Private repo.Private = remoteRepo.Private
repo.Host = remoteRepo.Host repo.Host = remoteRepo.Host
repo.CloneURL = remoteRepo.Clone repo.CloneURL = remoteRepo.Clone

View File

@ -5,10 +5,8 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"github.com/drone/drone/server/resource/commit" "github.com/drone/drone/server/database"
"github.com/drone/drone/server/resource/config" "github.com/drone/drone/server/resource/config"
"github.com/drone/drone/server/resource/perm"
"github.com/drone/drone/server/resource/repo"
"github.com/drone/drone/server/session" "github.com/drone/drone/server/session"
"github.com/drone/drone/shared/httputil" "github.com/drone/drone/shared/httputil"
"github.com/drone/drone/shared/sshutil" "github.com/drone/drone/shared/sshutil"
@ -17,14 +15,14 @@ import (
type RepoHandler struct { type RepoHandler struct {
conf *config.Config conf *config.Config
commits commit.CommitManager commits database.CommitManager
perms perm.PermManager perms database.PermManager
repos repo.RepoManager repos database.RepoManager
sess session.Session sess session.Session
} }
func NewRepoHandler(repos repo.RepoManager, commits commit.CommitManager, func NewRepoHandler(repos database.RepoManager, commits database.CommitManager,
perms perm.PermManager, sess session.Session, conf *config.Config) *RepoHandler { perms database.PermManager, sess session.Session, conf *config.Config) *RepoHandler {
return &RepoHandler{conf, commits, perms, repos, sess} return &RepoHandler{conf, commits, perms, repos, sess}
} }

View File

@ -5,27 +5,25 @@ import (
"net/http" "net/http"
"github.com/drone/drone/server/channel" "github.com/drone/drone/server/channel"
"github.com/drone/drone/server/resource/commit" "github.com/drone/drone/server/database"
"github.com/drone/drone/server/resource/perm"
"github.com/drone/drone/server/resource/repo"
"github.com/drone/drone/server/resource/user"
"github.com/drone/drone/server/session" "github.com/drone/drone/server/session"
"github.com/drone/drone/shared/httputil" "github.com/drone/drone/shared/httputil"
"github.com/drone/drone/shared/model"
"github.com/gorilla/pat" "github.com/gorilla/pat"
) )
type Renderer func(wr io.Writer, name string, data interface{}) error type Renderer func(wr io.Writer, name string, data interface{}) error
type SiteHandler struct { type SiteHandler struct {
users user.UserManager users database.UserManager
repos repo.RepoManager repos database.RepoManager
commits commit.CommitManager commits database.CommitManager
perms perm.PermManager perms database.PermManager
sess session.Session sess session.Session
render Renderer render Renderer
} }
func NewSiteHandler(users user.UserManager, repos repo.RepoManager, commits commit.CommitManager, perms perm.PermManager, sess session.Session, render Renderer) *SiteHandler { func NewSiteHandler(users database.UserManager, repos database.RepoManager, commits database.CommitManager, perms database.PermManager, sess session.Session, render Renderer) *SiteHandler {
return &SiteHandler{users, repos, commits, perms, sess, render} return &SiteHandler{users, repos, commits, perms, sess, render}
} }
@ -39,15 +37,15 @@ func (s *SiteHandler) GetIndex(w http.ResponseWriter, r *http.Request) error {
} }
feed, _ := s.commits.ListUser(u.ID) feed, _ := s.commits.ListUser(u.ID)
data := struct { data := struct {
User *user.User User *model.User
Feed []*commit.CommitRepo Feed []*model.CommitRepo
}{u, feed} }{u, feed}
return s.render(w, "user_feed.html", &data) return s.render(w, "user_feed.html", &data)
} }
// GetLogin serves the account login page // GetLogin serves the account login page
func (s *SiteHandler) GetLogin(w http.ResponseWriter, r *http.Request) error { func (s *SiteHandler) GetLogin(w http.ResponseWriter, r *http.Request) error {
return s.render(w, "login.html", struct{ User *user.User }{nil}) return s.render(w, "login.html", struct{ User *model.User }{nil})
} }
// GetUser serves the account settings page. // GetUser serves the account settings page.
@ -56,7 +54,7 @@ func (s *SiteHandler) GetUser(w http.ResponseWriter, r *http.Request) error {
if u == nil { if u == nil {
return s.render(w, "404.html", nil) return s.render(w, "404.html", nil)
} }
return s.render(w, "user_conf.html", struct{ User *user.User }{u}) return s.render(w, "user_conf.html", struct{ User *model.User }{u})
} }
func (s *SiteHandler) GetUsers(w http.ResponseWriter, r *http.Request) error { func (s *SiteHandler) GetUsers(w http.ResponseWriter, r *http.Request) error {
@ -64,7 +62,7 @@ func (s *SiteHandler) GetUsers(w http.ResponseWriter, r *http.Request) error {
if u == nil || u.Admin == false { if u == nil || u.Admin == false {
return s.render(w, "404.html", nil) return s.render(w, "404.html", nil)
} }
return s.render(w, "admin_users.html", struct{ User *user.User }{u}) return s.render(w, "admin_users.html", struct{ User *model.User }{u})
} }
func (s *SiteHandler) GetConfig(w http.ResponseWriter, r *http.Request) error { func (s *SiteHandler) GetConfig(w http.ResponseWriter, r *http.Request) error {
@ -72,7 +70,7 @@ func (s *SiteHandler) GetConfig(w http.ResponseWriter, r *http.Request) error {
if u == nil || u.Admin == false { if u == nil || u.Admin == false {
return s.render(w, "404.html", nil) return s.render(w, "404.html", nil)
} }
return s.render(w, "admin_conf.html", struct{ User *user.User }{u}) return s.render(w, "admin_conf.html", struct{ User *model.User }{u})
} }
func (s *SiteHandler) GetRepo(w http.ResponseWriter, r *http.Request) error { func (s *SiteHandler) GetRepo(w http.ResponseWriter, r *http.Request) error {
@ -89,14 +87,14 @@ func (s *SiteHandler) GetRepo(w http.ResponseWriter, r *http.Request) error {
return s.render(w, "404.html", nil) return s.render(w, "404.html", nil)
} }
data := struct { data := struct {
User *user.User User *model.User
Repo *repo.Repo Repo *model.Repo
Branch string Branch string
Channel string Channel string
Stream string Stream string
Branches []*commit.Commit Branches []*model.Commit
Commits []*commit.Commit Commits []*model.Commit
Commit *commit.Commit Commit *model.Commit
}{User: usr, Repo: arepo} }{User: usr, Repo: arepo}
// generate a token for connecting to the streaming server // generate a token for connecting to the streaming server
@ -148,8 +146,8 @@ func (s *SiteHandler) GetRepoAdmin(w http.ResponseWriter, r *http.Request) error
return s.render(w, "404.html", nil) return s.render(w, "404.html", nil)
} }
data := struct { data := struct {
User *user.User User *model.User
Repo *repo.Repo Repo *model.Repo
Host string Host string
Scheme string Scheme string
}{u, arepo, httputil.GetHost(r), httputil.GetScheme(r)} }{u, arepo, httputil.GetHost(r), httputil.GetScheme(r)}
@ -167,8 +165,8 @@ func (s *SiteHandler) GetRepos(w http.ResponseWriter, r *http.Request) error {
s.render(w, "500.html", nil) s.render(w, "500.html", nil)
} }
data := struct { data := struct {
User *user.User User *model.User
Repos []*repo.Repo Repos []*model.Repo
}{u, repos} }{u, repos}
return s.render(w, "user_repos.html", &data) return s.render(w, "user_repos.html", &data)
} }

View File

@ -4,21 +4,20 @@ import (
"encoding/json" "encoding/json"
"net/http" "net/http"
"github.com/drone/drone/server/resource/commit" "github.com/drone/drone/server/database"
"github.com/drone/drone/server/resource/repo"
"github.com/drone/drone/server/resource/user"
"github.com/drone/drone/server/session" "github.com/drone/drone/server/session"
"github.com/drone/drone/shared/model"
"github.com/gorilla/pat" "github.com/gorilla/pat"
) )
type UserHandler struct { type UserHandler struct {
commits commit.CommitManager commits database.CommitManager
repos repo.RepoManager repos database.RepoManager
users user.UserManager users database.UserManager
sess session.Session sess session.Session
} }
func NewUserHandler(users user.UserManager, repos repo.RepoManager, commits commit.CommitManager, sess session.Session) *UserHandler { func NewUserHandler(users database.UserManager, repos database.RepoManager, commits database.CommitManager, sess session.Session) *UserHandler {
return &UserHandler{commits, repos, users, sess} return &UserHandler{commits, repos, users, sess}
} }
@ -35,7 +34,7 @@ func (h *UserHandler) GetUser(w http.ResponseWriter, r *http.Request) error {
// requesting their own data, and will need to display // requesting their own data, and will need to display
// the Token on the website. // the Token on the website.
data := struct { data := struct {
*user.User *model.User
Token string `json:"token"` Token string `json:"token"`
}{u, u.Token} }{u, u.Token}
return json.NewEncoder(w).Encode(&data) return json.NewEncoder(w).Encode(&data)
@ -52,7 +51,7 @@ func (h *UserHandler) PutUser(w http.ResponseWriter, r *http.Request) error {
// unmarshal the repository from the payload // unmarshal the repository from the payload
defer r.Body.Close() defer r.Body.Close()
in := user.User{} in := model.User{}
if err := json.NewDecoder(r.Body).Decode(&in); err != nil { if err := json.NewDecoder(r.Body).Decode(&in); err != nil {
return badRequest{err} return badRequest{err}
} }

View File

@ -4,17 +4,17 @@ import (
"encoding/json" "encoding/json"
"net/http" "net/http"
"github.com/drone/drone/server/resource/user" "github.com/drone/drone/server/database"
"github.com/drone/drone/server/session" "github.com/drone/drone/server/session"
"github.com/gorilla/pat" "github.com/gorilla/pat"
) )
type UsersHandler struct { type UsersHandler struct {
users user.UserManager users database.UserManager
sess session.Session sess session.Session
} }
func NewUsersHandler(users user.UserManager, sess session.Session) *UsersHandler { func NewUsersHandler(users database.UserManager, sess session.Session) *UsersHandler {
return &UsersHandler{users, sess} return &UsersHandler{users, sess}
} }

View File

@ -10,14 +10,11 @@ import (
"code.google.com/p/go.net/websocket" "code.google.com/p/go.net/websocket"
"github.com/drone/drone/server/channel" "github.com/drone/drone/server/channel"
"github.com/drone/drone/server/database"
"github.com/drone/drone/server/database/schema" "github.com/drone/drone/server/database/schema"
"github.com/drone/drone/server/handler" "github.com/drone/drone/server/handler"
"github.com/drone/drone/server/queue" "github.com/drone/drone/server/queue"
"github.com/drone/drone/server/resource/commit"
"github.com/drone/drone/server/resource/config" "github.com/drone/drone/server/resource/config"
"github.com/drone/drone/server/resource/perm"
"github.com/drone/drone/server/resource/repo"
"github.com/drone/drone/server/resource/user"
"github.com/drone/drone/server/session" "github.com/drone/drone/server/session"
"github.com/drone/drone/shared/build/docker" "github.com/drone/drone/shared/build/docker"
"github.com/drone/drone/shared/build/log" "github.com/drone/drone/shared/build/log"
@ -95,10 +92,10 @@ func main() {
schema.Load(db) schema.Load(db)
// setup the database managers // setup the database managers
repos := repo.NewManager(db) repos := database.NewRepoManager(db)
users := user.NewManager(db) users := database.NewUserManager(db)
perms := perm.NewManager(db) perms := database.NewPermManager(db)
commits := commit.NewManager(db) commits := database.NewCommitManager(db)
// cancel all previously running builds // cancel all previously running builds
go commits.CancelAll() go commits.CancelAll()

View File

@ -1,9 +1,8 @@
package queue package queue
import ( import (
"github.com/drone/drone/server/resource/commit" "github.com/drone/drone/server/database"
"github.com/drone/drone/server/resource/repo" "github.com/drone/drone/shared/model"
"github.com/drone/drone/server/resource/user"
"github.com/drone/drone/shared/build/script" "github.com/drone/drone/shared/build/script"
) )
@ -16,9 +15,9 @@ type Queue struct {
// BuildTasks represents a build that is pending // BuildTasks represents a build that is pending
// execution. // execution.
type BuildTask struct { type BuildTask struct {
User *user.User User *model.User
Repo *repo.Repo Repo *model.Repo
Commit *commit.Commit Commit *model.Commit
// Build instructions from the .drone.yml // Build instructions from the .drone.yml
// file, unmarshalled. // file, unmarshalled.
@ -26,7 +25,7 @@ type BuildTask struct {
} }
// Start N workers with the given build runner. // Start N workers with the given build runner.
func Start(workers int, commits commit.CommitManager, runner BuildRunner) *Queue { func Start(workers int, commits database.CommitManager, runner BuildRunner) *Queue {
tasks := make(chan *BuildTask) tasks := make(chan *BuildTask)
queue := &Queue{tasks: tasks} queue := &Queue{tasks: tasks}

View File

@ -4,20 +4,19 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"github.com/drone/drone/server/channel" "github.com/drone/drone/server/channel"
"github.com/drone/drone/server/database"
"github.com/drone/drone/shared/build/git" "github.com/drone/drone/shared/build/git"
r "github.com/drone/drone/shared/build/repo" "github.com/drone/drone/shared/build/repo"
"github.com/drone/drone/shared/build/script" "github.com/drone/drone/shared/build/script"
"github.com/drone/drone/shared/model"
"io" "io"
"log" "log"
"path/filepath" "path/filepath"
"time" "time"
"github.com/drone/drone/server/resource/commit"
"github.com/drone/drone/server/resource/repo"
) )
type worker struct { type worker struct {
commits commit.CommitManager commits database.CommitManager
runner BuildRunner runner BuildRunner
} }
@ -52,7 +51,7 @@ func (w *worker) execute(task *BuildTask) error {
if e := recover(); e != nil { if e := recover(); e != nil {
task.Commit.Finished = time.Now().Unix() task.Commit.Finished = time.Now().Unix()
task.Commit.Duration = task.Commit.Finished - task.Commit.Started task.Commit.Duration = task.Commit.Finished - task.Commit.Started
task.Commit.Status = commit.StatusError task.Commit.Status = model.StatusError
w.commits.Update(task.Commit) w.commits.Update(task.Commit)
} }
}() }()
@ -66,7 +65,7 @@ func (w *worker) execute(task *BuildTask) error {
} }
// update commit and build status // update commit and build status
task.Commit.Status = commit.StatusStarted task.Commit.Status = model.StatusStarted
task.Commit.Started = time.Now().Unix() task.Commit.Started = time.Now().Unix()
// persist the commit to the database // persist the commit to the database
@ -132,14 +131,14 @@ func (w *worker) execute(task *BuildTask) error {
task.Commit.Finished = time.Now().Unix() task.Commit.Finished = time.Now().Unix()
task.Commit.Duration = task.Commit.Finished - task.Commit.Started task.Commit.Duration = task.Commit.Finished - task.Commit.Started
task.Commit.Status = commit.StatusSuccess task.Commit.Status = model.StatusSuccess
// capture build output // capture build output
stdout := buf.buf.String() stdout := buf.buf.String()
// if exit code != 0 set to failure // if exit code != 0 set to failure
if passed { if passed {
task.Commit.Status = commit.StatusFailure task.Commit.Status = model.StatusFailure
if buildErr != nil && len(stdout) == 0 { if buildErr != nil && len(stdout) == 0 {
// TODO: If you wanted to have very friendly error messages, you could do that here // TODO: If you wanted to have very friendly error messages, you could do that here
stdout = fmt.Sprintf("%s\n", buildErr.Error()) stdout = fmt.Sprintf("%s\n", buildErr.Error())
@ -173,7 +172,7 @@ func (w *worker) runBuild(task *BuildTask, buf io.Writer) (bool, error) {
var path = filepath.Join(task.Repo.Host, task.Repo.Owner, task.Repo.Name) var path = filepath.Join(task.Repo.Host, task.Repo.Owner, task.Repo.Name)
path = git.GitPath(task.Script.Git, path) path = git.GitPath(task.Script.Git, path)
repo := &r.Repo{ repo := &repo.Repo{
Name: task.Repo.Host + task.Repo.Owner + task.Repo.Name, Name: task.Repo.Host + task.Repo.Owner + task.Repo.Name,
Path: task.Repo.CloneURL, Path: task.Repo.CloneURL,
Branch: task.Commit.Branch, Branch: task.Commit.Branch,
@ -200,7 +199,7 @@ func (w *worker) runBuild(task *BuildTask, buf io.Writer) (bool, error) {
// updateGitHubStatus is a helper function that will send // updateGitHubStatus is a helper function that will send
// the build status to GitHub using the Status API. // the build status to GitHub using the Status API.
// see https://github.com/blog/1227-commit-status-api // see https://github.com/blog/1227-commit-status-api
func updateGitHubStatus(repo *repo.Repo, commit *commit.Commit) error { func updateGitHubStatus(repo *repo.Repo, commit *model.Commit) error {
/* /*
// convert from drone status to github status // convert from drone status to github status
var message, status string var message, status string

View File

@ -1,12 +0,0 @@
package perm
type perm struct {
ID int64 `meddler:"perm_id,pk"`
UserID int64 `meddler:"user_id"`
RepoID int64 `meddler:"repo_id"`
Read bool `meddler:"perm_read"`
Write bool `meddler:"perm_write"`
Admin bool `meddler:"perm_admin"`
Created int64 `meddler:"perm_created"`
Updated int64 `meddler:"perm_updated"`
}

View File

@ -1,22 +0,0 @@
package user
import (
"testing"
)
func TestSetEmail(t *testing.T) {
user := User{}
user.SetEmail("winkle@caltech.edu")
// make sure the email was correctly set
var got, want = user.Email, "winkle@caltech.edu"
if got != want {
t.Errorf("Want Email %s, got %s", want, got)
}
// make sure the gravatar hash was correctly calculated
got, want = user.Gravatar, "ab23a88a3ed77ecdfeb894c0eaf2817a"
if got != want {
t.Errorf("Want Gravatar %s, got %s", want, got)
}
}

View File

@ -3,7 +3,8 @@ package session
import ( import (
"net/http" "net/http"
"github.com/drone/drone/server/resource/user" "github.com/drone/drone/server/database"
"github.com/drone/drone/shared/model"
"github.com/gorilla/securecookie" "github.com/gorilla/securecookie"
"github.com/gorilla/sessions" "github.com/gorilla/sessions"
) )
@ -13,25 +14,25 @@ var cookies = sessions.NewCookieStore(
securecookie.GenerateRandomKey(64)) securecookie.GenerateRandomKey(64))
type Session interface { type Session interface {
User(r *http.Request) *user.User User(r *http.Request) *model.User
UserToken(r *http.Request) *user.User UserToken(r *http.Request) *model.User
UserCookie(r *http.Request) *user.User UserCookie(r *http.Request) *model.User
SetUser(w http.ResponseWriter, r *http.Request, u *user.User) SetUser(w http.ResponseWriter, r *http.Request, u *model.User)
Clear(w http.ResponseWriter, r *http.Request) Clear(w http.ResponseWriter, r *http.Request)
} }
type session struct { type session struct {
users user.UserManager users database.UserManager
} }
func NewSession(users user.UserManager) Session { func NewSession(users database.UserManager) Session {
return &session{ return &session{
users: users, users: users,
} }
} }
// User gets the currently authenticated user from the secure cookie session. // User gets the currently authenticated user from the secure cookie session.
func (s *session) User(r *http.Request) *user.User { func (s *session) User(r *http.Request) *model.User {
//if true { //if true {
// user, _ := s.users.Find(1) // user, _ := s.users.Find(1)
// return user // return user
@ -47,14 +48,14 @@ func (s *session) User(r *http.Request) *user.User {
} }
// UserToken gets the currently authenticated user for the given auth token. // UserToken gets the currently authenticated user for the given auth token.
func (s *session) UserToken(r *http.Request) *user.User { func (s *session) UserToken(r *http.Request) *model.User {
token := r.FormValue("access_token") token := r.FormValue("access_token")
user, _ := s.users.FindToken(token) user, _ := s.users.FindToken(token)
return user return user
} }
// UserCookie gets the currently authenticated user from the secure cookie session. // UserCookie gets the currently authenticated user from the secure cookie session.
func (s *session) UserCookie(r *http.Request) *user.User { func (s *session) UserCookie(r *http.Request) *model.User {
sess, err := cookies.Get(r, "_sess") sess, err := cookies.Get(r, "_sess")
if err != nil { if err != nil {
return nil return nil
@ -70,7 +71,7 @@ func (s *session) UserCookie(r *http.Request) *user.User {
} }
// SetUser writes the specified username to the session. // SetUser writes the specified username to the session.
func (s *session) SetUser(w http.ResponseWriter, r *http.Request, u *user.User) { func (s *session) SetUser(w http.ResponseWriter, r *http.Request, u *model.User) {
sess, _ := cookies.Get(r, "_sess") sess, _ := cookies.Get(r, "_sess")
sess.Values["uid"] = u.ID sess.Values["uid"] = u.ID
sess.Save(r, w) sess.Save(r, w)

View File

@ -1,20 +1,9 @@
package commit package model
import ( import (
"github.com/drone/drone/server/resource/util"
"time" "time"
) )
const (
StatusNone = "None"
StatusEnqueue = "Pending"
StatusStarted = "Started"
StatusSuccess = "Success"
StatusFailure = "Failure"
StatusError = "Error"
StatusKilled = "Killed"
)
type Commit struct { type Commit struct {
ID int64 `meddler:"commit_id,pk" json:"id"` ID int64 `meddler:"commit_id,pk" json:"id"`
RepoID int64 `meddler:"repo_id" json:"-"` RepoID int64 `meddler:"repo_id" json:"-"`
@ -37,7 +26,7 @@ type Commit struct {
// SetAuthor sets the author's email address and calculate the Gravatar hash. // SetAuthor sets the author's email address and calculate the Gravatar hash.
func (c *Commit) SetAuthor(email string) { func (c *Commit) SetAuthor(email string) {
c.Author = email c.Author = email
c.Gravatar = util.CreateGravatar(email) c.Gravatar = createGravatar(email)
} }
// Returns the Short (--short) Commit Hash. // Returns the Short (--short) Commit Hash.

1
shared/model/config.go Normal file
View File

@ -0,0 +1 @@
package model

View File

@ -1,4 +1,4 @@
package repo package model
import ( import (
"gopkg.in/yaml.v1" "gopkg.in/yaml.v1"
@ -11,12 +11,9 @@ var (
DefaultTimeout int64 = 7200 DefaultTimeout int64 = 7200
) )
const ( // RepoParams represents a set of private key value parameters
HostGitlab = "gitlab.com" // for each Repository.
HostGithub = "github.com" type RepoParams map[string]string
HostGithubEnterprise = "enterprise.github.com"
HostBitbucket = "bitbucket.org"
)
type Repo struct { type Repo struct {
ID int64 `meddler:"repo_id,pk" json:"-"` ID int64 `meddler:"repo_id,pk" json:"-"`
@ -44,23 +41,7 @@ type Repo struct {
Updated int64 `meddler:"repo_updated" json:"updated_at"` Updated int64 `meddler:"repo_updated" json:"updated_at"`
} }
func NewGithub(owner, name string) (*Repo, error) { func NewRepo(remote, owner, name string) (*Repo, error) {
return New(HostGithub, owner, name)
}
func NewGithubEnterprise(owner, name string) (*Repo, error) {
return New(HostGithubEnterprise, owner, name)
}
func NewGitlab(owner, name string) (*Repo, error) {
return New(HostGitlab, owner, name)
}
func NewBitbucket(owner, name string) (*Repo, error) {
return New(HostBitbucket, owner, name)
}
func New(remote, owner, name string) (*Repo, error) {
repo := Repo{} repo := Repo{}
repo.Remote = remote repo.Remote = remote
repo.Owner = owner repo.Owner = owner

11
shared/model/status.go Normal file
View File

@ -0,0 +1,11 @@
package model
const (
StatusNone = "None"
StatusEnqueue = "Pending"
StatusStarted = "Started"
StatusSuccess = "Success"
StatusFailure = "Failure"
StatusError = "Error"
StatusKilled = "Killed"
)

View File

@ -1,7 +1,6 @@
package user package model
import ( import (
"github.com/drone/drone/server/resource/util"
"time" "time"
) )
@ -23,9 +22,9 @@ type User struct {
Synced int64 `meddler:"user_synced" json:"synced_at"` Synced int64 `meddler:"user_synced" json:"synced_at"`
} }
func New(remote, login, email string) *User { func NewUser(remote, login, email string) *User {
user := User{} user := User{}
user.Token = util.GenerateToken() user.Token = generateToken()
user.Login = login user.Login = login
user.Remote = remote user.Remote = remote
user.Active = true user.Active = true
@ -36,15 +35,15 @@ func New(remote, login, email string) *User {
// SetEmail sets the email address and calculate the Gravatar hash. // SetEmail sets the email address and calculate the Gravatar hash.
func (u *User) SetEmail(email string) { func (u *User) SetEmail(email string) {
u.Email = email u.Email = email
u.Gravatar = util.CreateGravatar(email) u.Gravatar = createGravatar(email)
} }
func (u *User) Stale() bool { func (u *User) IsStale() bool {
switch { switch {
case u.Synced == 0: case u.Synced == 0:
return true return true
// refresh every 24 hours // refresh every 24 hours
case u.Synced+expires < time.Now().Unix(): case u.Synced+DefaultExpires < time.Now().Unix():
return true return true
default: default:
return false return false
@ -53,4 +52,4 @@ func (u *User) Stale() bool {
// by default, let's expire the user // by default, let's expire the user
// cache after 72 hours // cache after 72 hours
var expires = int64(time.Hour.Seconds() * 72) var DefaultExpires = int64(time.Hour.Seconds() * 72)

48
shared/model/util.go Normal file
View File

@ -0,0 +1,48 @@
package model
import (
"crypto/md5"
"crypto/rand"
"fmt"
"io"
"strings"
)
// standard characters allowed in token string.
var chars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
// default token length
var length = 40
// generateToken generates random strings good for use in URIs to
// identify unique objects.
func generateToken() string {
b := make([]byte, length)
r := make([]byte, length+(length/4)) // storage for random bytes.
clen := byte(len(chars))
maxrb := byte(256 - (256 % len(chars)))
i := 0
for {
io.ReadFull(rand.Reader, r)
for _, c := range r {
if c >= maxrb {
// Skip this number to avoid modulo bias.
continue
}
b[i] = chars[c%clen]
i++
if i == length {
return string(b)
}
}
}
}
// helper function to create a Gravatar Hash
// for the given Email address.
func createGravatar(email string) string {
email = strings.ToLower(strings.TrimSpace(email))
hash := md5.New()
hash.Write([]byte(email))
return fmt.Sprintf("%x", hash.Sum(nil))
}