153 lines
4.1 KiB
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
|
|
}
|