Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-workhorse
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kirill Smelkov
gitlab-workhorse
Commits
dabcc517
Commit
dabcc517
authored
Nov 27, 2015
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
X auth refreshing draftly works
parent
d528e25c
Pipeline
#113
failed with stage
Changes
2
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
77 additions
and
54 deletions
+77
-54
authorization.go
authorization.go
+0
-2
blob.go
blob.go
+77
-52
No files found.
authorization.go
View file @
dabcc517
...
...
@@ -51,8 +51,6 @@ func preAuthorizeHandler(handleFunc serviceHandleFunc, suffix string) serviceHan
// The auth backend validated the client request and told us additional
// request metadata. We must extract this information from the auth
// response body.
//log.Printf("resp body: %s", authResponse.Body)
//io.Copy(os.Stdout, authResponse.Body)
if
err
:=
json
.
NewDecoder
(
authResponse
.
Body
)
.
Decode
(
&
r
.
authorizationResponse
);
err
!=
nil
{
fail500
(
w
,
"decode authorization response"
,
err
)
return
...
...
blob.go
View file @
dabcc517
...
...
@@ -2,6 +2,17 @@
Handler for raw blob downloads
*/
/*
Cache-Control: private
ETag: "4c10677531b44f555ebbdaff24a9b2d6"
X-Content-Type-Options: nosniff
Content-Disposition: inline
Content-Transfer-Encoding: binary
Content-Type: text/plain; charset=utf-8
*/
package
main
import
(
...
...
@@ -12,85 +23,96 @@ import (
"strings"
"regexp"
"net/http"
"net/http/httptest"
)
/*
Cache-Control: private
ETag: "4c10677531b44f555ebbdaff24a9b2d6"
X-Content-Type-Options: nosniff
Content-Disposition: inline
Content-Transfer-Encoding: binary
// auth backend reply
type
backendAuthReply
struct
{
w
*
httptest
.
ResponseRecorder
// output of backend/preAuthorizeHandler
authorizationResponse
}
Content-Type: text/plain; charset=utf-8
*/
// ask auth backend whether download is ok for project
func
askAuthBackend
(
u
*
upstream
,
project
string
)
backendAuthReply
{
authReply
:=
backendAuthReply
{
w
:
httptest
.
NewRecorder
(),
}
// request to verify whether download is possible via asking as git fetch would do
// XXX privateToken not propagated, etc ...
reqDownloadAccess
,
err
:=
http
.
NewRequest
(
"GET"
,
project
+
".git/info/refs?service=git-upload-pack"
,
nil
)
if
err
!=
nil
{
fail500
(
authReply
.
w
,
"GET git-upload-pack"
,
err
)
//return false // XXX not cache as it is just we cannot create request
return
authReply
}
func
blobPreAuthorizeHandler
(
handleFunc
serviceHandleFunc
)
serviceHandleFunc
{
return
func
(
w
http
.
ResponseWriter
,
r
*
gitRequest
)
{
// swap original request to 'verify-download' one XXX "swap" not correct
r
:=
&
gitRequest
{
Request
:
reqDownloadAccess
,
u
:
u
,
}
// downloadOk := false
preAuthorizeHandler
(
func
(
w
http
.
ResponseWriter
,
r
*
gitRequest
)
{
// if we ever get to this point - auth handler approved
// access and thus it is ok to download
// downloadOk = true
},
""
)
(
authReply
.
w
,
r
)
return
authReply
}
// authorization info, as replied by authBackend for a request
type
authInfo
struct
{
authResponse
authorizationResponse
authReply
backendAuthReply
// XXX no need?
Tauth
int64
// in seconds
Naccess
int64
}
// project -> authInfo
// FIXME
it have to
be not only project (privateToken etc...)
var
authCache
=
make
(
map
[
string
]
authInfo
)
//
{}
project -> authInfo
// FIXME
should
be not only project (privateToken etc...)
var
authCache
=
make
(
map
[
string
]
*
authInfo
)
const
authCacheRefresh
=
30
// in seconds
const
authCacheRefresh
=
10
*
time
.
Second
// XXX -> 30
// refresh cache entry periodically while it is used
// refresh
auth
cache entry periodically while it is used
// if the entry is detected to be not used - remove it from cache and stop rereshing
func
authRefresh
(
u
*
upstream
,
project
string
)
{
for
;;
{
log
.
Printf
(
"AUTH refresh sleep ..."
)
time
.
Sleep
(
authCacheRefresh
)
// XXX lock?
auth
,
ok
:=
authCache
[
project
]
if
!
ok
{
// someone removed the entry from cache - no
log
.
Printf
(
"AUTH refresh - %v entry removed"
,
project
)
break
// need to further refresh XXX ok?
}
log
.
Printf
(
"AUTH refresh - %v Naccess: %v"
,
project
,
auth
.
Naccess
)
if
auth
.
Naccess
==
0
{
// not used - we can remove and stop refreshing
// XXX lock?
delete
(
authCache
,
project
)
break
}
askAuthBackend
(
u
,
project
)
}
}
// ask auth backend whether download is ok for project
func
askAuthBackend
(
u
*
upstream
,
project
string
)
authorizationResponse
{
// request to verify whether download is possible via asking as git fetch would do
// XXX privateToken not propagated, etc ...
reqDownloadAccess
,
err
:=
http
.
NewRequest
(
"GET"
,
project
+
".git/info/refs?service=git-upload-pack"
,
nil
)
if
err
!=
nil
{
fail500
(
w
,
"GET git-upload-pack"
,
err
)
return
false
// XXX not cache as it is just we cannot create request
}
log
.
Printf
(
"AUTH - refreshing %v"
,
project
)
authReply
:=
askAuthBackend
(
u
,
project
)
// swap original request to 'verify-download' one
//requestBlob := r.Request
r
:=
&
gitRequest
{
Request
:
reqDownloadAccess
,
u
:
u
,
// XXX lock ?
auth
.
authReply
=
authReply
auth
.
Tauth
=
time
.
Now
()
.
Unix
()
auth
.
Naccess
=
0
}
// downloadOk := false
preAuthorizeHandler
(
func
(
w
http
.
ResponseWriter
,
r
*
gitRequest
)
{
// if we ever get to this point - auth handler approved
// access and thus it is ok to download
// downloadOk = true
},
""
)
(
w
,
r
)
return
r
.
authorizationResponse
}
...
...
@@ -99,18 +121,21 @@ func verifyDownloadAccess(w http.ResponseWriter, r *gitRequest, project string)
// XXX do we need mutex to lock authCache ?
auth
,
ok
:=
authCache
[
project
]
if
ok
{
log
.
Printf
(
"downloadOk cached %v ago: %v"
,
auth
.
Naccess
++
log
.
Printf
(
"authReply cached %v ago: %v (hits: %v)"
,
time
.
Since
(
time
.
Unix
(
auth
.
Tauth
,
0
)),
auth
.
authResponse
)
r
.
authorizationResponse
=
auth
.
authResponse
return
(
auth
.
authResponse
.
RepoPath
!=
""
)
// XXX ok?
auth
.
authReply
.
authorizationResponse
,
auth
.
Naccess
)
r
.
authorizationResponse
=
auth
.
authReply
.
authorizationResponse
return
(
auth
.
authReply
.
RepoPath
!=
""
)
// XXX ok?
}
r
.
authorizationResponse
=
askAuthBackend
(
r
.
u
,
project
)
authReply
:
=
askAuthBackend
(
r
.
u
,
project
)
// XXX do we need to lock authCache ?
authCache
[
project
]
=
authInfo
{
r
.
authorizationResponse
,
time
.
Now
()
.
Unix
()}
return
downloadOk
authCache
[
project
]
=
&
authInfo
{
authReply
,
time
.
Now
()
.
Unix
(),
0
}
go
authRefresh
(
r
.
u
,
project
)
return
(
authReply
.
RepoPath
!=
""
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment