diff --git a/build/server b/build/server index b51f108..a7ecb84 100755 Binary files a/build/server and b/build/server differ diff --git a/server/handlers/app.go b/server/handlers/app.go index 2f59f9d..b8e94c3 100644 --- a/server/handlers/app.go +++ b/server/handlers/app.go @@ -1,18 +1,55 @@ package handlers import ( + "encoding/base64" + "encoding/json" "log" "net/http" + "github.com/authorizerdev/authorizer/server/utils" "github.com/gin-gonic/gin" ) -// TODO read query param = state which is base64 encoded -// make sure url is present in allowed origins -// set that in redirect_url +type State struct { + AuthorizerURL string `json:"authorizerURL"` + RedirectURL string `json:"redirectURL"` +} + func AppHandler() gin.HandlerFunc { return func(c *gin.Context) { - log.Println("Host:", c.Request.Host) + host := c.Request.Host + state := c.Query("state") + if state == "" { + c.JSON(400, gin.H{"error": "invalid state"}) + return + } + + decodedState, err := base64.StdEncoding.DecodeString(state) + if err != nil { + c.JSON(400, gin.H{"error": "[unable to decode state] invalid state"}) + return + } + var stateObj State + err = json.Unmarshal(decodedState, &stateObj) + if err != nil { + c.JSON(400, gin.H{"error": "[unable to parse state] invalid state"}) + return + } + + // validate redirect url with allowed origins + if !utils.IsValidRedirectURL(stateObj.RedirectURL) { + c.JSON(400, gin.H{"error": "invalid redirect url"}) + return + } + + log.Println(stateObj) + log.Println(host, utils.GetDomainName(stateObj.AuthorizerURL), utils.GetDomainName(host)) + // validate host and domain of authorizer url + if utils.GetDomainName(stateObj.AuthorizerURL) != utils.GetDomainName(host) { + c.JSON(400, gin.H{"error": "invalid host url"}) + return + } + // debug the request state if pusher := c.Writer.Pusher(); pusher != nil { // use pusher.Push() to do server push @@ -22,8 +59,8 @@ func AppHandler() gin.HandlerFunc { } c.HTML(http.StatusOK, "app.tmpl", gin.H{ "data": map[string]string{ - "authorizerURL": c.Request.Host, - "redirect_url": "http://localhost:8080/app", + "authorizerURL": stateObj.AuthorizerURL, + "redirectURL": stateObj.RedirectURL, }, }) } diff --git a/server/handlers/oauthCallback.go b/server/handlers/oauthCallback.go index d6912d8..43aac1f 100644 --- a/server/handlers/oauthCallback.go +++ b/server/handlers/oauthCallback.go @@ -174,11 +174,12 @@ func OAuthCallbackHandler() gin.HandlerFunc { } var err error + code := c.Request.FormValue("code") switch provider { case enum.Google.String(): - err = processGoogleUserInfo(c.Request.FormValue("code"), c) + err = processGoogleUserInfo(code, c) case enum.Github.String(): - err = processGithubUserInfo(c.Request.FormValue("code"), c) + err = processGithubUserInfo(code, c) default: err = fmt.Errorf(`invalid oauth provider`) } diff --git a/server/handlers/oauthLogin.go b/server/handlers/oauthLogin.go index a8f077b..a4097fb 100644 --- a/server/handlers/oauthLogin.go +++ b/server/handlers/oauthLogin.go @@ -15,7 +15,7 @@ import ( func OAuthLoginHandler() gin.HandlerFunc { return func(c *gin.Context) { // TODO validate redirect URL - redirectURL := c.Query("redirect_url") + redirectURL := c.Query("redirectURL") if redirectURL == "" { c.JSON(400, gin.H{ diff --git a/server/utils/cookie.go b/server/utils/cookie.go index 7b6194c..6fe9b9c 100644 --- a/server/utils/cookie.go +++ b/server/utils/cookie.go @@ -12,7 +12,7 @@ func SetCookie(gc *gin.Context, token string) { secure := true httpOnly := true - host := GetDomainName(gc.Request.Host) + host := GetHostName(gc.Request.Host) log.Println("=> host", host) gc.SetSameSite(http.SameSiteNoneMode) gc.SetCookie(constants.COOKIE_NAME, token, 3600, "/", host, secure, httpOnly) @@ -35,7 +35,7 @@ func DeleteCookie(gc *gin.Context) { secure = false } - host := GetDomainName(gc.Request.Host) + host := GetHostName(gc.Request.Host) gc.SetSameSite(http.SameSiteNoneMode) gc.SetCookie(constants.COOKIE_NAME, "", -1, "/", host, secure, httpOnly) } diff --git a/server/utils/urls.go b/server/utils/urls.go index accf01a..e89894d 100644 --- a/server/utils/urls.go +++ b/server/utils/urls.go @@ -1,11 +1,13 @@ package utils import ( + "log" "net/url" + "strings" ) // function to get hostname -func GetDomainName(auth_url string) string { +func GetHostName(auth_url string) string { u, err := url.Parse("//" + auth_url) if err != nil { return `localhost` @@ -13,25 +15,38 @@ func GetDomainName(auth_url string) string { host := u.Hostname() + return host +} + +// function to get domain name +func GetDomainName(auth_url string) string { + u, err := url.Parse("//" + auth_url) + if err != nil { + return `localhost` + } + + host := u.Hostname() + log.Println("=> host", host) + // code to get root domain in case of sub-domains - // hostParts := strings.Split(host, ".") - // hostPartsLen := len(hostParts) + hostParts := strings.Split(host, ".") + hostPartsLen := len(hostParts) - // if hostPartsLen == 1 { - // return host - // } + if hostPartsLen == 1 { + return host + } - // if hostPartsLen == 2 { - // if hostParts[0] == "www" { - // return hostParts[1] - // } else { - // return host - // } - // } + if hostPartsLen == 2 { + if hostParts[0] == "www" { + return hostParts[1] + } else { + return host + } + } - // if hostPartsLen > 2 { - // return strings.Join(hostParts[hostPartsLen-2:], ".") - // } + if hostPartsLen > 2 { + return strings.Join(hostParts[hostPartsLen-2:], ".") + } return host } diff --git a/server/utils/validator.go b/server/utils/validator.go index b93eaba..b953045 100644 --- a/server/utils/validator.go +++ b/server/utils/validator.go @@ -1,8 +1,31 @@ package utils -import "net/mail" +import ( + "net/mail" + "strings" + + "github.com/authorizerdev/authorizer/server/constants" +) func IsValidEmail(email string) bool { _, err := mail.ParseAddress(email) return err == nil } + +func IsValidRedirectURL(url string) bool { + if len(constants.ALLOWED_ORIGINS) == 1 && constants.ALLOWED_ORIGINS[0] == "*" { + return true + } + + hasValidURL := false + urlDomain := GetDomainName(url) + + for _, val := range constants.ALLOWED_ORIGINS { + if strings.Contains(val, urlDomain) { + hasValidURL = true + break + } + } + + return hasValidURL +} diff --git a/templates/app.tmpl b/templates/app.tmpl index 16c8f8a..ca1933b 100644 --- a/templates/app.tmpl +++ b/templates/app.tmpl @@ -6,12 +6,12 @@ Document +
- \ No newline at end of file