Skip to content
This repository has been archived by the owner on Jan 30, 2020. It is now read-only.

1) Add websocket support, and 2) make sure to redirect to where we came from #3

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# This file is a template, and might need editing before it works on your project.
# Official docker image.
image: golang:latest

variables:
FAILFASTCI_NAMESPACE: jj-ff
GOLANG_DEP_VER: 0.4.1
GO_SRC_PATH: github.com/joejulian/oauth2_proxy

stages:
- test
- build
- publish

services:
- docker:dind


test-fmt:
stage: test
image: golang
tags:
- gitlab-org
script:
- go fmt

test-vet:
stage: test
image: golang
tags:
- gitlab-org
script:
- curl -L -s https://github.com/golang/dep/releases/download/v${GOLANG_DEP_VER}/dep-linux-amd64 -o $GOPATH/bin/dep
- chmod +x $GOPATH/bin/dep
- mkdir -p $(dirname $GOPATH/src/${GO_SRC_PATH})
- ln -sf $PWD $GOPATH/src/${GO_SRC_PATH}
- cd $GOPATH/src/${GO_SRC_PATH}
- dep ensure
- go vet

test:
stage: test
image: golang
tags:
- gitlab-org
script:
- curl -L -s https://github.com/golang/dep/releases/download/v${GOLANG_DEP_VER}/dep-linux-amd64 -o $GOPATH/bin/dep
- chmod +x $GOPATH/bin/dep
- mkdir -p $(dirname $GOPATH/src/${GO_SRC_PATH})
- ln -sf $PWD $GOPATH/src/${GO_SRC_PATH}
- cd $GOPATH/src/${GO_SRC_PATH}
- dep ensure
- go test

build:
stage: build
image: golang
tags:
- gitlab-org
script:
- go build

build-master:
stage: publish
image: docker:latest
script:
- docker build --pull -t "$CI_REGISTRY_IMAGE" .
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
- docker push "$CI_REGISTRY_IMAGE"
only:
- master
tags:
- docker

build:
stage: publish
image: docker:latest
script:
- docker build --pull -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" .
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG"
except:
- master
tags:
- docker
46 changes: 46 additions & 0 deletions gap.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
## Google Auth Proxy Config File
## https://github.com/bitly/google_auth_proxy

## <addr>:<port> to listen on for HTTP clients
# http_address = "127.0.0.1:4180"

## the OAuth Redirect URL.
redirect_url = "https://auth.int.treatwell.com/oauth2/callback"

## the http url(s) of the upstream endpoint. If multiple, routing is based on path
upstreams = [
"http://127.0.0.1:8080/"
]

## pass HTTP Basic Auth, X-Forwarded-User and X-Forwarded-Email information to upstream
# pass_basic_auth = true

## Google Apps Domains to allow authentication for
google_apps_domains = [
"treatwell.nl"
]


## The Google OAuth Client ID, Secret
client_id = "598239317768-0i5vee2o45qpjqj4ivimdutnff79lqou.apps.googleusercontent.com"
client_secret = "sSzmqIahuWFKt9ghdYcE0zjr"

## Authenticated Email Addresses File (one email per line)
# authenticated_emails_file = ""

## Htpasswd File (optional)
## Additionally authenticate against a htpasswd file. Entries must be created with "htpasswd -s" for SHA encryption
## enabling exposes a username/login signin form
#htpasswd_file = "/opt/htpasswd"


## Cookie Settings
## Secret - the seed string for secure cookies
## Domain - optional cookie domain to force cookies to (ie: .yourcompany.com)
## Expire - expire timeframe for cookie
# cookie_secret = ""
cookie_domain = "int.treatwell.com"
cookie_expire = "168h"
# cookie_https_only = true
# cookie_httponly = true

