diff options
Diffstat (limited to 'workhorse/internal/channel/auth_checker.go')
-rw-r--r-- | workhorse/internal/channel/auth_checker.go | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/workhorse/internal/channel/auth_checker.go b/workhorse/internal/channel/auth_checker.go new file mode 100644 index 00000000000..f44850e0861 --- /dev/null +++ b/workhorse/internal/channel/auth_checker.go @@ -0,0 +1,69 @@ +package channel + +import ( + "errors" + "net/http" + "time" + + "gitlab.com/gitlab-org/gitlab-workhorse/internal/api" +) + +type AuthCheckerFunc func() *api.ChannelSettings + +// Regularly checks that authorization is still valid for a channel, outputting +// to the stopper when it isn't +type AuthChecker struct { + Checker AuthCheckerFunc + Template *api.ChannelSettings + StopCh chan error + Done chan struct{} + Count int64 +} + +var ErrAuthChanged = errors.New("connection closed: authentication changed or endpoint unavailable") + +func NewAuthChecker(f AuthCheckerFunc, template *api.ChannelSettings, stopCh chan error) *AuthChecker { + return &AuthChecker{ + Checker: f, + Template: template, + StopCh: stopCh, + Done: make(chan struct{}), + } +} +func (c *AuthChecker) Loop(interval time.Duration) { + for { + select { + case <-time.After(interval): + settings := c.Checker() + if !c.Template.IsEqual(settings) { + c.StopCh <- ErrAuthChanged + return + } + c.Count = c.Count + 1 + case <-c.Done: + return + } + } +} + +func (c *AuthChecker) Close() error { + close(c.Done) + return nil +} + +// Generates a CheckerFunc from an *api.API + request needing authorization +func authCheckFunc(myAPI *api.API, r *http.Request, suffix string) AuthCheckerFunc { + return func() *api.ChannelSettings { + httpResponse, authResponse, err := myAPI.PreAuthorize(suffix, r) + if err != nil { + return nil + } + defer httpResponse.Body.Close() + + if httpResponse.StatusCode != http.StatusOK || authResponse == nil { + return nil + } + + return authResponse.Channel + } +} |