moved to single binary project structure

This commit is contained in:
Brad Rydzewski
2015-09-29 17:53:21 -07:00
parent 76ea19aca0
commit 155576fb03
139 changed files with 0 additions and 9815 deletions

58
shared/ccmenu/ccmenu.go Normal file
View File

@@ -0,0 +1,58 @@
package ccmenu
import (
"encoding/xml"
"strconv"
"time"
"github.com/drone/drone/pkg/types"
)
type CCProjects struct {
XMLName xml.Name `xml:"Projects"`
Project *CCProject `xml:"Project"`
}
type CCProject struct {
XMLName xml.Name `xml:"Project"`
Name string `xml:"name,attr"`
Activity string `xml:"activity,attr"`
LastBuildStatus string `xml:"lastBuildStatus,attr"`
LastBuildLabel string `xml:"lastBuildLabel,attr"`
LastBuildTime string `xml:"lastBuildTime,attr"`
WebURL string `xml:"webUrl,attr"`
}
func NewCC(r *types.Repo, b *types.Build) *CCProjects {
proj := &CCProject{
Name: r.Owner + "/" + r.Name,
WebURL: r.Self,
Activity: "Building",
LastBuildStatus: "Unknown",
LastBuildLabel: "Unknown",
}
// if the build is not currently running then
// we can return the latest build status.
if b.Status != types.StatePending &&
b.Status != types.StateRunning {
proj.Activity = "Sleeping"
proj.LastBuildTime = time.Unix(b.Started, 0).Format(time.RFC3339)
proj.LastBuildLabel = strconv.Itoa(b.Number)
}
// ensure the last build state accepts a valid
// ccmenu enumeration
switch b.Status {
case types.StateError, types.StateKilled:
proj.LastBuildStatus = "Exception"
case types.StateSuccess:
proj.LastBuildStatus = "Success"
case types.StateFailure:
proj.LastBuildStatus = "Failure"
default:
proj.LastBuildStatus = "Unknown"
}
return &CCProjects{Project: proj}
}

View File

@@ -0,0 +1,72 @@
package sshutil
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"hash"
"github.com/drone/drone/Godeps/_workspace/src/code.google.com/p/go.crypto/ssh"
)
const (
RSA_BITS = 2048 // Default number of bits in an RSA key
RSA_BITS_MIN = 768 // Minimum number of bits in an RSA key
)
// helper function to generate an RSA Private Key.
func GeneratePrivateKey() (*rsa.PrivateKey, error) {
return rsa.GenerateKey(rand.Reader, RSA_BITS)
}
// helper function that marshalls an RSA Public Key to an SSH
// .authorized_keys format
func MarshalPublicKey(pubkey *rsa.PublicKey) []byte {
pk, err := ssh.NewPublicKey(pubkey)
if err != nil {
return []byte{}
}
return ssh.MarshalAuthorizedKey(pk)
}
// helper function that marshalls an RSA Private Key to
// a PEM encoded file.
func MarshalPrivateKey(privkey *rsa.PrivateKey) []byte {
privateKeyMarshaled := x509.MarshalPKCS1PrivateKey(privkey)
privateKeyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Headers: nil, Bytes: privateKeyMarshaled})
return privateKeyPEM
}
// UnMarshalPrivateKey is a helper function that unmarshals a PEM
// bytes to an RSA Private Key
func UnMarshalPrivateKey(privateKeyPEM []byte) *rsa.PrivateKey {
derBlock, _ := pem.Decode(privateKeyPEM)
privateKey, err := x509.ParsePKCS1PrivateKey(derBlock.Bytes)
if err != nil {
return nil
}
return privateKey
}
// Encrypt is helper function to encrypt a plain-text string using
// an RSA public key.
func Encrypt(hash hash.Hash, pubkey *rsa.PublicKey, msg string) (string, error) {
src, err := rsa.EncryptOAEP(hash, rand.Reader, pubkey, []byte(msg), nil)
return base64.RawURLEncoding.EncodeToString(src), err
}
// Decrypt is helper function to encrypt a plain-text string using
// an RSA public key.
func Decrypt(hash hash.Hash, privkey *rsa.PrivateKey, secret string) (string, error) {
decoded, err := base64.RawURLEncoding.DecodeString(secret)
if err != nil {
return "", err
}
out, err := rsa.DecryptOAEP(hash, rand.Reader, privkey, decoded, nil)
return string(out), err
}

View File