40 changes: 26 additions & 14 deletions oauthproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"io/ioutil"
"log"
"net/http"
"net/http/httputil"
"net/url"
"regexp"
"strings"
Expand Down Expand Up @@ -54,7 +53,7 @@ func NewOauthProxy(opts *Options, validator func(string) bool) *OauthProxy {
path := u.Path
u.Path = ""
log.Printf("mapping path %q => upstream %q", path, u)
serveMux.Handle(path, httputil.NewSingleHostReverseProxy(u))
serveMux.Handle(path, NewWebsocketReverseProxy(u))
}
for _, u := range opts.CompiledRegex {
log.Printf("compiled skip-auth-regex => %q", u)
Expand Down Expand Up @@ -98,9 +97,7 @@ func (p *OauthProxy) GetLoginURL(redirectUrl string) string {
params.Add("scope", p.oauthScope)
params.Add("client_id", p.clientID)
params.Add("response_type", "code")
if strings.HasPrefix(redirectUrl, "/") {
params.Add("state", redirectUrl)
}
params.Add("state", redirectUrl)
return fmt.Sprintf("%s?%s", p.oauthLoginUrl, params.Encode())
}

Expand Down Expand Up @@ -227,16 +224,18 @@ func (p *OauthProxy) PingPage(rw http.ResponseWriter) {
fmt.Fprintf(rw, "OK")
}

func (p *OauthProxy) ErrorPage(rw http.ResponseWriter, code int, title string, message string) {
func (p *OauthProxy) ErrorPage(rw http.ResponseWriter, req *http.Request, code int, title string, message string) {
log.Printf("ErrorPage %d %s %s", code, title, message)
rw.WriteHeader(code)
templates := getTemplates()
t := struct {
Title string
Message string
Redirect string
}{
Title: fmt.Sprintf("%d %s", code, title),
Message: message,
Redirect: req.Form.Get("state"),
}
templates.ExecuteTemplate(rw, "error.html", t)
}
Expand All @@ -246,6 +245,11 @@ func (p *OauthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code
rw.WriteHeader(code)
templates := getTemplates()

redirect := req.FormValue("rd")
if redirect == "" {
redirect = fmt.Sprintf("https://%s%s", req.Host, req.URL.RequestURI())
}

t := struct {
SignInMessage string
CustomLogin bool
Expand All @@ -254,9 +258,10 @@ func (p *OauthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code
}{
SignInMessage: p.SignInMessage,
CustomLogin: p.displayCustomLoginForm(),
Redirect: req.URL.RequestURI(),
Redirect: redirect,
Version: VERSION,
}

templates.ExecuteTemplate(rw, "sign_in.html", t)
}

Expand Down Expand Up @@ -322,7 +327,7 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == signInPath {
redirect, err := p.GetRedirect(req)
if err != nil {
p.ErrorPage(rw, 500, "Internal Error", err.Error())
p.ErrorPage(rw, req, 500, "Internal Error", err.Error())
return
}

Expand All @@ -338,7 +343,7 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == oauthStartPath {
redirect, err := p.GetRedirect(req)
if err != nil {
p.ErrorPage(rw, 500, "Internal Error", err.Error())
p.ErrorPage(rw, req, 500, "Internal Error", err.Error())
return
}
http.Redirect(rw, req, p.GetLoginURL(redirect), 302)
Expand All @@ -348,19 +353,19 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
// finish the oauth cycle
err := req.ParseForm()
if err != nil {
p.ErrorPage(rw, 500, "Internal Error", err.Error())
p.ErrorPage(rw, req, 500, "Internal Error", err.Error())
return
}
errorString := req.Form.Get("error")
if errorString != "" {
p.ErrorPage(rw, 403, "Permission Denied", errorString)
p.ErrorPage(rw, req, 403, "Permission Denied", errorString)
return
}

_, email, err := p.redeemCode(req.Form.Get("code"))
if err != nil {
log.Printf("%s error redeeming code %s", remoteAddr, err)
p.ErrorPage(rw, 500, "Internal Error", err.Error())
p.ErrorPage(rw, req, 500, "Internal Error", err.Error())
return
}

Expand All @@ -376,7 +381,7 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
http.Redirect(rw, req, redirect, 302)
return
} else {
p.ErrorPage(rw, 403, "Permission Denied", "Invalid Account")
p.ErrorPage(rw, req, 403, "Permission Denied", "Invalid Account")
return
}
}
Expand All @@ -389,8 +394,11 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
}
}

authedByBasicAuth := false

if !ok {
user, ok = p.CheckBasicAuth(req)
authedByBasicAuth = ok
// if we want to promote basic auth requests to cookie'd requests, we could do that here
// not sure that would be ideal in all circumstances though
// if ok {
Expand All @@ -406,7 +414,11 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {

// At this point, the user is authenticated. proxy normally
if p.PassBasicAuth {
req.SetBasicAuth(user, "")
if (authedByBasicAuth) {
// Strip the password if the basic auth was used to identify the google_auth_proxy user
// otherwise, just pass the basic auth information along.
req.SetBasicAuth(user, "")
}
req.Header["X-Forwarded-User"] = []string{user}
req.Header["X-Forwarded-Email"] = []string{email}
}
Expand Down
2 changes: 1 addition & 1 deletion templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func getTemplates() *template.Template {
<h2>{{.Title}}</h2>
<p>{{.Message}}</p>
<hr>
<p><a href="/oauth2/sign_in">Sign In</a></p>
<p><a href="/oauth2/sign_in?rd={{.Redirect}}">Sign In</a></p>
</body>
</html>{{end}}`)
if err != nil {
Expand Down
Loading