Commit e5673020 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 71f620be
...@@ -73,7 +73,28 @@ func NewAuthCache(u *upstream) *AuthCache { ...@@ -73,7 +73,28 @@ func NewAuthCache(u *upstream) *AuthCache {
// Verify that download access is ok or not. // Verify that download access is ok or not.
// first we try to use the cache; if information is not there -> ask auth backend // first we try to use the cache; if information is not there -> ask auth backend
// download is ok if AuthReply.RepoPath != "" // download is ok if AuthReply.RepoPath != ""
func (c *AuthCache) VerifyDownloadAccess(key AuthCacheKey) AuthReply { func (c *AuthCache) VerifyDownloadAccess(project string, query url.Values, header http.Header) AuthReply {
// Use only tokens from query/header to minimize cache and avoid
// creating redundant cache entries because of e.g. unrelated headers.
q := url.Values{}
for k, v := range query {
if strings.HasSuffix(k, "_token") {
q[k] = v
}
}
h := url.Values{}
for k, v := range header {
if strings.HasSuffix(strings.ToUpper(k), "-TOKEN") {
h[k] = v
}
}
key := AuthCacheKey{project, q.Encode(), h.Encode()}
return c.verifyDownloadAccess(key)
}
func (c *AuthCache) verifyDownloadAccess(key AuthCacheKey) AuthReply {
var authReply AuthReply var authReply AuthReply
// first try to read from cache in parallel with other readers // first try to read from cache in parallel with other readers
...@@ -166,6 +187,7 @@ func (c *AuthCache) refreshEntry(auth *AuthCacheEntry, key AuthCacheKey) { ...@@ -166,6 +187,7 @@ func (c *AuthCache) refreshEntry(auth *AuthCacheEntry, key AuthCacheKey) {
} }
} }
// Ask auth backend about cache key
func (c *AuthCache) askAuthBackend(key AuthCacheKey) AuthReply { func (c *AuthCache) askAuthBackend(key AuthCacheKey) AuthReply {
// key.header -> url.Values -> http.Header // key.header -> url.Values -> http.Header
hv, err := url.ParseQuery(key.header) hv, err := url.ParseQuery(key.header)
...@@ -226,8 +248,8 @@ func askAuthBackend(u *upstream, project, query string, header *http.Header) Aut ...@@ -226,8 +248,8 @@ func askAuthBackend(u *upstream, project, query string, header *http.Header) Aut
return authReply return authReply
} }
func verifyDownloadAccess(u *upstream, project, query string, header string) AuthReply { func verifyDownloadAccess(u *upstream, project string, query url.Values, header http.Header) AuthReply {
return u.authCache.VerifyDownloadAccess(AuthCacheKey{project, query, header}) return u.authCache.VerifyDownloadAccess(project, query, header)
} }
// HTTP handler for `.../raw/<ref>/path` // HTTP handler for `.../raw/<ref>/path`
...@@ -236,7 +258,7 @@ var rawRe = regexp.MustCompile(`/raw/`) ...@@ -236,7 +258,7 @@ var rawRe = regexp.MustCompile(`/raw/`)
func handleGetBlobRaw(w http.ResponseWriter, r *gitRequest) { func handleGetBlobRaw(w http.ResponseWriter, r *gitRequest) {
// Extract project & refpath // Extract project & refpath
// <project>/raw/branch/file -> <project>, branch/file // <project>/raw/branch/file -> <project>, branch/file
u := r.Request.URL // XXX naming u := r.Request.URL
rawLoc := rawRe.FindStringIndex(u.Path) rawLoc := rawRe.FindStringIndex(u.Path)
if rawLoc == nil { if rawLoc == nil {
fail500(w, errors.New("extract project name")) fail500(w, errors.New("extract project name"))
...@@ -245,26 +267,8 @@ func handleGetBlobRaw(w http.ResponseWriter, r *gitRequest) { ...@@ -245,26 +267,8 @@ func handleGetBlobRaw(w http.ResponseWriter, r *gitRequest) {
project := u.Path[:rawLoc[0]] project := u.Path[:rawLoc[0]]
refpath := u.Path[rawLoc[1]:] refpath := u.Path[rawLoc[1]:]
// XXX should be in cache
// Extract only tokens from query
query := url.Values{}
for k, v := range u.Query() {
if strings.HasSuffix(k, "_token") {
query[k] = v
}
}
// XXX should be in cache
// Extract only token headers
header := url.Values{}
for k, v := range r.Request.Header {
if strings.HasSuffix(strings.ToUpper(k), "-TOKEN") {
header[k] = v
}
}
// Query download access auth for this project // Query download access auth for this project
authReply := verifyDownloadAccess(r.u, project, query.Encode(), header.Encode()) authReply := verifyDownloadAccess(r.u, project, u.Query(), r.Request.Header)
if authReply.RepoPath == "" { if authReply.RepoPath == "" {
// access denied - copy auth reply to client in full - // access denied - copy auth reply to client in full -
// there are HTTP code and other headers / body relevant for // there are HTTP code and other headers / body relevant for
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment