2019-04-21 08:34:25 +08:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/hmac"
|
|
|
|
"crypto/sha256"
|
|
|
|
"encoding/hex"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
)
|
|
|
|
|
|
|
|
func ssoRedirectHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
commenterToken := r.FormValue("commenterToken")
|
|
|
|
domain := r.Header.Get("Referer")
|
|
|
|
|
|
|
|
if commenterToken == "" {
|
|
|
|
fmt.Fprintf(w, "Error: %s\n", errorMissingField.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
domain = domainStrip(domain)
|
|
|
|
if domain == "" {
|
|
|
|
fmt.Fprintf(w, "Error: No Referer header found in request\n")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err := commenterGetByCommenterToken(commenterToken)
|
|
|
|
if err != nil && err != errorNoSuchToken {
|
|
|
|
fmt.Fprintf(w, "Error: %s\n", err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
d, err := domainGet(domain)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Fprintf(w, "Error: %s\n", errorNoSuchDomain.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if !d.SsoProvider {
|
|
|
|
fmt.Fprintf(w, "Error: SSO not configured for %s\n", domain)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if d.SsoSecret == "" || d.SsoUrl == "" {
|
|
|
|
fmt.Fprintf(w, "Error: %s\n", errorMissingConfig.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
key, err := hex.DecodeString(d.SsoSecret)
|
|
|
|
if err != nil {
|
|
|
|
logger.Errorf("cannot decode SSO secret as hex: %v", err)
|
|
|
|
fmt.Fprintf(w, "Error: %s\n", err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-04-21 11:25:35 +08:00
|
|
|
token, err := ssoTokenNew(domain, commenterToken)
|
2019-04-21 08:34:25 +08:00
|
|
|
if err != nil {
|
2019-04-21 11:25:35 +08:00
|
|
|
fmt.Fprintf(w, "Error: %s\n", err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
tokenBytes, err := hex.DecodeString(token)
|
|
|
|
if err != nil {
|
|
|
|
logger.Errorf("cannot decode hex token: %v", err)
|
2019-04-21 08:34:25 +08:00
|
|
|
fmt.Fprintf(w, "Error: %s\n", errorInternal.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
h := hmac.New(sha256.New, key)
|
|
|
|
h.Write(tokenBytes)
|
|
|
|
signature := hex.EncodeToString(h.Sum(nil))
|
|
|
|
|
|
|
|
u, err := url.Parse(d.SsoUrl)
|
|
|
|
if err != nil {
|
|
|
|
// this should really not be happening; we're checking if the
|
|
|
|
// passed URL is valid at domain update
|
|
|
|
logger.Errorf("cannot parse URL: %v", err)
|
|
|
|
fmt.Fprintf(w, "Error: %s\n", errorInternal.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
q := u.Query()
|
2019-04-21 11:25:35 +08:00
|
|
|
q.Set("token", token)
|
2019-04-21 08:34:25 +08:00
|
|
|
q.Set("hmac", signature)
|
|
|
|
u.RawQuery = q.Encode()
|
|
|
|
|
|
|
|
http.Redirect(w, r, u.String(), http.StatusFound)
|
|
|
|
}
|