woj-server/internal/web/oauth/service.go

96 lines
2.2 KiB
Go

package oauth
import (
"context"
"git.0x7f.app/WOJ/woj-server/internal/misc/config"
"git.0x7f.app/WOJ/woj-server/internal/misc/log"
"git.0x7f.app/WOJ/woj-server/internal/repo/cache"
"git.0x7f.app/WOJ/woj-server/internal/service/user"
"git.0x7f.app/WOJ/woj-server/internal/web/jwt"
"github.com/coreos/go-oidc/v3/oidc"
"github.com/gin-gonic/gin"
"github.com/samber/do"
"go.uber.org/zap"
"golang.org/x/oauth2"
)
type Service interface {
LoginHandler() gin.HandlerFunc
CallbackHandler() gin.HandlerFunc
IsEnabled() bool
GetLoginPath() string
GetCallbackPath() string
HealthCheck() error
}
const (
basePath = "/oauth"
callbackPath = basePath + "/callback"
loginPath = basePath + "/login"
)
func NewService(i *do.Injector) (Service, error) {
srv := &service{}
srv.log = do.MustInvoke[log.Service](i).GetLogger("oauth")
srv.jwt = do.MustInvoke[jwt.Service](i)
srv.user = do.MustInvoke[user.Service](i)
srv.cache = do.MustInvoke[cache.Service](i)
srv.enabled = false
conf := do.MustInvoke[config.Service](i).GetConfig()
if conf.WebServer.OAuth.Domain == "" {
return srv, srv.err
}
srv.provider, srv.err = oidc.NewProvider(context.Background(), conf.WebServer.OAuth.Domain)
if srv.err != nil {
srv.log.Error("failed to create oauth provider", zap.Error(srv.err), zap.String("domain", conf.WebServer.OAuth.Domain))
return srv, srv.err
}
srv.verifier = srv.provider.Verifier(&oidc.Config{ClientID: conf.WebServer.OAuth.ClientID})
srv.conf = oauth2.Config{
ClientID: conf.WebServer.OAuth.ClientID,
ClientSecret: conf.WebServer.OAuth.ClientSecret,
RedirectURL: conf.WebServer.PublicBase + callbackPath,
Endpoint: srv.provider.Endpoint(),
Scopes: []string{oidc.ScopeOpenID, "profile", "email", "roles"},
}
srv.enabled = true
return srv, srv.err
}
type service struct {
log *zap.Logger
jwt jwt.Service
user user.Service
cache cache.Service
provider *oidc.Provider
conf oauth2.Config
verifier *oidc.IDTokenVerifier
enabled bool
err error
}
func (s *service) IsEnabled() bool {
return s.enabled && s.err == nil
}
func (s *service) GetLoginPath() string {
return loginPath
}
func (s *service) GetCallbackPath() string {
return callbackPath
}
func (s *service) HealthCheck() error {
return s.err
}