authorizer/server/handlers/oauthCallbackHandler.go

110 lines
3.1 KiB
Go
Raw Normal View History

package handlers
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strings"
"time"
"github.com/gin-gonic/gin"
"github.com/yauthdev/yauth/server/constants"
"github.com/yauthdev/yauth/server/db"
"github.com/yauthdev/yauth/server/enum"
"github.com/yauthdev/yauth/server/oauth"
"github.com/yauthdev/yauth/server/session"
"github.com/yauthdev/yauth/server/utils"
"golang.org/x/oauth2"
)
func processGoogleUserInfo(state string, code string, c *gin.Context) error {
sessionState := session.GetToken(state)
if sessionState == "" {
return fmt.Errorf("invalid oauth state")
}
session.DeleteToken(sessionState)
token, err := oauth.OAuthProvider.GoogleConfig.Exchange(oauth2.NoContext, code)
if err != nil {
return fmt.Errorf("invalid google exchange code: %s", err.Error())
}
client := oauth.OAuthProvider.GoogleConfig.Client(oauth2.NoContext, token)
response, err := client.Get(constants.GoogleUserInfoURL)
if err != nil {
return err
}
defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body)
if err != nil {
return fmt.Errorf("failed to read google response body: %s", err.Error())
}
userRawData := make(map[string]string)
json.Unmarshal(body, &userRawData)
existingUser, err := db.Mgr.GetUserByEmail(userRawData["email"])
user := db.User{}
if err != nil {
// user not registered, register user and generate session token
user = db.User{
FirstName: userRawData["given_name"],
LastName: userRawData["family_name"],
Image: userRawData["picture"],
Email: userRawData["email"],
EmailVerifiedAt: time.Now().Unix(),
SignupMethod: enum.Google.String(),
}
user, _ = db.Mgr.SaveUser(user)
} else {
// user exists in db, check if method was google
// if not append google to existing signup method and save it
signupMethod := existingUser.SignupMethod
if !strings.Contains(signupMethod, enum.Google.String()) {
signupMethod += signupMethod + "," + enum.Google.String()
}
user = db.User{
FirstName: userRawData["given_name"],
LastName: userRawData["family_name"],
Image: userRawData["picture"],
Email: userRawData["email"],
EmailVerifiedAt: time.Now().Unix(),
SignupMethod: signupMethod,
2021-07-17 17:09:50 +00:00
Password: existingUser.Password,
}
user, _ = db.Mgr.SaveUser(user)
}
userIdStr := fmt.Sprintf("%d", user.ID)
2021-07-17 17:09:50 +00:00
refreshToken, _, _ := utils.CreateAuthToken(utils.UserAuthInfo{
ID: userIdStr,
Email: user.Email,
}, enum.RefreshToken)
accessToken, _, _ := utils.CreateAuthToken(utils.UserAuthInfo{
ID: userIdStr,
Email: user.Email,
}, enum.AccessToken)
utils.SetCookie(c, accessToken)
session.SetToken(userIdStr, refreshToken)
return nil
}
func HandleOAuthCallback(provider enum.OAuthProvider) gin.HandlerFunc {
return func(c *gin.Context) {
if provider == enum.GoogleProvider {
err := processGoogleUserInfo(c.Request.FormValue("state"), c.Request.FormValue("code"), c)
if err != nil {
c.Redirect(http.StatusTemporaryRedirect, constants.FRONTEND_URL+"?error="+err.Error())
}
c.Redirect(http.StatusTemporaryRedirect, constants.FRONTEND_URL)
}
}
}