From 8610cf944a725fafc14a3874ded8e52433a2c84e Mon Sep 17 00:00:00 2001 From: Michael Quigley Date: Thu, 1 Dec 2022 14:48:23 -0500 Subject: [PATCH] add admin support to rest_model_zrok.Principal; authenticator (#116) --- controller/config.go | 5 +++++ controller/controller.go | 2 +- controller/util.go | 29 ++++++++++++++++++++++++++--- rest_model_zrok/principal.go | 3 +++ rest_server_zrok/embedded_spec.go | 6 ++++++ specs/zrok.yml | 2 ++ ui/src/api/types.js | 1 + 7 files changed, 44 insertions(+), 4 deletions(-) diff --git a/controller/config.go b/controller/config.go index 5ac9533e..feebdc1b 100644 --- a/controller/config.go +++ b/controller/config.go @@ -10,6 +10,7 @@ const ConfigVersion = 1 type Config struct { V int + Admin *AdminConfig Endpoint *EndpointConfig Proxy *ProxyConfig Email *EmailConfig @@ -20,6 +21,10 @@ type Config struct { Influx *InfluxConfig } +type AdminConfig struct { + Secrets []string `cf:"+secret"` +} + type EndpointConfig struct { Host string Port int diff --git a/controller/controller.go b/controller/controller.go index 9919aac1..0ce4afae 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -26,7 +26,7 @@ func Run(inCfg *Config) error { } api := operations.NewZrokAPI(swaggerSpec) - api.KeyAuth = ZrokAuthenticate + api.KeyAuth = newZrokAuthenticator(cfg).authenticate api.AccountInviteHandler = newInviteHandler() api.AccountLoginHandler = account.LoginHandlerFunc(loginHandler) api.AccountRegisterHandler = newRegisterHandler() diff --git a/controller/util.go b/controller/util.go index 5eebd54a..54fa1f6f 100644 --- a/controller/util.go +++ b/controller/util.go @@ -13,20 +13,43 @@ import ( "strings" ) -func ZrokAuthenticate(token string) (*rest_model_zrok.Principal, error) { +type zrokAuthenticator struct { + cfg *Config +} + +func newZrokAuthenticator(cfg *Config) *zrokAuthenticator { + return &zrokAuthenticator{cfg} +} + +func (za *zrokAuthenticator) authenticate(token string) (*rest_model_zrok.Principal, error) { tx, err := str.Begin() if err != nil { return nil, err } defer func() { _ = tx.Rollback() }() + if a, err := str.FindAccountWithToken(token, tx); err == nil { - principal := rest_model_zrok.Principal{ + principal := &rest_model_zrok.Principal{ ID: int64(a.Id), Token: a.Token, Email: a.Email, } - return &principal, nil + return principal, nil } else { + // check for admin secret + if cfg.Admin != nil { + for _, secret := range cfg.Admin.Secrets { + if token == secret { + principal := &rest_model_zrok.Principal{ + ID: int64(-1), + Admin: true, + } + return principal, nil + } + } + } + + // no match return nil, errors2.New(401, "invalid api key") } } diff --git a/rest_model_zrok/principal.go b/rest_model_zrok/principal.go index dcda9328..d39106fb 100644 --- a/rest_model_zrok/principal.go +++ b/rest_model_zrok/principal.go @@ -17,6 +17,9 @@ import ( // swagger:model principal type Principal struct { + // admin + Admin bool `json:"admin,omitempty"` + // email Email string `json:"email,omitempty"` diff --git a/rest_server_zrok/embedded_spec.go b/rest_server_zrok/embedded_spec.go index 99567025..73017072 100644 --- a/rest_server_zrok/embedded_spec.go +++ b/rest_server_zrok/embedded_spec.go @@ -599,6 +599,9 @@ func init() { "principal": { "type": "object", "properties": { + "admin": { + "type": "boolean" + }, "email": { "type": "string" }, @@ -1383,6 +1386,9 @@ func init() { "principal": { "type": "object", "properties": { + "admin": { + "type": "boolean" + }, "email": { "type": "string" }, diff --git a/specs/zrok.yml b/specs/zrok.yml index 6c21ed9e..e72adadf 100644 --- a/specs/zrok.yml +++ b/specs/zrok.yml @@ -399,6 +399,8 @@ definitions: type: string token: type: string + admin: + type: boolean registerRequest: type: object diff --git a/ui/src/api/types.js b/ui/src/api/types.js index bf86fd89..780f9aff 100644 --- a/ui/src/api/types.js +++ b/ui/src/api/types.js @@ -90,6 +90,7 @@ * @property {number} id * @property {string} email * @property {string} token + * @property {boolean} admin */ /**