chore: add comments to code

This commit is contained in:
Stavros
2025-02-08 12:33:58 +02:00
parent e09f241364
commit 7a3a463489
17 changed files with 485 additions and 92 deletions

View File

@@ -8,36 +8,45 @@ import (
"github.com/rs/zerolog/log"
)
// We are assuming that the generic provider will return a JSON object with an email field
type GenericUserInfoResponse struct {
Email string `json:"email"`
}
func GetGenericEmail(client *http.Client, url string) (string, error) {
// Using the oauth client get the user info url
res, resErr := client.Get(url)
// Check if there was an error
if resErr != nil {
return "", resErr
}
log.Debug().Msg("Got response from generic provider")
// Read the body of the response
body, bodyErr := io.ReadAll(res.Body)
// Check if there was an error
if bodyErr != nil {
return "", bodyErr
}
log.Debug().Msg("Read body from generic provider")
// Parse the body into a user struct
var user GenericUserInfoResponse
// Unmarshal the body into the user struct
jsonErr := json.Unmarshal(body, &user)
// Check if there was an error
if jsonErr != nil {
return "", jsonErr
}
log.Debug().Msg("Parsed user from generic provider")
// Return the email
return user.Email, nil
}

View File

@@ -9,47 +9,58 @@ import (
"github.com/rs/zerolog/log"
)
// Github has a different response than the generic provider
type GithubUserInfoResponse []struct {
Email string `json:"email"`
Primary bool `json:"primary"`
}
// The scopes required for the github provider
func GithubScopes() []string {
return []string{"user:email"}
}
func GetGithubEmail(client *http.Client) (string, error) {
// Get the user emails from github using the oauth http client
res, resErr := client.Get("https://api.github.com/user/emails")
// Check if there was an error
if resErr != nil {
return "", resErr
}
log.Debug().Msg("Got response from github")
// Read the body of the response
body, bodyErr := io.ReadAll(res.Body)
// Check if there was an error
if bodyErr != nil {
return "", bodyErr
}
log.Debug().Msg("Read body from github")
// Parse the body into a user struct
var emails GithubUserInfoResponse
// Unmarshal the body into the user struct
jsonErr := json.Unmarshal(body, &emails)
// Check if there was an error
if jsonErr != nil {
return "", jsonErr
}
log.Debug().Msg("Parsed emails from github")
// Find and return the primary email
for _, email := range emails {
if email.Primary {
return email.Email, nil
}
}
// User does not have a primary email?
return "", errors.New("no primary email found")
}

View File

@@ -8,40 +8,50 @@ import (
"github.com/rs/zerolog/log"
)
// Google works the same as the generic provider
type GoogleUserInfoResponse struct {
Email string `json:"email"`
}
// The scopes required for the google provider
func GoogleScopes() []string {
return []string{"https://www.googleapis.com/auth/userinfo.email"}
}
func GetGoogleEmail(client *http.Client) (string, error) {
// Get the user info from google using the oauth http client
res, resErr := client.Get("https://www.googleapis.com/userinfo/v2/me")
// Check if there was an error
if resErr != nil {
return "", resErr
}
log.Debug().Msg("Got response from google")
// Read the body of the response
body, bodyErr := io.ReadAll(res.Body)
// Check if there was an error
if bodyErr != nil {
return "", bodyErr
}
log.Debug().Msg("Read body from google")
// Parse the body into a user struct
var user GoogleUserInfoResponse
// Unmarshal the body into the user struct
jsonErr := json.Unmarshal(body, &user)
// Check if there was an error
if jsonErr != nil {
return "", jsonErr
}
log.Debug().Msg("Parsed user from google")
// Return the email
return user.Email, nil
}

View File