@@ -0,0 +1,40 @@
package sshutil
import (
"crypto/sha256"
"testing"
"github.com/drone/drone/Godeps/_workspace/src/github.com/franela/goblin"
)
func TestSSHUtil(t *testing.T) {
g := goblin.Goblin(t)
g.Describe("sshutil", func() {
var encrypted, testMsg string
privkey, err := GeneratePrivateKey()
g.Assert(err == nil).IsTrue()
pubkey := privkey.PublicKey
sha256 := sha256.New()
testMsg = "foo=bar"
g.Before(func() {
encrypted, err = Encrypt(sha256, &pubkey, testMsg)
g.Assert(err == nil).IsTrue()
})
g.It("Can decrypt encrypted msg", func() {
decrypted, err := Decrypt(sha256, privkey, encrypted)
g.Assert(err == nil).IsTrue()
g.Assert(decrypted == testMsg).IsTrue()
})
g.It("Unmarshals private key from PEM block", func() {
privateKeyPEM := MarshalPrivateKey(privkey)
privateKey := UnMarshalPrivateKey(privateKeyPEM)
g.Assert(privateKey.PublicKey.E == pubkey.E).IsTrue()
})
})
}

124
shared/docker/copy.go Normal file
View File

@@ -0,0 +1,124 @@
package docker
import (
"encoding/binary"
"errors"
"io"
)
const (
StdWriterPrefixLen = 8
StdWriterFdIndex = 0
StdWriterSizeIndex = 4
)
type StdType [StdWriterPrefixLen]byte
var (
Stdin StdType = StdType{0: 0}
Stdout StdType = StdType{0: 1}
Stderr StdType = StdType{0: 2}
)
type StdWriter struct {
io.Writer
prefix StdType
sizeBuf []byte
}
var ErrInvalidStdHeader = errors.New("Unrecognized input header")
// StdCopy is a modified version of io.Copy.
//
// StdCopy will demultiplex `src`, assuming that it contains two streams,
// previously multiplexed together using a StdWriter instance.
// As it reads from `src`, StdCopy will write to `dstout` and `dsterr`.
//
// StdCopy will read until it hits EOF on `src`. It will then return a nil error.
// In other words: if `err` is non nil, it indicates a real underlying error.
//
// `written` will hold the total number of bytes written to `dstout` and `dsterr`.
func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, err error) {
var (
buf = make([]byte, 32*1024+StdWriterPrefixLen+1)
bufLen = len(buf)
nr, nw int
er, ew error
out io.Writer
frameSize int
)
for {
// Make sure we have at least a full header
for nr < StdWriterPrefixLen {
var nr2 int
nr2, er = src.Read(buf[nr:])
nr += nr2
if er == io.EOF {
if nr < StdWriterPrefixLen {
return written, nil
}
break
}
if er != nil {
return 0, er
}
}
// Check the first byte to know where to write
switch buf[StdWriterFdIndex] {
case 0:
fallthrough
case 1:
// Write on stdout
out = dstout
case 2:
// Write on stderr
out = dsterr
default:
return 0, ErrInvalidStdHeader
}
// Retrieve the size of the frame
frameSize = int(binary.BigEndian.Uint32(buf[StdWriterSizeIndex : StdWriterSizeIndex+4]))
// Check if the buffer is big enough to read the frame.
// Extend it if necessary.
if frameSize+StdWriterPrefixLen > bufLen {
buf = append(buf, make([]byte, frameSize+StdWriterPrefixLen-bufLen+1)...)
bufLen = len(buf)
}
// While the amount of bytes read is less than the size of the frame + header, we keep reading
for nr < frameSize+StdWriterPrefixLen {
var nr2 int
nr2, er = src.Read(buf[nr:])
nr += nr2
if er == io.EOF {
if nr < frameSize+StdWriterPrefixLen {
return written, nil
}
break
}
if er != nil {
return 0, er
}
}
// Write the retrieved frame (without header)
nw, ew = out.Write(buf[StdWriterPrefixLen : frameSize+StdWriterPrefixLen])
if ew != nil {
return 0, ew
}
// If the frame has not been fully written: error
if nw != frameSize {
return 0, io.ErrShortWrite
}
written += int64(nw)
// Move the rest of the buffer to the beginning
copy(buf, buf[frameSize+StdWriterPrefixLen:])
// Move the index
nr -= frameSize + StdWriterPrefixLen
}
}

111
shared/httputil/httputil.go Normal file
View File

