go: Parse the TempAuth config

This is needed because we have a test cluster behind a proxy that
terminates SSL. May come useful to someone who uses TempAuth in
general.

Change-Id: I3feac186c3fc8d2c804e490745969e0613ad2382
This commit is contained in:
Pete Zaitcev
2016-09-02 23:50:00 -06:00
parent 1576fe3286
commit 4dc15f04f2
2 changed files with 58 additions and 14 deletions

View File

@@ -103,7 +103,7 @@ func (server *ProxyServer) GetHandler(config hummingbird.Config) http.Handler {
server.LogRequest, server.LogRequest,
middleware.ValidateRequest, middleware.ValidateRequest,
NewProxyContextMiddleware(server.mc, server.C), NewProxyContextMiddleware(server.mc, server.C),
NewTempAuth(server.mc), NewTempAuth(server.mc, config),
).Then(router) ).Then(router)
} }

View File

@@ -30,6 +30,7 @@ type testUser struct {
Username string Username string
Password string Password string
Roles []string Roles []string
Url string
} }
type TempAuth struct { type TempAuth struct {
@@ -38,16 +39,55 @@ type TempAuth struct {
next http.Handler next http.Handler
} }
func NewTempAuth(mc hummingbird.MemcacheRing) func(http.Handler) http.Handler { func NewTempAuth(mc hummingbird.MemcacheRing, config hummingbird.Config) func(http.Handler) http.Handler {
var users []testUser
// Hardcoding "tempauth" is incorrect. The actual name of the section
// is determined by the entry in the pipeline= in [pipeline:main]. XXX
section := "filter:tempauth"
if config.HasSection(section) {
users = []testUser{}
for key, val := range config.File[section] {
keyparts := strings.Split(key, "_")
valparts := strings.Fields(val)
if len(keyparts) != 3 || keyparts[0] != "user" {
// egg specification and other configuration
continue
}
vallen := len(valparts)
if vallen < 1 {
continue
}
url := ""
groups := []string{}
if vallen > 1 {
urlSpot := 0
s := valparts[vallen-1]
if strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://") {
urlSpot = 1
url = s
}
for _, group := range valparts[1:vallen-urlSpot] {
groups = append(groups, group)
}
}
user := testUser{keyparts[1], keyparts[2], valparts[0], groups, url}
users = append(users, user)
}
} else {
// Swift would traceback in case of a missing section, but
// traditional Hummingbird uses a hardcoded tempauth. Always.
// [XXX isn't it a very bad idea in a public cloud?]
users = []testUser{
{"admin", "admin", "admin", []string{".admin", ".reseller_admin"}, ""},
{"test", "tester", "testing", []string{".admin"}, ""},
{"test2", "tester2", "testing2", []string{".admin"}, ""},
{"test2", "tester2", "testing2", []string{".admin"}, ""},
{"test", "tester3", "testing3", []string{}, ""},
}
}
tempAuth := &TempAuth{ tempAuth := &TempAuth{
mc: mc, mc: mc,
testUsers: []testUser{ testUsers: users,
{"admin", "admin", "admin", []string{".admin", ".reseller_admin"}},
{"test", "tester", "testing", []string{".admin"}},
{"test2", "tester2", "testing2", []string{".admin"}},
{"test2", "tester2", "testing2", []string{".admin"}},
{"test", "tester3", "testing3", []string{}},
},
} }
return tempAuth.getMiddleware return tempAuth.getMiddleware
} }
@@ -57,15 +97,15 @@ func (ta *TempAuth) getMiddleware(next http.Handler) http.Handler {
return ta return ta
} }
func (ta *TempAuth) login(account, user, key string) (string, error) { func (ta *TempAuth) login(account, user, key string) (string, string, error) {
for _, tu := range ta.testUsers { for _, tu := range ta.testUsers {
if tu.Account == account && tu.Username == user && tu.Password == key { if tu.Account == account && tu.Username == user && tu.Password == key {
token := hummingbird.UUID() token := hummingbird.UUID()
ta.mc.Set(token, true, 3600) ta.mc.Set(token, true, 3600)
return token, nil return token, tu.Url, nil
} }
} }
return "", errors.New("User not found.") return "", "", errors.New("User not found.")
} }
func (ta *TempAuth) createAccount(account string) bool { func (ta *TempAuth) createAccount(account string) bool {
@@ -90,14 +130,18 @@ func (ta *TempAuth) ServeHTTP(writer http.ResponseWriter, request *http.Request)
account := parts[0] account := parts[0]
user = parts[1] user = parts[1]
password := request.Header.Get("X-Auth-Key") password := request.Header.Get("X-Auth-Key")
token, err := ta.login(account, user, password) token, url, err := ta.login(account, user, password)
if err != nil { if err != nil {
hummingbird.StandardResponse(writer, 401) hummingbird.StandardResponse(writer, 401)
return return
} }
writer.Header().Set("X-Storage-Token", token) writer.Header().Set("X-Storage-Token", token)
writer.Header().Set("X-Auth-Token", token) writer.Header().Set("X-Auth-Token", token)
if url != "" {
writer.Header().Set("X-Storage-URL", url)
} else {
writer.Header().Set("X-Storage-URL", fmt.Sprintf("http://%s/v1/AUTH_%s", request.Host, account)) writer.Header().Set("X-Storage-URL", fmt.Sprintf("http://%s/v1/AUTH_%s", request.Host, account))
}
hummingbird.StandardResponse(writer, 200) hummingbird.StandardResponse(writer, 200)
} else { } else {
token := request.Header.Get("X-Auth-Token") token := request.Header.Get("X-Auth-Token")