package service import ( "context" "fmt" "github.com/gin-gonic/gin" domain "github.com/haydenhargreaves/Potion/internal/domain/user" "github.com/haydenhargreaves/Potion/internal/infrastructure/auth" "golang.org/x/oauth2" ) // NOTE: HOW THIS WORKS // // I need to store the refresh token along side the user in the DB. // Create a "session token" (cookie) with an expiration and store that in the DB and the session. // Send this session token along with all the requests (stored in the session) and when // authorization is needed, use it. // Once the expiration of MY token expires, prompt the user to log back in. // // So what is the point of the Google refresh token? Well, its not really useful right now, but if // we need to perform Google actions, we can use it to get more access tokens, which are needed for // the Google actions. Currently, I have no need for it, but it will be stored anyway. // // ------------------------------------------------------------------------------------------------ // GoogleLogin generates a URL which is used to redirect the user to the Google sign in page. This // URL is in the Google domain and is not coupled with this application. The data from this URL will // be passed into a callback and work to complete the Google OAuth workflow. func GoogleLogin(ctx *gin.Context) string { url := auth.GoogleAuthConfig.AuthCodeURL( "randomstate", oauth2.AccessTypeOffline, oauth2.ApprovalForce, ) return url } // GoogleCallback accepts the data from the Google login endpoint and uses it to fetch the users // data. The data is then used to log the user in or create an account. // // TODO: The repository implementation is not yet done. func GoogleCallback(ctx *gin.Context) (domain.GoogleUserInfo, error) { var ( state string = ctx.Query("state") code string = ctx.Query("code") ) // Ensure the state matches, prevents M.I.T.M. attacks if state != "randomstate" { return domain.GoogleUserInfo{}, fmt.Errorf("States don't match, received %s", state) } // Get access token from Google token, err := auth.GoogleAuthConfig.Exchange(context.Background(), code) if err != nil { return domain.GoogleUserInfo{}, fmt.Errorf("Code exchange failed: %s", err.Error()) } googleUserInfo, err := auth.GetUserData(token.AccessToken) if err != nil { return domain.GoogleUserInfo{}, err } // TODO: Need to hit the repository to store the required data in the user table // temporary return googleUserInfo, nil }