diff --git a/controller/config/config.go b/controller/config/config.go index 564af677..1f09d0c5 100644 --- a/controller/config/config.go +++ b/controller/config/config.go @@ -22,6 +22,7 @@ type Config struct { Bridge *metrics.BridgeConfig Endpoint *EndpointConfig Email *emailUi.Config + Invites *InvitesConfig Limits *limits.Config Maintenance *MaintenanceConfig Metrics *metrics.Config @@ -33,11 +34,8 @@ type Config struct { } type AdminConfig struct { - InvitesOpen bool - InviteTokenStrategy string - InviteTokenContact string - Secrets []string `cf:"+secret"` - TouLink string + Secrets []string `cf:"+secret"` + TouLink string } type EndpointConfig struct { @@ -45,6 +43,12 @@ type EndpointConfig struct { Port int } +type InvitesConfig struct { + InvitesOpen bool + TokenStrategy string + TokenContact string +} + type MaintenanceConfig struct { ResetPassword *ResetPasswordMaintenanceConfig Registration *RegistrationMaintenanceConfig diff --git a/controller/configuration.go b/controller/configuration.go index 73ea42ad..de104469 100644 --- a/controller/configuration.go +++ b/controller/configuration.go @@ -21,20 +21,22 @@ func newConfigurationHandler(cfg *config.Config) *configurationHandler { func (ch *configurationHandler) Handle(_ metadata.ConfigurationParams) middleware.Responder { data := &rest_model_zrok.Configuration{ Version: build.String(), - InvitesOpen: cfg.Admin != nil && cfg.Admin.InvitesOpen, - RequiresInviteToken: cfg.Registration != nil && cfg.Admin.InviteTokenStrategy == "store", + InvitesOpen: cfg.Invites != nil && cfg.Invites.InvitesOpen, + RequiresInviteToken: cfg.Invites != nil && cfg.Invites.TokenStrategy == "store", } if cfg.Admin != nil { data.TouLink = cfg.Admin.TouLink - data.InviteTokenContact = cfg.Admin.InviteTokenContact - if cfg.Passwords != nil { - data.PasswordRequirements = &rest_model_zrok.PasswordRequirements{ - Length: int64(cfg.Passwords.Length), - RequireCapital: cfg.Passwords.RequireCapital, - RequireNumeric: cfg.Passwords.RequireNumeric, - RequireSpecial: cfg.Passwords.RequireSpecial, - ValidSpecialCharacters: cfg.Passwords.ValidSpecialCharacters, - } + } + if cfg.Invites != nil { + data.InviteTokenContact = cfg.Invites.TokenContact + } + if cfg.Passwords != nil { + data.PasswordRequirements = &rest_model_zrok.PasswordRequirements{ + Length: int64(cfg.Passwords.Length), + RequireCapital: cfg.Passwords.RequireCapital, + RequireNumeric: cfg.Passwords.RequireNumeric, + RequireSpecial: cfg.Passwords.RequireSpecial, + ValidSpecialCharacters: cfg.Passwords.ValidSpecialCharacters, } } return metadata.NewConfigurationOK().WithPayload(data) diff --git a/controller/invite.go b/controller/invite.go index d8badfde..f2d194e9 100644 --- a/controller/invite.go +++ b/controller/invite.go @@ -20,6 +20,10 @@ func newInviteHandler(cfg *config.Config) *inviteHandler { } func (h *inviteHandler) Handle(params account.InviteParams) middleware.Responder { + if h.cfg.Invites == nil || !h.cfg.Invites.InvitesOpen { + logrus.Warn("not accepting invites; attempt from '%v'", params.Body.Email) + return account.NewInviteBadRequest() + } if params.Body == nil || params.Body.Email == "" { logrus.Errorf("missing email") return account.NewInviteBadRequest() @@ -38,7 +42,7 @@ func (h *inviteHandler) Handle(params account.InviteParams) middleware.Responder } defer func() { _ = tx.Rollback() }() - if h.cfg.Admin != nil && h.cfg.Admin.InviteTokenStrategy == "store" { + if h.cfg.Invites != nil && h.cfg.Invites.TokenStrategy == "store" { inviteToken, err := str.FindInviteTokenByToken(params.Body.Token, tx) if err != nil { logrus.Errorf("cannot get invite token '%v' for '%v': %v", params.Body.Token, params.Body.Email, err) diff --git a/etc/ctrl.yml b/etc/ctrl.yml index 6c8f5e62..c88a4023 100644 --- a/etc/ctrl.yml +++ b/etc/ctrl.yml @@ -23,18 +23,6 @@ admin: # If `tou_link` is present, the frontend will display the "Terms of Use" link on the login and registration forms # tou_link: 'Terms and Conditions' - # - # To allow open invites to your `zrok` instance, set `invites_open` to `true` - # - invites_open: true - # - # Set `token_strategy` to `store` to require an invite token. - # - #token_strategy: store - # - # Set `invite_token_contact` to include an email address or a URL where an invite token can be requested - # - invite_token_contact: invites@zrok.io # The `bridge` section configures the `zrok controller metrics bridge`, specifying the source and sink where OpenZiti # `fabric.usage` events are consumed and then sent into `zrok`. For production environments, we recommend that you use @@ -65,6 +53,23 @@ email: password: "" from: ziggy@zrok.io +# Invites +# +invites: + # + # Setting `invites_open` to `true` will allow your service instance to allow users to request invites. + # + invites_open: false + # + # Setting `token_strategy` to `store` will use the `invite_tokens` table in the database for available invite tokens. + # + token_strategy: store + # + # Setting `token_contact` to something other than an empty string will show the contact information in the + # `zrok invite` command. + # + token_contact: invite@zrok.io + # Service instance limits configuration. # # See `docs/guides/metrics-and-limits/configuring-limits.md` for details.