approve the credentials if the request succeeds, or reject them

This commit is contained in:
risk danger olson 2013-11-01 18:54:33 -06:00 committed by Rick Olson
parent 0074d2ffeb
commit e8de7a3b82
2 changed files with 33 additions and 14 deletions

@ -23,7 +23,7 @@ func Put(filename string) error {
return err return err
} }
req, _, err := clientRequest("PUT", oid) req, creds, err := clientRequest("PUT", oid)
if err != nil { if err != nil {
return err return err
} }
@ -31,7 +31,7 @@ func Put(filename string) error {
req.Body = file req.Body = file
req.ContentLength = stat.Size() req.ContentLength = stat.Size()
res, err := doRequest(req) res, err := doRequest(req, creds)
if err != nil { if err != nil {
return err return err
} }
@ -43,13 +43,13 @@ func Put(filename string) error {
func Get(filename string) (io.ReadCloser, error) { func Get(filename string) (io.ReadCloser, error) {
oid := filepath.Base(filename) oid := filepath.Base(filename)
if stat, err := os.Stat(filename); err != nil || stat == nil { if stat, err := os.Stat(filename); err != nil || stat == nil {
req, _, err := clientRequest("GET", oid) req, creds, err := clientRequest("GET", oid)
if err != nil { if err != nil {
return nil, err return nil, err
} }
req.Header.Set("Accept", "application/vnd.git-media") req.Header.Set("Accept", "application/vnd.git-media")
res, err := doRequest(req) res, err := doRequest(req, creds)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -60,13 +60,15 @@ func Get(filename string) (io.ReadCloser, error) {
return os.Open(filename) return os.Open(filename)
} }
func doRequest(req *http.Request) (*http.Response, error) { func doRequest(req *http.Request, creds Creds) (*http.Response, error) {
res, err := http.DefaultClient.Do(req) res, err := http.DefaultClient.Do(req)
if err == nil { if err == nil {
defer res.Body.Close() defer res.Body.Close()
if res.StatusCode > 299 { if res.StatusCode > 299 {
execCreds(creds, "reject")
apierr := &Error{} apierr := &Error{}
dec := json.NewDecoder(res.Body) dec := json.NewDecoder(res.Body)
if err := dec.Decode(apierr); err != nil { if err := dec.Decode(apierr); err != nil {
@ -75,12 +77,14 @@ func doRequest(req *http.Request) (*http.Response, error) {
return res, apierr return res, apierr
} }
} else {
execCreds(creds, "approve")
} }
return res, err return res, err
} }
func clientRequest(method, oid string) (*http.Request, map[string]string, error) { func clientRequest(method, oid string) (*http.Request, Creds, error) {
u := objectUrl(oid) u := objectUrl(oid)
req, err := http.NewRequest(method, u.String(), nil) req, err := http.NewRequest(method, u.String(), nil)
if err == nil { if err == nil {

@ -8,16 +8,16 @@ import (
"strings" "strings"
) )
func credentials(u *url.URL) (map[string]string, error) { func credentials(u *url.URL) (Creds, error) {
credInput := fmt.Sprintf("protocol=%s\nhost=%s\n", u.Scheme, u.Host) creds := Creds{"protocol": u.Scheme, "host": u.Host}
cmd, err := execCreds(credInput, "fill") cmd, err := execCreds(creds, "fill")
if err != nil { if err != nil {
return nil, err return nil, err
} }
return cmd.Credentials(), nil return cmd.Credentials(), nil
} }
func execCreds(input, subCommand string) (*CredentialCmd, error) { func execCreds(input Creds, subCommand string) (*CredentialCmd, error) {
cmd := NewCommand(input, subCommand) cmd := NewCommand(input, subCommand)
err := cmd.Start() err := cmd.Start()
if err == nil { if err == nil {
@ -38,11 +38,11 @@ type CredentialCmd struct {
*exec.Cmd *exec.Cmd
} }
func NewCommand(input, subCommand string) *CredentialCmd { func NewCommand(input Creds, subCommand string) *CredentialCmd {
buf1 := new(bytes.Buffer) buf1 := new(bytes.Buffer)
buf2 := new(bytes.Buffer) buf2 := new(bytes.Buffer)
cmd := exec.Command("git", "credential", subCommand) cmd := exec.Command("git", "credential", subCommand)
cmd.Stdin = bytes.NewBufferString(input) cmd.Stdin = input.Buffer()
cmd.Stdout = buf1 cmd.Stdout = buf1
cmd.Stderr = buf2 cmd.Stderr = buf2
return &CredentialCmd{buf1, buf2, subCommand, cmd} return &CredentialCmd{buf1, buf2, subCommand, cmd}
@ -56,8 +56,8 @@ func (c *CredentialCmd) StdoutString() string {
return c.output.String() return c.output.String()
} }
func (c *CredentialCmd) Credentials() map[string]string { func (c *CredentialCmd) Credentials() Creds {
creds := make(map[string]string) creds := make(Creds)
for _, line := range strings.Split(c.StdoutString(), "\n") { for _, line := range strings.Split(c.StdoutString(), "\n") {
pieces := strings.SplitN(line, "=", 2) pieces := strings.SplitN(line, "=", 2)
@ -69,3 +69,18 @@ func (c *CredentialCmd) Credentials() map[string]string {
return creds return creds
} }
type Creds map[string]string
func (c Creds) Buffer() *bytes.Buffer {
buf := new(bytes.Buffer)
for k, v := range c {
buf.Write([]byte(k))
buf.Write([]byte("="))
buf.Write([]byte(v))
buf.Write([]byte("\n"))
}
return buf
}