Skip to content

Commit

Permalink
take multi-token auth config instead of individual variables (#117)
Browse files Browse the repository at this point in the history
* take multi-token auth config instead of individual variables

* simplify conditionorc environment variables
  • Loading branch information
DoctorVin authored Oct 11, 2023
1 parent ce8c4a6 commit 6d0c0e8
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 61 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ multistage-image:
--build-arg BUILD_DATE=$(BUILD_DATE) --label org.label-schema.schema-version=1.0 \
--label org.label-schema.vcs-ref=$(GIT_COMMIT_FULL) --label=org.label-schema.vcs-url=$(REPO)

push-ms-devel: multistage-image
docker tag ${DOCKER_IMAGE}:latest localhost:5001/conditionorc:latest
docker push localhost:5001/conditionorc:latest
kind load docker-image localhost:5001/conditionorc:latest

# https://gist.github.com/prwhite/8168133
# COLORS
Expand Down
12 changes: 11 additions & 1 deletion cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import (
"github.com/metal-toolbox/conditionorc/internal/server"
"github.com/metal-toolbox/conditionorc/internal/store"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"go.hollow.sh/toolbox/events"
"go.hollow.sh/toolbox/ginjwt"
)

var shutdownTimeout = 10 * time.Second
Expand Down Expand Up @@ -56,7 +58,13 @@ var cmdServer = &cobra.Command{
server.WithStore(repository),
server.WithStreamBroker(streamBroker),
server.WithConditionDefinitions(app.Config.ConditionDefinitions),
server.WithAuthMiddlewareConfig(app.Config.APIServerJWTAuth),
}

if viper.GetViper().GetBool("oidc.enabled") {
app.Logger.Info("enabling OIDC")
options = append(options, server.WithAuthMiddlewareConfig(app.Config.APIServerJWTAuth))
} else {
app.Logger.Info("OIDC disabled")
}

srv := server.New(options...)
Expand All @@ -83,4 +91,6 @@ var cmdServer = &cobra.Command{
// install command flags
func init() {
rootCmd.AddCommand(cmdServer)
cmdServer.Flags().Bool("oidc", true, "use oidc auth")
ginjwt.BindFlagFromViperInst(viper.GetViper(), "oidc.enabled", cmdServer.Flags().Lookup("oidc"))
}
53 changes: 7 additions & 46 deletions internal/app/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,11 @@ type Configuration struct {
StoreKind model.StoreKind `mapstructure:"store_kind"`

// APIServerJWTAuth sets the JWT verification configuration for the conditionorc API service.
APIServerJWTAuth *ginjwt.AuthConfig `mapstructure:"ginjwt_auth"`
APIServerJWTAuth []ginjwt.AuthConfig `mapstructure:"ginjwt_auth"`

// ConditionDefinitions holds one or more condition definitions the conditionorc API, orchestrator support.
ConditionDefinitions rctypes.Definitions `mapstructure:"conditions"`

// APIOIDCOptions defines configuration to handle OIDC authn/authz for conditions API clients.
APIOIDCOptions APIOIDCOptions `mapstructure:"api_server_oidc"`

// ServerserviceOptions defines the serverservice client configuration parameters
//
// This parameter is required when StoreKind is set to serverservice.
Expand All @@ -66,17 +63,6 @@ type Configuration struct {
Notifications notify.Configuration `mapstructure:"notifications"`
}

// APIOIDCOptions defines configuration to handle OIDC authn/authz for conditions API clients.
type APIOIDCOptions struct {
EnabledOAuth bool `mapstructure:"enable_oauth"`
IssuerEndpoint string `mapstructure:"issuer_endpoint"`
AudienceEndpoint string `mapstructure:"audience_endpoint"`
JWKSURI string `mapstructure:"jwksuri"`
RolesClaim string `mapstructure:"roles_claim"`
UsernameClaim string `mapstructure:"username_claim"`
}

// ServerserviceOptions defines configuration for the Serverservice client.
// https://github.com/metal-toolbox/hollow-serverservice
type ServerserviceOptions struct {
EndpointURL *url.URL
Expand Down Expand Up @@ -173,41 +159,16 @@ var (
)

func (a *App) apiServerJWTAuthParams() error {
if !a.v.GetBool("api.oidc.enabled") {
if !a.v.GetBool("oidc.enabled") {
return nil
}

errOIDCAuthParams := errors.New("conditions API OIDC Auth params not defined")

required := []string{
"audience.endpoint",
"issuer.endpoint",
"jwksuri",
"claims.roles",
"claims.username",
}

var unset []string

for _, k := range required {
if a.v.GetString("api.oidc."+k) == "" {
unset = append(unset, "api.oidc."+k)
}
}

if len(unset) > 0 {
return errors.Wrap(errOIDCAuthParams, strings.Join(unset, ","))
}

a.Config.APIServerJWTAuth = &ginjwt.AuthConfig{
Enabled: true,
Audience: a.v.GetString("api.oidc.audience.endpoint"),
Issuer: a.v.GetString("api.oidc.issuer.endpoint"),
JWKSURI: a.v.GetString("api.oidc.jwksuri"),
LogFields: a.v.GetStringSlice("api.oidc.log"),
RolesClaim: a.v.GetString("api.oidc.claims.roles"),
UsernameClaim: a.v.GetString("api.oidc.claims.username"),
cfgs, err := ginjwt.GetAuthConfigsFromFlags(a.v)
if err != nil {
return err
}
a.Logger.WithField("config.length", len(cfgs)).Debug("oidc configurations found")
a.Config.APIServerJWTAuth = cfgs

return nil
}
Expand Down
10 changes: 5 additions & 5 deletions internal/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ var (
// Server type holds attributes of the condition orc server
type Server struct {
// Logger is the app logger
authMWConfig *ginjwt.AuthConfig
authMWConfigs []ginjwt.AuthConfig
logger *logrus.Logger
streamBroker events.Stream
listenAddress string
Expand Down Expand Up @@ -78,9 +78,9 @@ func WithConditionDefinitions(defs rctypes.Definitions) Option {
}

// WithAuthMiddlewareConfig sets the auth middleware configuration.
func WithAuthMiddlewareConfig(authMWConfig *ginjwt.AuthConfig) Option {
func WithAuthMiddlewareConfig(authMWConfigs []ginjwt.AuthConfig) Option {
return func(s *Server) {
s.authMWConfig = authMWConfig
s.authMWConfigs = authMWConfigs
}
}

Expand All @@ -104,8 +104,8 @@ func New(opts ...Option) *http.Server {
}

// add auth middleware
if s.authMWConfig != nil && s.authMWConfig.Enabled {
authMW, err := ginjwt.NewAuthMiddleware(*s.authMWConfig)
if s.authMWConfigs != nil {
authMW, err := ginjwt.NewMultiTokenMiddlewareFromConfigs(s.authMWConfigs...)
if err != nil {
s.logger.Fatal("failed to initialize auth middleware: ", "error", err)
}
Expand Down
13 changes: 4 additions & 9 deletions pkg/api/v1/routes/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"go.hollow.sh/toolbox/events"
"go.hollow.sh/toolbox/ginjwt"
"go.hollow.sh/toolbox/ginauth"

v1types "github.com/metal-toolbox/conditionorc/pkg/api/v1/types"
rctypes "github.com/metal-toolbox/rivets/condition"
Expand All @@ -28,7 +28,7 @@ var ginNoOp = func(_ *gin.Context) {

// Routes type sets up the conditionorc API router routes.
type Routes struct {
authMW *ginjwt.Middleware
authMW *ginauth.MultiTokenMiddleware
repository store.Repository
streamBroker events.Stream
conditionDefinitions rctypes.Definitions
Expand Down Expand Up @@ -60,7 +60,7 @@ func WithLogger(logger *logrus.Logger) Option {
}

// WithAuthMiddleware sets the auth middleware on the routes type.
func WithAuthMiddleware(authMW *ginjwt.Middleware) Option {
func WithAuthMiddleware(authMW *ginauth.MultiTokenMiddleware) Option {
return func(r *Routes) {
r.authMW = authMW
}
Expand Down Expand Up @@ -115,15 +115,10 @@ func (r *Routes) composeAuthHandler(scopes []string) gin.HandlerFunc {
if r.authMW == nil {
return ginNoOp
}
return r.authMW.RequiredScopes(scopes)
return r.authMW.AuthRequired(scopes)
}

func (r *Routes) Routes(g *gin.RouterGroup) {
// JWT token verification.
if r.authMW != nil {
g.Use(r.authMW.AuthRequired())
}

servers := g.Group("/servers/:uuid")
{
// /servers/:uuid/state/:conditionState
Expand Down

0 comments on commit 6d0c0e8

Please sign in to comment.