@@ -0,0 +1,111 @@
package httputil
import (
"net/http"
"strings"
)
// IsHttps is a helper function that evaluates the http.Request
// and returns True if the Request uses HTTPS. It is able to detect,
// using the X-Forwarded-Proto, if the original request was HTTPS and
// routed through a reverse proxy with SSL termination.
func IsHttps(r *http.Request) bool {
switch {
case r.URL.Scheme == "https":
return true
case r.TLS != nil:
return true
case strings.HasPrefix(r.Proto, "HTTPS"):
return true
case r.Header.Get("X-Forwarded-Proto") == "https":
return true
default:
return false
}
}
// GetScheme is a helper function that evaluates the http.Request
// and returns the scheme, HTTP or HTTPS. It is able to detect,
// using the X-Forwarded-Proto, if the original request was HTTPS
// and routed through a reverse proxy with SSL termination.
func GetScheme(r *http.Request) string {
switch {
case r.URL.Scheme == "https":
return "https"
case r.TLS != nil:
return "https"
case strings.HasPrefix(r.Proto, "HTTPS"):
return "https"
case r.Header.Get("X-Forwarded-Proto") == "https":
return "https"
default:
return "http"
}
}
// GetHost is a helper function that evaluates the http.Request
// and returns the hostname. It is able to detect, using the
// X-Forarded-For header, the original hostname when routed
// through a reverse proxy.
func GetHost(r *http.Request) string {
switch {
case len(r.Host) != 0:
return r.Host
case len(r.URL.Host) != 0:
return r.URL.Host
case len(r.Header.Get("X-Forwarded-For")) != 0:
return r.Header.Get("X-Forwarded-For")
case len(r.Header.Get("X-Host")) != 0:
return r.Header.Get("X-Host")
case len(r.Header.Get("XFF")) != 0:
return r.Header.Get("XFF")
case len(r.Header.Get("X-Real-IP")) != 0:
return r.Header.Get("X-Real-IP")
default:
return "localhost:8080"
}
}
// GetURL is a helper function that evaluates the http.Request
// and returns the URL as a string. Only the scheme + hostname
// are included; the path is excluded.
func GetURL(r *http.Request) string {
return GetScheme(r) + "://" + GetHost(r)
}
// GetCookie retrieves and verifies the cookie value.
func GetCookie(r *http.Request, name string) (value string) {
cookie, err := r.Cookie(name)
if err != nil {
return
}
value = cookie.Value
return
}
// SetCookie writes the cookie value.
func SetCookie(w http.ResponseWriter, r *http.Request, name, value string) {
cookie := http.Cookie{
Name: name,
Value: value,
Path: "/",
Domain: r.URL.Host,
HttpOnly: true,
Secure: IsHttps(r),
}
http.SetCookie(w, &cookie)
}
// DelCookie deletes a cookie.
func DelCookie(w http.ResponseWriter, r *http.Request, name string) {
cookie := http.Cookie{
Name: name,
Value: "deleted",
Path: "/",
Domain: r.URL.Host,
MaxAge: -1,
}
http.SetCookie(w, &cookie)
}

98
shared/token/token.go Normal file
View File

@@ -0,0 +1,98 @@
package token
import (
"net/http"
"github.com/drone/drone/Godeps/_workspace/src/github.com/dgrijalva/jwt-go"
)
type SecretFunc func(*Token) (string, error)
const (
UserToken = "user"
SessToken = "sess"
HookToken = "hook"
)
// Default algorithm used to sign JWT tokens.
const SignerAlgo = "HS256"
type Token struct {
Kind string
Text string
}
// Parse parses
func Parse(raw string, fn SecretFunc) (*Token, error) {
token := &Token{}
parsed, err := jwt.Parse(raw, keyFunc(token, fn))
if err != nil {
return nil, err
} else if !parsed.Valid {
return nil, jwt.ValidationError{}
}
return token, nil
}
func ParseRequest(req *http.Request, fn SecretFunc) (*Token, error) {
token := &Token{}
parsed, err := jwt.ParseFromRequest(req, keyFunc(token, fn))
if err != nil {
return nil, err
} else if !parsed.Valid {
return nil, jwt.ValidationError{}
}
return token, nil
}
func New(kind, text string) *Token {
return &Token{Kind: kind, Text: text}
}
// Sign signs the token using the given secret hash
// and returns the string value.
func (t *Token) Sign(secret string) (string, error) {
return t.SignExpires(secret, 0)
}
// Sign signs the token using the given secret hash
// with an expiration date.
func (t *Token) SignExpires(secret string, exp int64) (string, error) {
token := jwt.New(jwt.SigningMethodHS256)
token.Claims["type"] = t.Kind
token.Claims["text"] = t.Text
if exp > 0 {
token.Claims["exp"] = float64(exp)
}
return token.SignedString([]byte(secret))
}
func keyFunc(token *Token, fn SecretFunc) jwt.Keyfunc {
return func(t *jwt.Token) (interface{}, error) {
// validate the correct algorithm is being used
if t.Method.Alg() != SignerAlgo {
return nil, jwt.ErrSignatureInvalid
}
// extract the token kind and cast to
// the expected type.
kindv, ok := t.Claims["type"]
if !ok {
return nil, jwt.ValidationError{}
}
token.Kind, _ = kindv.(string)
// extract the token value and cast to
// exepected type.
textv, ok := t.Claims["text"]
if !ok {
return nil, jwt.ValidationError{}
}
token.Text, _ = textv.(string)
// invoke the callback function to retrieve
// the secret key used to verify
secret, err := fn(token)
return []byte(secret), err
}
}

View File

@@ -0,0 +1 @@
package token