@@ -25,8 +25,11 @@ type Providers struct {
}
func (providers *Providers) Init() {
// If we have a client id and secret for github, initialize the oauth provider
if providers.Config.GithubClientId != "" && providers.Config.GithubClientSecret != "" {
log.Info().Msg("Initializing Github OAuth")
// Create a new oauth provider with the github config
providers.Github = oauth.NewOAuth(oauth2.Config{
ClientID: providers.Config.GithubClientId,
ClientSecret: providers.Config.GithubClientSecret,
@@ -34,10 +37,16 @@ func (providers *Providers) Init() {
Scopes: GithubScopes(),
Endpoint: endpoints.GitHub,
})
// Initialize the oauth provider
providers.Github.Init()
}
// If we have a client id and secret for google, initialize the oauth provider
if providers.Config.GoogleClientId != "" && providers.Config.GoogleClientSecret != "" {
log.Info().Msg("Initializing Google OAuth")
// Create a new oauth provider with the google config
providers.Google = oauth.NewOAuth(oauth2.Config{
ClientID: providers.Config.GoogleClientId,
ClientSecret: providers.Config.GoogleClientSecret,
@@ -45,10 +54,15 @@ func (providers *Providers) Init() {
Scopes: GoogleScopes(),
Endpoint: endpoints.Google,
})
// Initialize the oauth provider
providers.Google.Init()
}
if providers.Config.TailscaleClientId != "" && providers.Config.TailscaleClientSecret != "" {
log.Info().Msg("Initializing Tailscale OAuth")
// Create a new oauth provider with the tailscale config
providers.Tailscale = oauth.NewOAuth(oauth2.Config{
ClientID: providers.Config.TailscaleClientId,
ClientSecret: providers.Config.TailscaleClientSecret,
@@ -56,10 +70,16 @@ func (providers *Providers) Init() {
Scopes: TailscaleScopes(),
Endpoint: TailscaleEndpoint,
})
// Initialize the oauth provider
providers.Tailscale.Init()
}
// If we have a client id and secret for generic oauth, initialize the oauth provider
if providers.Config.GenericClientId != "" && providers.Config.GenericClientSecret != "" {
log.Info().Msg("Initializing Generic OAuth")
// Create a new oauth provider with the generic config
providers.Generic = oauth.NewOAuth(oauth2.Config{
ClientID: providers.Config.GenericClientId,
ClientSecret: providers.Config.GenericClientSecret,
@@ -70,11 +90,14 @@ func (providers *Providers) Init() {
TokenURL: providers.Config.GenericTokenURL,
},
})
// Initialize the oauth provider
providers.Generic.Init()
}
}
func (providers *Providers) GetProvider(provider string) *oauth.OAuth {
// Return the provider based on the provider string
switch provider {
case "github":
return providers.Github
@@ -90,58 +113,103 @@ func (providers *Providers) GetProvider(provider string) *oauth.OAuth {
}
func (providers *Providers) GetUser(provider string) (string, error) {
// Get the email from the provider
switch provider {
case "github":
// If the github provider is not configured, return an error
if providers.Github == nil {
log.Debug().Msg("Github provider not configured")
return "", nil
}
// Get the client from the github provider
client := providers.Github.GetClient()
log.Debug().Msg("Got client from github")
// Get the email from the github provider
email, emailErr := GetGithubEmail(client)
// Check if there was an error
if emailErr != nil {
return "", emailErr
}
log.Debug().Msg("Got email from github")
// Return the email
return email, nil
case "google":
// If the google provider is not configured, return an error
if providers.Google == nil {
log.Debug().Msg("Google provider not configured")
return "", nil
}
// Get the client from the google provider
client := providers.Google.GetClient()
log.Debug().Msg("Got client from google")
// Get the email from the google provider
email, emailErr := GetGoogleEmail(client)
// Check if there was an error
if emailErr != nil {
return "", emailErr
}
log.Debug().Msg("Got email from google")
// Return the email
return email, nil
case "tailscale":
// If the tailscale provider is not configured, return an error
if providers.Tailscale == nil {
log.Debug().Msg("Tailscale provider not configured")
return "", nil
}
// Get the client from the tailscale provider
client := providers.Tailscale.GetClient()
log.Debug().Msg("Got client from tailscale")
// Get the email from the tailscale provider
email, emailErr := GetTailscaleEmail(client)
// Check if there was an error
if emailErr != nil {
return "", emailErr
}
log.Debug().Msg("Got email from tailscale")
// Return the email
return email, nil
case "generic":
// If the generic provider is not configured, return an error
if providers.Generic == nil {
log.Debug().Msg("Generic provider not configured")
return "", nil
}
// Get the client from the generic provider
client := providers.Generic.GetClient()
log.Debug().Msg("Got client from generic")
// Get the email from the generic provider
email, emailErr := GetGenericEmail(client, providers.Config.GenericUserURL)
// Check if there was an error
if emailErr != nil {
return "", emailErr
}
log.Debug().Msg("Got email from generic")
// Return the email
return email, nil
default:
return "", nil
@@ -149,6 +217,7 @@ func (providers *Providers) GetUser(provider string) (string, error) {
}
func (provider *Providers) GetConfiguredProviders() []string {
// Create a list of the configured providers
providers := []string{}
if provider.Github != nil {
providers = append(providers, "github")

View File

@@ -9,48 +9,60 @@ import (
"golang.org/x/oauth2"
)
// The tailscale email is the loginName
type TailscaleUser struct {
LoginName string `json:"loginName"`
}
// The response from the tailscale user info endpoint
type TailscaleUserInfoResponse struct {
Users []TailscaleUser `json:"users"`
}
// The scopes required for the tailscale provider
func TailscaleScopes() []string {
return []string{"users:read"}
}
// The tailscale endpoint
var TailscaleEndpoint = oauth2.Endpoint{
TokenURL: "https://api.tailscale.com/api/v2/oauth/token",
}
func GetTailscaleEmail(client *http.Client) (string, error) {
// Get the user info from tailscale using the oauth http client
res, resErr := client.Get("https://api.tailscale.com/api/v2/tailnet/-/users")
// Check if there was an error
if resErr != nil {
return "", resErr
}
log.Debug().Msg("Got response from tailscale")
// Read the body of the response
body, bodyErr := io.ReadAll(res.Body)
// Check if there was an error
if bodyErr != nil {
return "", bodyErr
}
log.Debug().Msg("Read body from tailscale")
// Parse the body into a user struct
var users TailscaleUserInfoResponse
// Unmarshal the body into the user struct
jsonErr := json.Unmarshal(body, &users)
// Check if there was an error
if jsonErr != nil {
return "", jsonErr
}
log.Debug().Msg("Parsed users from tailscale")
// Return the email of the first user
return users.Users[0].LoginName, nil
}