Hayden Hargreaves a9cdc25adf (FEAT): Implemented the first stages of Google OAuth.
All that's left is the UI and repository implementation.
2025-06-13 22:50:46 -07:00

62 lines
2.1 KiB
Go

package auth
import (
"encoding/json"
"fmt"
"io"
"net/http"
domain "github.com/haydenhargreaves/Potion/internal/domain/user"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
)
// GoogleAuthConfig is a global variable that stores the current state of the Google configuration.
// NewGoogleConfig should be called before this value is accessed, or the application will panic
// to prevent a null reference.
var GoogleAuthConfig oauth2.Config
// NewGOogleConfig creates a google authentication configuration. The configuration is set as a
// global variable which can be used by importing this module. The configuration is used to query
// the google OAuth API and collect user data.
//
// This function should be called before any calls to the Google API are made, otherwise a null
// value will be accessed and the call will panic.
//
// The global variable is returned by this function but is not needed.
func NewGoogleConfig(redirectUrl, clientId, clientSecret string, scope []string) oauth2.Config {
GoogleAuthConfig = oauth2.Config{
RedirectURL: redirectUrl,
ClientID: clientId,
ClientSecret: clientSecret,
Scopes: scope,
Endpoint: google.Endpoint,
}
return GoogleAuthConfig
}
// GetUserData accepts a access token and calls the Google OAuth API to receive the respective user
// data. Any errors that occur will be wrapped and returned to the caller.
func GetUserData(accessToken string) (domain.GoogleUserInfo, error) {
googleApiUrl := fmt.Sprintf("https://www.googleapis.com/oauth2/v2/userinfo?access_token=%s", accessToken)
resp, err := http.Get(googleApiUrl)
if err != nil {
return domain.GoogleUserInfo{}, fmt.Errorf("Failed to fetch user info from Google: %s", err.Error())
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return domain.GoogleUserInfo{}, fmt.Errorf("Failed to read body from response: %s", err.Error())
}
var googleUserInfo domain.GoogleUserInfo
if err := json.Unmarshal(body, &googleUserInfo); err != nil {
return domain.GoogleUserInfo{}, fmt.Errorf("Failed to parser response: %s", err.Error())
}
return googleUserInfo, nil
}