clearcase/internal/setup/auth_handler.go

153 lines
4.1 KiB
Go

package setup
import (
"context"
"crypto/rand"
"fmt"
"forge.cadoles.com/wpetit/clearcase/internal/config"
"forge.cadoles.com/wpetit/clearcase/internal/http/handler/webui/auth"
"github.com/gorilla/sessions"
"github.com/markbates/goth"
"github.com/markbates/goth/gothic"
"github.com/markbates/goth/providers/gitea"
"github.com/markbates/goth/providers/github"
"github.com/markbates/goth/providers/google"
"github.com/markbates/goth/providers/openidConnect"
"github.com/pkg/errors"
)
func NewAuthHandlerFromConfig(ctx context.Context, conf *config.Config) (*auth.Handler, error) {
// Configure sessions store
keyPairs := make([][]byte, 0)
if len(conf.HTTP.Session.Keys) == 0 {
key, err := getRandomBytes(32)
if err != nil {
return nil, errors.Wrap(err, "could not generate cookie signing key")
}
keyPairs = append(keyPairs, key)
} else {
for _, k := range conf.HTTP.Session.Keys {
keyPairs = append(keyPairs, []byte(k))
}
}
sessionStore := sessions.NewCookieStore(keyPairs...)
sessionStore.MaxAge(int(conf.HTTP.Session.Cookie.MaxAge))
sessionStore.Options.Path = conf.HTTP.Session.Cookie.Path
sessionStore.Options.HttpOnly = conf.HTTP.Session.Cookie.HTTPOnly
sessionStore.Options.Secure = conf.HTTP.Session.Cookie.Secure
// Configure providers
gothProviders := make([]goth.Provider, 0)
providers := make([]auth.Provider, 0)
if conf.Auth.Providers.Google.Key != "" && conf.Auth.Providers.Google.Secret != "" {
googleProvider := google.New(
conf.Auth.Providers.Google.Key,
conf.Auth.Providers.Google.Secret,
fmt.Sprintf("%s/auth/providers/google/callback", conf.HTTP.BaseURL),
conf.Auth.Providers.Google.Scopes...,
)
gothProviders = append(gothProviders, googleProvider)
providers = append(providers, auth.Provider{
ID: googleProvider.Name(),
Label: "Google",
Icon: "fa-google",
})
}
if conf.Auth.Providers.Github.Key != "" && conf.Auth.Providers.Github.Secret != "" {
githubProvider := github.New(
conf.Auth.Providers.Github.Key,
conf.Auth.Providers.Github.Secret,
fmt.Sprintf("%s/auth/providers/github/callback", conf.HTTP.BaseURL),
conf.Auth.Providers.Github.Scopes...,
)
gothProviders = append(gothProviders, githubProvider)
providers = append(providers, auth.Provider{
ID: githubProvider.Name(),
Label: "Github",
Icon: "fa-github",
})
}
if conf.Auth.Providers.Gitea.Key != "" && conf.Auth.Providers.Gitea.Secret != "" {
giteaProvider := gitea.NewCustomisedURL(
conf.Auth.Providers.Gitea.Key,
conf.Auth.Providers.Gitea.Secret,
fmt.Sprintf("%s/auth/providers/gitea/callback", conf.HTTP.BaseURL),
conf.Auth.Providers.Gitea.AuthURL,
conf.Auth.Providers.Gitea.TokenURL,
conf.Auth.Providers.Gitea.ProfileURL,
conf.Auth.Providers.Gitea.Scopes...,
)
gothProviders = append(gothProviders, giteaProvider)
providers = append(providers, auth.Provider{
ID: giteaProvider.Name(),
Label: conf.Auth.Providers.Gitea.Label,
Icon: "fa-git-alt",
})
}
if conf.Auth.Providers.OIDC.Key != "" && conf.Auth.Providers.OIDC.Secret != "" {
oidcProvider, err := openidConnect.New(
conf.Auth.Providers.OIDC.Key,
conf.Auth.Providers.OIDC.Secret,
fmt.Sprintf("%s/auth/providers/openid-connect/callback", conf.HTTP.BaseURL),
conf.Auth.Providers.OIDC.DiscoveryURL,
conf.Auth.Providers.OIDC.Scopes...,
)
if err != nil {
return nil, errors.Wrap(err, "could not configure oidc provider")
}
gothProviders = append(gothProviders, oidcProvider)
providers = append(providers, auth.Provider{
ID: oidcProvider.Name(),
Label: conf.Auth.Providers.OIDC.Label,
Icon: conf.Auth.Providers.OIDC.Icon,
})
}
goth.UseProviders(gothProviders...)
gothic.Store = sessionStore
opts := []auth.OptionFunc{
auth.WithProviders(providers...),
}
auth := auth.NewHandler(
sessionStore,
opts...,
)
return auth, nil
}
func getRandomBytes(n int) ([]byte, error) {
data := make([]byte, n)
read, err := rand.Read(data)
if err != nil {
return nil, errors.WithStack(err)
}
if read != n {
return nil, errors.Errorf("could not read %d bytes", n)
}
return data, nil
}