mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-12-27 02:40:30 +00:00
added token to post-commit hooks
This commit is contained in:
parent
dfb0210cf5
commit
7009778176
11 changed files with 172 additions and 13 deletions
2
Makefile
2
Makefile
|
@ -88,5 +88,5 @@ rpm:
|
|||
# DRONE_STAGING_USER -- the username used to login
|
||||
# DRONE_STAGING_KEY -- the identity file path (~/.ssh/id_rsa)
|
||||
deploy:
|
||||
scp -i $$DRONE_STAGING_KEY debian/drone.deb $$DRONE_STAGING_USER@$$DRONE_STAGING_HOST:/tmp
|
||||
scp -i $$DRONE_STAGING_KEY packaging/output/drone.deb $$DRONE_STAGING_USER@$$DRONE_STAGING_HOST:/tmp
|
||||
ssh -i $$DRONE_STAGING_KEY $$DRONE_STAGING_USER@$$DRONE_STAGING_HOST -- dpkg -i /tmp/drone.deb
|
||||
|
|
|
@ -135,7 +135,7 @@ func (r *Gitlab) Activate(user *model.User, repo *model.Repo, link string) error
|
|||
|
||||
// append the repo owner / name to the hook url since gitlab
|
||||
// doesn't send this detail in the post-commit hook
|
||||
link += "?owner=" + repo.Owner + "&name=" + repo.Name
|
||||
link += "&owner=" + repo.Owner + "&name=" + repo.Name
|
||||
|
||||
// add the hook
|
||||
return client.AddProjectHook(path, link, true, false, true)
|
||||
|
|
|
@ -37,6 +37,7 @@ func Connect(driver, datasource string) (*sql.DB, error) {
|
|||
migration.DefaultSetVersion = migrate.SetVersion
|
||||
var migrations = []migration.Migrator{
|
||||
migrate.Setup,
|
||||
migrate.Migrate_20142110,
|
||||
}
|
||||
return migration.Open(driver, datasource, migrations)
|
||||
}
|
||||
|
|
146
server/datastore/migrate/migrate.go
Normal file
146
server/datastore/migrate/migrate.go
Normal file
|
@ -0,0 +1,146 @@
|
|||
package migrate
|
||||
|
||||
import (
|
||||
"github.com/BurntSushi/migration"
|
||||
)
|
||||
|
||||
// Setup is the database migration function that
|
||||
// will setup the initial SQL database structure.
|
||||
func Setup(tx migration.LimitedTx) error {
|
||||
var stmts = []string{
|
||||
blobTable,
|
||||
userTable,
|
||||
repoTable,
|
||||
permTable,
|
||||
commitTable,
|
||||
}
|
||||
for _, stmt := range stmts {
|
||||
_, err := tx.Exec(transform(stmt))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Migrate_20142110 is a database migration on Oct-10 2014.
|
||||
func Migrate_20142110(tx migration.LimitedTx) error {
|
||||
var stmts = []string{
|
||||
commitRepoIndex, // index the commit table repo_id column
|
||||
repoTokenColumn, // add the repo token column
|
||||
repoTokenUpdate, // update the repo token column to empty string
|
||||
}
|
||||
for _, stmt := range stmts {
|
||||
_, err := tx.Exec(transform(stmt))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var userTable = `
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
user_id INTEGER PRIMARY KEY AUTOINCREMENT
|
||||
,user_remote VARCHAR(255)
|
||||
,user_login VARCHAR(255)
|
||||
,user_access VARCHAR(255)
|
||||
,user_secret VARCHAR(255)
|
||||
,user_name VARCHAR(255)
|
||||
,user_email VARCHAR(255)
|
||||
,user_gravatar VARCHAR(255)
|
||||
,user_token VARCHAR(255)
|
||||
,user_admin BOOLEAN
|
||||
,user_active BOOLEAN
|
||||
,user_syncing BOOLEAN
|
||||
,user_created INTEGER
|
||||
,user_updated INTEGER
|
||||
,user_synced INTEGER
|
||||
,UNIQUE(user_token)
|
||||
,UNIQUE(user_remote, user_login)
|
||||
);
|
||||
`
|
||||
|
||||
var permTable = `
|
||||
CREATE TABLE IF NOT EXISTS perms (
|
||||
perm_id INTEGER PRIMARY KEY AUTOINCREMENT
|
||||
,user_id INTEGER
|
||||
,repo_id INTEGER
|
||||
,perm_read BOOLEAN
|
||||
,perm_write BOOLEAN
|
||||
,perm_admin BOOLEAN
|
||||
,perm_created INTEGER
|
||||
,perm_updated INTEGER
|
||||
,UNIQUE (repo_id, user_id)
|
||||
);
|
||||
`
|
||||
|
||||
var repoTable = `
|
||||
CREATE TABLE IF NOT EXISTS repos (
|
||||
repo_id INTEGER PRIMARY KEY AUTOINCREMENT
|
||||
,user_id INTEGER
|
||||
,repo_remote VARCHAR(255)
|
||||
,repo_host VARCHAR(255)
|
||||
,repo_owner VARCHAR(255)
|
||||
,repo_name VARCHAR(255)
|
||||
,repo_url VARCHAR(1024)
|
||||
,repo_clone_url VARCHAR(255)
|
||||
,repo_git_url VARCHAR(255)
|
||||
,repo_ssh_url VARCHAR(255)
|
||||
,repo_active BOOLEAN
|
||||
,repo_private BOOLEAN
|
||||
,repo_privileged BOOLEAN
|
||||
,repo_post_commit BOOLEAN
|
||||
,repo_pull_request BOOLEAN
|
||||
,repo_public_key BLOB
|
||||
,repo_private_key BLOB
|
||||
,repo_params BLOB
|
||||
,repo_timeout INTEGER
|
||||
,repo_created INTEGER
|
||||
,repo_updated INTEGER
|
||||
,UNIQUE(repo_host, repo_owner, repo_name)
|
||||
);
|
||||
`
|
||||
|
||||
var repoTokenColumn = `
|
||||
ALTER TABLE repos ADD COLUMN repo_token VARCHAR(40)
|
||||
`
|
||||
|
||||
var repoTokenUpdate = `
|
||||
UPDATE repos SET repo_token = '';
|
||||
`
|
||||
|
||||
var commitTable = `
|
||||
CREATE TABLE IF NOT EXISTS commits (
|
||||
commit_id INTEGER PRIMARY KEY AUTOINCREMENT
|
||||
,repo_id INTEGER
|
||||
,commit_status VARCHAR(255)
|
||||
,commit_started INTEGER
|
||||
,commit_finished INTEGER
|
||||
,commit_duration INTEGER
|
||||
,commit_sha VARCHAR(255)
|
||||
,commit_branch VARCHAR(255)
|
||||
,commit_pr VARCHAR(255)
|
||||
,commit_author VARCHAR(255)
|
||||
,commit_gravatar VARCHAR(255)
|
||||
,commit_timestamp VARCHAR(255)
|
||||
,commit_message VARCHAR(255)
|
||||
,commit_yaml BLOB
|
||||
,commit_created INTEGER
|
||||
,commit_updated INTEGER
|
||||
,UNIQUE(commit_sha, commit_branch, repo_id)
|
||||
);
|
||||
`
|
||||
|
||||
var commitRepoIndex = `
|
||||
CREATE INDEX commit_repo_id_idx ON commits (repo_id);
|
||||
`
|
||||
|
||||
var blobTable = `
|
||||
CREATE TABLE IF NOT EXISTS blobs (
|
||||
blob_id INTEGER PRIMARY KEY AUTOINCREMENT
|
||||
,blob_path VARCHAR(255)
|
||||
,blob_data BLOB
|
||||
,UNIQUE(blob_path)
|
||||
);
|
||||
`
|
|
@ -1,6 +1,7 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
|
@ -24,6 +25,7 @@ import (
|
|||
func PostHook(c web.C, w http.ResponseWriter, r *http.Request) {
|
||||
var ctx = context.FromC(c)
|
||||
var host = c.URLParams["host"]
|
||||
var token = r.FormValue("token")
|
||||
var remote = remote.Lookup(host)
|
||||
if remote == nil {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
|
@ -52,6 +54,14 @@ func PostHook(c web.C, w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
// each hook contains a token to verify the sender. If the token
|
||||
// is not provided or does not match, exit
|
||||
if len(repo.Token) == 0 || repo.Token != token {
|
||||
log.Printf("Rejected post commit hook for %s. Token mismatch\n", repo.Name)
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
if repo.Active == false ||
|
||||
(repo.PostCommit == false && len(hook.PullRequest) == 0) ||
|
||||
(repo.PullRequest == false && len(hook.PullRequest) != 0) {
|
||||
|
|
|
@ -80,6 +80,7 @@ func PostRepo(c web.C, w http.ResponseWriter, r *http.Request) {
|
|||
repo.PostCommit = true
|
||||
repo.UserID = user.ID
|
||||
repo.Timeout = 3600 // default to 1 hour
|
||||
repo.Token = model.GenerateToken()
|
||||
|
||||
// generates the rsa key
|
||||
key, err := sshutil.GeneratePrivateKey()
|
||||
|
@ -98,7 +99,7 @@ func PostRepo(c web.C, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// setup the post-commit hook with the remote system and
|
||||
// if necessary, register the public key
|
||||
var hook = fmt.Sprintf("%s/api/hook/%s", httputil.GetURL(r), repo.Remote)
|
||||
var hook = fmt.Sprintf("%s/api/hook/%s?token=%s", httputil.GetURL(r), repo.Remote, repo.Token)
|
||||
if err := remote.Activate(user, repo, hook); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
|
|
|
@ -26,7 +26,7 @@ type Commit struct {
|
|||
// SetAuthor sets the author's email address and calculate the Gravatar hash.
|
||||
func (c *Commit) SetAuthor(email string) {
|
||||
c.Author = email
|
||||
c.Gravatar = createGravatar(email)
|
||||
c.Gravatar = CreateGravatar(email)
|
||||
}
|
||||
|
||||
// Returns the Short (--short) Commit Hash.
|
||||
|
|
|
@ -18,6 +18,7 @@ type RepoParams map[string]string
|
|||
type Repo struct {
|
||||
ID int64 `meddler:"repo_id,pk" json:"-"`
|
||||
UserID int64 `meddler:"user_id" json:"-"`
|
||||
Token string `meddler:"repo_token" json:"-"`
|
||||
Remote string `meddler:"repo_remote" json:"remote"`
|
||||
Host string `meddler:"repo_host" json:"host"`
|
||||
Owner string `meddler:"repo_owner" json:"owner"`
|
||||
|
|
|
@ -24,7 +24,7 @@ type User struct {
|
|||
|
||||
func NewUser(remote, login, email string) *User {
|
||||
user := User{}
|
||||
user.Token = generateToken()
|
||||
user.Token = GenerateToken()
|
||||
user.Login = login
|
||||
user.Remote = remote
|
||||
user.Active = true
|
||||
|
@ -35,7 +35,7 @@ func NewUser(remote, login, email string) *User {
|
|||
// SetEmail sets the email address and calculate the Gravatar hash.
|
||||
func (u *User) SetEmail(email string) {
|
||||
u.Email = email
|
||||
u.Gravatar = createGravatar(email)
|
||||
u.Gravatar = CreateGravatar(email)
|
||||
}
|
||||
|
||||
func (u *User) IsStale() bool {
|
||||
|
|
|
@ -14,9 +14,9 @@ var chars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567
|
|||
// default token length
|
||||
var length = 40
|
||||
|
||||
// generateToken generates random strings good for use in URIs to
|
||||
// GenerateToken generates random strings good for use in URIs to
|
||||
// identify unique objects.
|
||||
func generateToken() string {
|
||||
func GenerateToken() string {
|
||||
b := make([]byte, length)
|
||||
r := make([]byte, length+(length/4)) // storage for random bytes.
|
||||
clen := byte(len(chars))
|
||||
|
@ -40,7 +40,7 @@ func generateToken() string {
|
|||
|
||||
// helper function to create a Gravatar Hash
|
||||
// for the given Email address.
|
||||
func createGravatar(email string) string {
|
||||
func CreateGravatar(email string) string {
|
||||
email = strings.ToLower(strings.TrimSpace(email))
|
||||
hash := md5.New()
|
||||
hash.Write([]byte(email))
|
||||
|
|
|
@ -4,15 +4,15 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
func Test_createGravatar(t *testing.T) {
|
||||
var got, want = createGravatar("dr_cooper@caltech.edu"), "2b77ba83e2216ddcd11fe8c24b70c2a3"
|
||||
func Test_CreateGravatar(t *testing.T) {
|
||||
var got, want = CreateGravatar("dr_cooper@caltech.edu"), "2b77ba83e2216ddcd11fe8c24b70c2a3"
|
||||
if got != want {
|
||||
t.Errorf("Got gravatar hash %s, want %s", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_generateToken(t *testing.T) {
|
||||
token := generateToken()
|
||||
func Test_GenerateToken(t *testing.T) {
|
||||
token := GenerateToken()
|
||||
if len(token) != length {
|
||||
t.Errorf("Want token length %d, got %d", length, len(token))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue