parent
245a5b5e1b
commit
7b16213e22
|
@ -10,27 +10,27 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ENV = ""
|
ENV = ""
|
||||||
DB_TYPE = ""
|
DB_TYPE = ""
|
||||||
DB_URL = ""
|
DB_URL = ""
|
||||||
SMTP_HOST = ""
|
SMTP_HOST = ""
|
||||||
SMTP_PORT = ""
|
SMTP_PORT = ""
|
||||||
SENDER_EMAIL = ""
|
SENDER_EMAIL = ""
|
||||||
SENDER_PASSWORD = ""
|
SENDER_PASSWORD = ""
|
||||||
JWT_TYPE = ""
|
JWT_TYPE = ""
|
||||||
JWT_SECRET = ""
|
JWT_SECRET = ""
|
||||||
FRONTEND_URL = ""
|
FRONTEND_URL = ""
|
||||||
SERVER_URL = ""
|
SERVER_URL = ""
|
||||||
PORT = "8080"
|
PORT = "8080"
|
||||||
REDIS_URL = ""
|
REDIS_URL = ""
|
||||||
IS_PROD = false
|
IS_PROD = false
|
||||||
COOKIE_NAME = ""
|
COOKIE_NAME = ""
|
||||||
GOOGLE_CLIENT_ID = ""
|
GOOGLE_CLIENT_ID = ""
|
||||||
GOOGLE_CLIENT_SECRET = ""
|
GOOGLE_CLIENT_SECRET = ""
|
||||||
GITHUB_CLIENT_ID = ""
|
GITHUB_CLIENT_ID = ""
|
||||||
GITHUB_CLIENT_SECRET = ""
|
GITHUB_CLIENT_SECRET = ""
|
||||||
FACEBOOK_CLIENT_ID = ""
|
// FACEBOOK_CLIENT_ID = ""
|
||||||
FACEBOOK_CLIENT_SECRET = ""
|
// FACEBOOK_CLIENT_SECRET = ""
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -57,8 +57,8 @@ func init() {
|
||||||
GOOGLE_CLIENT_SECRET = os.Getenv("GOOGLE_CLIENT_SECRET")
|
GOOGLE_CLIENT_SECRET = os.Getenv("GOOGLE_CLIENT_SECRET")
|
||||||
GITHUB_CLIENT_ID = os.Getenv("GITHUB_CLIENT_ID")
|
GITHUB_CLIENT_ID = os.Getenv("GITHUB_CLIENT_ID")
|
||||||
GITHUB_CLIENT_SECRET = os.Getenv("GITHUB_CLIENT_SECRET")
|
GITHUB_CLIENT_SECRET = os.Getenv("GITHUB_CLIENT_SECRET")
|
||||||
FACEBOOK_CLIENT_ID = os.Getenv("FACEBOOK_CLIENT_ID")
|
// FACEBOOK_CLIENT_ID = os.Getenv("FACEBOOK_CLIENT_ID")
|
||||||
FACEBOOK_CLIENT_SECRET = os.Getenv("FACEBOOK_CLIENT_SECRET")
|
// FACEBOOK_CLIENT_SECRET = os.Getenv("FACEBOOK_CLIENT_SECRET")
|
||||||
|
|
||||||
if ENV == "" {
|
if ENV == "" {
|
||||||
ENV = "production"
|
ENV = "production"
|
||||||
|
|
|
@ -44,43 +44,111 @@ func processGoogleUserInfo(state string, code string, c *gin.Context) error {
|
||||||
json.Unmarshal(body, &userRawData)
|
json.Unmarshal(body, &userRawData)
|
||||||
|
|
||||||
existingUser, err := db.Mgr.GetUserByEmail(userRawData["email"])
|
existingUser, err := db.Mgr.GetUserByEmail(userRawData["email"])
|
||||||
user := db.User{}
|
user := db.User{
|
||||||
|
FirstName: userRawData["given_name"],
|
||||||
|
LastName: userRawData["family_name"],
|
||||||
|
Image: userRawData["picture"],
|
||||||
|
Email: userRawData["email"],
|
||||||
|
EmailVerifiedAt: time.Now().Unix(),
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// user not registered, register user and generate session token
|
// user not registered, register user and generate session token
|
||||||
user = db.User{
|
user.SignupMethod = enum.Google.String()
|
||||||
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 {
|
} else {
|
||||||
// user exists in db, check if method was google
|
// user exists in db, check if method was google
|
||||||
// if not append google to existing signup method and save it
|
// if not append google to existing signup method and save it
|
||||||
|
|
||||||
signupMethod := existingUser.SignupMethod
|
signupMethod := existingUser.SignupMethod
|
||||||
if !strings.Contains(signupMethod, enum.Google.String()) {
|
if !strings.Contains(signupMethod, enum.Google.String()) {
|
||||||
signupMethod += signupMethod + "," + enum.Google.String()
|
signupMethod = signupMethod + "," + enum.Google.String()
|
||||||
}
|
}
|
||||||
user = db.User{
|
user.SignupMethod = signupMethod
|
||||||
FirstName: userRawData["given_name"],
|
user.Password = existingUser.Password
|
||||||
LastName: userRawData["family_name"],
|
|
||||||
Image: userRawData["picture"],
|
|
||||||
Email: userRawData["email"],
|
|
||||||
EmailVerifiedAt: time.Now().Unix(),
|
|
||||||
SignupMethod: signupMethod,
|
|
||||||
Password: existingUser.Password,
|
|
||||||
}
|
|
||||||
|
|
||||||
user, _ = db.Mgr.SaveUser(user)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user, _ = db.Mgr.SaveUser(user)
|
||||||
userIdStr := fmt.Sprintf("%d", user.ID)
|
userIdStr := fmt.Sprintf("%d", user.ID)
|
||||||
|
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 processGithubUserInfo(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.GithubConfig.Exchange(oauth2.NoContext, code)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid google exchange code: %s", err.Error())
|
||||||
|
}
|
||||||
|
client := http.Client{}
|
||||||
|
req, err := http.NewRequest("GET", constants.GithubUserInfoURL, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error creating github user info request: %s", err.Error())
|
||||||
|
}
|
||||||
|
req.Header = http.Header{
|
||||||
|
"Authorization": []string{fmt.Sprintf("token %s", token.AccessToken)},
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := client.Do(req)
|
||||||
|
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"])
|
||||||
|
name := strings.Split(userRawData["name"], " ")
|
||||||
|
firstName := ""
|
||||||
|
lastName := ""
|
||||||
|
if len(name) >= 1 && strings.TrimSpace(name[0]) != "" {
|
||||||
|
firstName = name[0]
|
||||||
|
}
|
||||||
|
if len(name) > 1 && strings.TrimSpace(name[1]) != "" {
|
||||||
|
lastName = name[0]
|
||||||
|
}
|
||||||
|
user := db.User{
|
||||||
|
FirstName: firstName,
|
||||||
|
LastName: lastName,
|
||||||
|
Image: userRawData["avatar_url"],
|
||||||
|
Email: userRawData["email"],
|
||||||
|
EmailVerifiedAt: time.Now().Unix(),
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
// user not registered, register user and generate session token
|
||||||
|
user.SignupMethod = enum.Github.String()
|
||||||
|
} 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.Github.String()) {
|
||||||
|
signupMethod = signupMethod + "," + enum.Github.String()
|
||||||
|
}
|
||||||
|
user.SignupMethod = signupMethod
|
||||||
|
user.Password = existingUser.Password
|
||||||
|
}
|
||||||
|
|
||||||
|
user, _ = db.Mgr.SaveUser(user)
|
||||||
|
userIdStr := fmt.Sprintf("%d", user.ID)
|
||||||
refreshToken, _, _ := utils.CreateAuthToken(utils.UserAuthInfo{
|
refreshToken, _, _ := utils.CreateAuthToken(utils.UserAuthInfo{
|
||||||
ID: userIdStr,
|
ID: userIdStr,
|
||||||
Email: user.Email,
|
Email: user.Email,
|
||||||
|
@ -97,13 +165,18 @@ func processGoogleUserInfo(state string, code string, c *gin.Context) error {
|
||||||
|
|
||||||
func HandleOAuthCallback(provider enum.OAuthProvider) gin.HandlerFunc {
|
func HandleOAuthCallback(provider enum.OAuthProvider) gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
|
var err error
|
||||||
if provider == enum.GoogleProvider {
|
if provider == enum.GoogleProvider {
|
||||||
err := processGoogleUserInfo(c.Request.FormValue("state"), c.Request.FormValue("code"), c)
|
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)
|
|
||||||
}
|
}
|
||||||
|
if provider == enum.GithubProvider {
|
||||||
|
err = processGithubUserInfo(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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,5 +20,10 @@ func HandleOAuthLogin(provider enum.OAuthProvider) gin.HandlerFunc {
|
||||||
url := oauth.OAuthProvider.GoogleConfig.AuthCodeURL(oauthStateString)
|
url := oauth.OAuthProvider.GoogleConfig.AuthCodeURL(oauthStateString)
|
||||||
c.Redirect(http.StatusTemporaryRedirect, url)
|
c.Redirect(http.StatusTemporaryRedirect, url)
|
||||||
}
|
}
|
||||||
|
if provider == enum.GithubProvider {
|
||||||
|
session.SetToken(oauthStateString, enum.Github.String())
|
||||||
|
url := oauth.OAuthProvider.GithubConfig.AuthCodeURL(oauthStateString)
|
||||||
|
c.Redirect(http.StatusTemporaryRedirect, url)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,15 +3,14 @@ package oauth
|
||||||
import (
|
import (
|
||||||
"github.com/yauthdev/yauth/server/constants"
|
"github.com/yauthdev/yauth/server/constants"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
facebookOAuth2 "golang.org/x/oauth2/facebook"
|
|
||||||
githubOAuth2 "golang.org/x/oauth2/github"
|
githubOAuth2 "golang.org/x/oauth2/github"
|
||||||
googleOAuth2 "golang.org/x/oauth2/google"
|
googleOAuth2 "golang.org/x/oauth2/google"
|
||||||
)
|
)
|
||||||
|
|
||||||
type OAuthProviders struct {
|
type OAuthProviders struct {
|
||||||
GoogleConfig *oauth2.Config
|
GoogleConfig *oauth2.Config
|
||||||
GithubConfig *oauth2.Config
|
GithubConfig *oauth2.Config
|
||||||
FacebookConfig *oauth2.Config
|
// FacebookConfig *oauth2.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
var OAuthProvider OAuthProviders
|
var OAuthProvider OAuthProviders
|
||||||
|
@ -27,19 +26,19 @@ func init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if constants.GITHUB_CLIENT_ID != "" && constants.GITHUB_CLIENT_SECRET != "" {
|
if constants.GITHUB_CLIENT_ID != "" && constants.GITHUB_CLIENT_SECRET != "" {
|
||||||
OAuthProvider.GoogleConfig = &oauth2.Config{
|
OAuthProvider.GithubConfig = &oauth2.Config{
|
||||||
ClientID: constants.GITHUB_CLIENT_ID,
|
ClientID: constants.GITHUB_CLIENT_ID,
|
||||||
ClientSecret: constants.GITHUB_CLIENT_SECRET,
|
ClientSecret: constants.GITHUB_CLIENT_SECRET,
|
||||||
RedirectURL: constants.SERVER_URL + "/callback/github",
|
RedirectURL: constants.SERVER_URL + "/callback/github",
|
||||||
Endpoint: githubOAuth2.Endpoint,
|
Endpoint: githubOAuth2.Endpoint,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if constants.FACEBOOK_CLIENT_ID != "" && constants.FACEBOOK_CLIENT_SECRET != "" {
|
// if constants.FACEBOOK_CLIENT_ID != "" && constants.FACEBOOK_CLIENT_SECRET != "" {
|
||||||
OAuthProvider.GoogleConfig = &oauth2.Config{
|
// OAuthProvider.FacebookConfig = &oauth2.Config{
|
||||||
ClientID: constants.FACEBOOK_CLIENT_ID,
|
// ClientID: constants.FACEBOOK_CLIENT_ID,
|
||||||
ClientSecret: constants.FACEBOOK_CLIENT_SECRET,
|
// ClientSecret: constants.FACEBOOK_CLIENT_SECRET,
|
||||||
RedirectURL: constants.SERVER_URL + "/callback/facebook/",
|
// RedirectURL: constants.SERVER_URL + "/callback/facebook/",
|
||||||
Endpoint: facebookOAuth2.Endpoint,
|
// Endpoint: facebookOAuth2.Endpoint,
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"log"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/yauthdev/yauth/server/enum"
|
"github.com/yauthdev/yauth/server/enum"
|
||||||
|
@ -26,5 +27,10 @@ func main() {
|
||||||
r.GET("/login/google", handlers.HandleOAuthLogin(enum.GoogleProvider))
|
r.GET("/login/google", handlers.HandleOAuthLogin(enum.GoogleProvider))
|
||||||
r.GET("/callback/google", handlers.HandleOAuthCallback(enum.GoogleProvider))
|
r.GET("/callback/google", handlers.HandleOAuthCallback(enum.GoogleProvider))
|
||||||
}
|
}
|
||||||
|
log.Println(oauth.OAuthProvider.GithubConfig)
|
||||||
|
if oauth.OAuthProvider.GithubConfig != nil {
|
||||||
|
r.GET("/login/github", handlers.HandleOAuthLogin(enum.GithubProvider))
|
||||||
|
r.GET("/callback/github", handlers.HandleOAuthCallback(enum.GithubProvider))
|
||||||
|
}
|
||||||
r.Run()
|
r.Run()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user