Merge pull request #6 from SeanOC/master
Added the ability to pass an optional redirect path as part of the manual login form
This commit is contained in:
commit
9a6e895368
@ -67,13 +67,16 @@ func (p *OauthProxy) SetRedirectUrl(redirectUrl *url.URL) {
|
|||||||
p.redirectUrl = redirectUrl
|
p.redirectUrl = redirectUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *OauthProxy) GetLoginURL() string {
|
func (p *OauthProxy) GetLoginURL(redirectUrl string) string {
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("redirect_uri", p.redirectUrl.String())
|
params.Add("redirect_uri", p.redirectUrl.String())
|
||||||
params.Add("approval_prompt", "force")
|
params.Add("approval_prompt", "force")
|
||||||
params.Add("scope", p.oauthScope)
|
params.Add("scope", p.oauthScope)
|
||||||
params.Add("client_id", p.clientID)
|
params.Add("client_id", p.clientID)
|
||||||
params.Add("response_type", "code")
|
params.Add("response_type", "code")
|
||||||
|
if strings.HasPrefix(redirectUrl, "/") {
|
||||||
|
params.Add("state", redirectUrl)
|
||||||
|
}
|
||||||
return fmt.Sprintf("%s?%s", p.oauthLoginUrl, params.Encode())
|
return fmt.Sprintf("%s?%s", p.oauthLoginUrl, params.Encode())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,6 +103,9 @@ func apiRequest(req *http.Request) (*simplejson.Json, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *OauthProxy) redeemCode(code string) (string, error) {
|
func (p *OauthProxy) redeemCode(code string) (string, error) {
|
||||||
|
if code == "" {
|
||||||
|
return "", errors.New("missing code")
|
||||||
|
}
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("redirect_uri", p.redirectUrl.String())
|
params.Add("redirect_uri", p.redirectUrl.String())
|
||||||
params.Add("client_id", p.clientID)
|
params.Add("client_id", p.clientID)
|
||||||
@ -197,7 +203,6 @@ func (p *OauthProxy) ErrorPage(rw http.ResponseWriter, code int, title string, m
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *OauthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code int) {
|
func (p *OauthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code int) {
|
||||||
// TODO: capture state for which url to redirect to at the end
|
|
||||||
p.ClearCookie(rw, req)
|
p.ClearCookie(rw, req)
|
||||||
rw.WriteHeader(code)
|
rw.WriteHeader(code)
|
||||||
templates := getTemplates()
|
templates := getTemplates()
|
||||||
@ -205,9 +210,11 @@ func (p *OauthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code
|
|||||||
t := struct {
|
t := struct {
|
||||||
SignInMessage string
|
SignInMessage string
|
||||||
Htpasswd bool
|
Htpasswd bool
|
||||||
|
Redirect string
|
||||||
}{
|
}{
|
||||||
SignInMessage: p.SignInMessage,
|
SignInMessage: p.SignInMessage,
|
||||||
Htpasswd: p.HtpasswdFile != nil,
|
Htpasswd: p.HtpasswdFile != nil,
|
||||||
|
Redirect: req.URL.RequestURI(),
|
||||||
}
|
}
|
||||||
templates.ExecuteTemplate(rw, "sign_in.html", t)
|
templates.ExecuteTemplate(rw, "sign_in.html", t)
|
||||||
}
|
}
|
||||||
@ -239,39 +246,46 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
|||||||
|
|
||||||
var ok bool
|
var ok bool
|
||||||
var user string
|
var user string
|
||||||
|
redirect := req.FormValue("rd")
|
||||||
|
|
||||||
|
if redirect == "" {
|
||||||
|
redirect = "/"
|
||||||
|
}
|
||||||
|
|
||||||
if req.URL.Path == signInPath {
|
if req.URL.Path == signInPath {
|
||||||
user, ok = p.ManualSignIn(rw, req)
|
user, ok = p.ManualSignIn(rw, req)
|
||||||
if ok {
|
if ok {
|
||||||
p.SetCookie(rw, req, user)
|
p.SetCookie(rw, req, user)
|
||||||
http.Redirect(rw, req, "/", 302)
|
http.Redirect(rw, req, redirect, 302)
|
||||||
} else {
|
} else {
|
||||||
p.SignInPage(rw, req, 200)
|
p.SignInPage(rw, req, 200)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if req.URL.Path == oauthStartPath {
|
if req.URL.Path == oauthStartPath {
|
||||||
http.Redirect(rw, req, p.GetLoginURL(), 302)
|
// get the ?rd= value
|
||||||
return
|
err := req.ParseForm()
|
||||||
}
|
|
||||||
if req.URL.Path == oauthCallbackPath {
|
|
||||||
// finish the oauth cycle
|
|
||||||
reqParams, err := url.ParseQuery(req.URL.RawQuery)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.ErrorPage(rw, 500, "Internal Error", err.Error())
|
p.ErrorPage(rw, 500, "Internal Error", err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
errorString, ok := reqParams["error"]
|
http.Redirect(rw, req, p.GetLoginURL(redirect), 302)
|
||||||
if ok && len(errorString) == 1 {
|
|
||||||
p.ErrorPage(rw, 403, "Permission Denied", errorString[0])
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
code, ok := reqParams["code"]
|
if req.URL.Path == oauthCallbackPath {
|
||||||
if !ok || len(code) != 1 {
|
// finish the oauth cycle
|
||||||
p.ErrorPage(rw, 500, "Internal Error", "Invalid API response")
|
err := req.ParseForm()
|
||||||
|
if err != nil {
|
||||||
|
p.ErrorPage(rw, 500, "Internal Error", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
errorString := req.Form.Get("error")
|
||||||
|
if errorString != "" {
|
||||||
|
p.ErrorPage(rw, 403, "Permission Denied", errorString)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
token, err := p.redeemCode(code[0])
|
token, err := p.redeemCode(req.Form.Get("code"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error redeeming code %s", err.Error())
|
log.Printf("error redeeming code %s", err.Error())
|
||||||
p.ErrorPage(rw, 500, "Internal Error", err.Error())
|
p.ErrorPage(rw, 500, "Internal Error", err.Error())
|
||||||
@ -285,11 +299,16 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
redirect := req.Form.Get("state")
|
||||||
|
if redirect == "" {
|
||||||
|
redirect = "/"
|
||||||
|
}
|
||||||
|
|
||||||
// set cookie, or deny
|
// set cookie, or deny
|
||||||
if p.Validator(email) {
|
if p.Validator(email) {
|
||||||
log.Printf("authenticating %s completed", email)
|
log.Printf("authenticating %s completed", email)
|
||||||
p.SetCookie(rw, req, email)
|
p.SetCookie(rw, req, email)
|
||||||
http.Redirect(rw, req, "/", 302)
|
http.Redirect(rw, req, redirect, 302)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
p.ErrorPage(rw, 403, "Permission Denied", "Invalid Account")
|
p.ErrorPage(rw, 403, "Permission Denied", "Invalid Account")
|
||||||
|
@ -12,12 +12,14 @@ func getTemplates() *template.Template {
|
|||||||
<head><title>Sign In</title></head>
|
<head><title>Sign In</title></head>
|
||||||
<body>
|
<body>
|
||||||
<form method="GET" action="/oauth2/start">
|
<form method="GET" action="/oauth2/start">
|
||||||
|
<input type="hidden" name="rd" value="{{.Redirect}}">
|
||||||
<button type="submit">Sign In w/ Google</button>
|
<button type="submit">Sign In w/ Google</button>
|
||||||
{{.SignInMessage}}
|
{{.SignInMessage}}
|
||||||
</form>
|
</form>
|
||||||
{{ if .Htpasswd }}
|
{{ if .Htpasswd }}
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<form method="POST" action="/oauth2/sign_in">
|
<form method="POST" action="/oauth2/sign_in">
|
||||||
|
<input type="hidden" name="rd" value="{{.Redirect}}">
|
||||||
<label>Username: <input type="text" name="username" size="10"></label><br/>
|
<label>Username: <input type="text" name="username" size="10"></label><br/>
|
||||||
<label>Password: <input type="password" name="password" size="10"></label><br/>
|
<label>Password: <input type="password" name="password" size="10"></label><br/>
|
||||||
<button type="submit">Sign In</button>
|
<button type="submit">Sign In</button>
|
||||||
|
Loading…
Reference in New Issue
Block a user