зеркало из https://github.com/golang/build.git
131 строка
3.0 KiB
Go
131 строка
3.0 KiB
Go
// Copyright 2015 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package gerrit
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"log"
|
|
"net/http"
|
|
"net/http/cookiejar"
|
|
"net/url"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// Auth is a Gerrit authentication mode.
|
|
// The most common ones are NoAuth or BasicAuth.
|
|
type Auth interface {
|
|
setAuth(*Client, *http.Request)
|
|
}
|
|
|
|
// BasicAuth sends a username and password.
|
|
func BasicAuth(username, password string) Auth {
|
|
return basicAuth{username, password}
|
|
}
|
|
|
|
type basicAuth struct {
|
|
username, password string
|
|
}
|
|
|
|
func (ba basicAuth) setAuth(c *Client, r *http.Request) {
|
|
r.SetBasicAuth(ba.username, ba.password)
|
|
}
|
|
|
|
// GitCookiesAuth derives the Gerrit authentication token from
|
|
// gitcookies based on the URL of the Gerrit request.
|
|
func GitCookiesAuth() Auth {
|
|
return gitCookiesAuth{}
|
|
}
|
|
|
|
type gitCookiesAuth struct{}
|
|
|
|
func (gitCookiesAuth) setAuth(c *Client, r *http.Request) {
|
|
url, err := url.Parse(c.url)
|
|
if err != nil {
|
|
// Something else will complain about this.
|
|
return
|
|
}
|
|
host := url.Host
|
|
|
|
// First look in Git's http.cookiefile, which is where Gerrit
|
|
// now tells users to store this information.
|
|
git := exec.Command("git", "config", "http.cookiefile")
|
|
git.Stderr = os.Stderr
|
|
gitOut, err := git.Output()
|
|
if err != nil {
|
|
log.Printf("git config http.cookiefile failed: %s", err)
|
|
return
|
|
}
|
|
cookieFile := strings.TrimSpace(string(gitOut))
|
|
if len(cookieFile) != 0 {
|
|
// Load the cookie file.
|
|
data, _ := ioutil.ReadFile(cookieFile)
|
|
jar := parseGitCookies(string(data))
|
|
cookies := jar.Cookies(url)
|
|
if len(cookies) > 0 {
|
|
for _, cookie := range cookies {
|
|
r.AddCookie(cookie)
|
|
}
|
|
return
|
|
}
|
|
}
|
|
|
|
// If not there, then look in $HOME/.netrc, which is where Gerrit
|
|
// used to tell users to store the information, until the passwords
|
|
// got so long that old versions of curl couldn't handle them.
|
|
data, _ := ioutil.ReadFile(filepath.Join(os.Getenv("HOME"), ".netrc"))
|
|
for _, line := range strings.Split(string(data), "\n") {
|
|
if i := strings.Index(line, "#"); i >= 0 {
|
|
line = line[:i]
|
|
}
|
|
f := strings.Fields(line)
|
|
if len(f) >= 6 && f[0] == "machine" && f[1] == host && f[2] == "login" && f[4] == "password" {
|
|
r.SetBasicAuth(f[3], f[5])
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func parseGitCookies(data string) *cookiejar.Jar {
|
|
jar, _ := cookiejar.New(nil)
|
|
for _, line := range strings.Split(data, "\n") {
|
|
f := strings.Split(line, "\t")
|
|
if len(f) < 7 {
|
|
continue
|
|
}
|
|
expires, err := strconv.ParseInt(f[4], 10, 64)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
c := http.Cookie{
|
|
Domain: f[0],
|
|
Path: f[2],
|
|
Secure: f[3] == "TRUE",
|
|
Expires: time.Unix(expires, 0),
|
|
Name: f[5],
|
|
Value: f[6],
|
|
}
|
|
// Construct a fake URL to add c to the jar.
|
|
url := url.URL{
|
|
Scheme: "http",
|
|
Host: c.Domain,
|
|
Path: c.Path,
|
|
}
|
|
jar.SetCookies(&url, []*http.Cookie{&c})
|
|
}
|
|
return jar
|
|
}
|
|
|
|
// NoAuth makes requests unauthenticated.
|
|
var NoAuth = noAuth{}
|
|
|
|
type noAuth struct{}
|
|
|
|
func (noAuth) setAuth(c *Client, r *http.Request) {}
|