From cd08b98a0a9e6fc6bbc82d990e0012f8b6fc70d4 Mon Sep 17 00:00:00 2001 From: Cam Otts Date: Tue, 31 Jan 2023 12:44:03 -0600 Subject: [PATCH] added configuration endpoint which sends tou link and version info --- cmd/zrok/enable.go | 8 +- controller/config.go | 1 + controller/configuration.go | 30 ++++ controller/controller.go | 1 + .../metadata/configuration_parameters.go | 128 ++++++++++++++++++ .../metadata/configuration_responses.go | 98 ++++++++++++++ rest_client_zrok/metadata/metadata_client.go | 40 ++++++ rest_model_zrok/configuration.go | 53 ++++++++ rest_server_zrok/embedded_spec.go | 54 ++++++++ .../operations/metadata/configuration.go | 56 ++++++++ .../metadata/configuration_parameters.go | 46 +++++++ .../metadata/configuration_responses.go | 59 ++++++++ .../metadata/configuration_urlbuilder.go | 87 ++++++++++++ rest_server_zrok/operations/zrok_api.go | 12 ++ specs/zrok.yml | 19 +++ ui/src/api/metadata.js | 11 ++ ui/src/api/types.js | 8 ++ ui/src/console/login/Login.js | 19 ++- ui/src/register/SetPasswordForm.js | 19 ++- 19 files changed, 742 insertions(+), 7 deletions(-) create mode 100644 controller/configuration.go create mode 100644 rest_client_zrok/metadata/configuration_parameters.go create mode 100644 rest_client_zrok/metadata/configuration_responses.go create mode 100644 rest_model_zrok/configuration.go create mode 100644 rest_server_zrok/operations/metadata/configuration.go create mode 100644 rest_server_zrok/operations/metadata/configuration_parameters.go create mode 100644 rest_server_zrok/operations/metadata/configuration_responses.go create mode 100644 rest_server_zrok/operations/metadata/configuration_urlbuilder.go diff --git a/cmd/zrok/enable.go b/cmd/zrok/enable.go index 5938a5a8..3b52039c 100644 --- a/cmd/zrok/enable.go +++ b/cmd/zrok/enable.go @@ -2,6 +2,10 @@ package main import ( "fmt" + "os" + user2 "os/user" + "time" + "github.com/charmbracelet/bubbles/spinner" tea "github.com/charmbracelet/bubbletea" httptransport "github.com/go-openapi/runtime/client" @@ -11,9 +15,6 @@ import ( "github.com/openziti/zrok/zrokdir" "github.com/shirou/gopsutil/v3/host" "github.com/spf13/cobra" - "os" - user2 "os/user" - "time" ) func init() { @@ -89,6 +90,7 @@ func (cmd *enableCommand) run(_ *cobra.Command, args []string) { }() resp, err := zrok.Environment.Enable(req, auth) + //Switch on err type (401, 400, 500, etc...) if err != nil { time.Sleep(250 * time.Millisecond) prg.Send(fmt.Sprintf("the zrok service returned an error: %v\n", err)) diff --git a/controller/config.go b/controller/config.go index 01f87e68..80aab2ef 100644 --- a/controller/config.go +++ b/controller/config.go @@ -27,6 +27,7 @@ type Config struct { type AdminConfig struct { Secrets []string `cf:"+secret"` + TouLink string } type EndpointConfig struct { diff --git a/controller/configuration.go b/controller/configuration.go new file mode 100644 index 00000000..89071813 --- /dev/null +++ b/controller/configuration.go @@ -0,0 +1,30 @@ +package controller + +import ( + "github.com/go-openapi/runtime/middleware" + "github.com/openziti/zrok/build" + "github.com/openziti/zrok/rest_model_zrok" + "github.com/openziti/zrok/rest_server_zrok/operations/metadata" +) + +type configurationHandler struct { + cfg *Config +} + +func newConfigurationHandler(cfg *Config) *configurationHandler { + return &configurationHandler{ + cfg: cfg, + } +} + +func (ch *configurationHandler) Handle(_ metadata.ConfigurationParams) middleware.Responder { + tou := "" + if cfg.Admin != nil { + tou = cfg.Admin.TouLink + } + data := &rest_model_zrok.Configuration{ + Version: build.String(), + TouLink: tou, + } + return metadata.NewConfigurationOK().WithPayload(data) +} diff --git a/controller/controller.go b/controller/controller.go index 394698a7..509f80b8 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -42,6 +42,7 @@ func Run(inCfg *Config) error { api.AdminUpdateFrontendHandler = newUpdateFrontendHandler() api.EnvironmentEnableHandler = newEnableHandler(cfg.Limits) api.EnvironmentDisableHandler = newDisableHandler() + api.MetadataConfigurationHandler = newConfigurationHandler(cfg) api.MetadataGetEnvironmentDetailHandler = newEnvironmentDetailHandler() api.MetadataGetShareDetailHandler = newShareDetailHandler() api.MetadataOverviewHandler = metadata.OverviewHandlerFunc(overviewHandler) diff --git a/rest_client_zrok/metadata/configuration_parameters.go b/rest_client_zrok/metadata/configuration_parameters.go new file mode 100644 index 00000000..ca0f881d --- /dev/null +++ b/rest_client_zrok/metadata/configuration_parameters.go @@ -0,0 +1,128 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package metadata + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" +) + +// NewConfigurationParams creates a new ConfigurationParams object, +// with the default timeout for this client. +// +// Default values are not hydrated, since defaults are normally applied by the API server side. +// +// To enforce default values in parameter, use SetDefaults or WithDefaults. +func NewConfigurationParams() *ConfigurationParams { + return &ConfigurationParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewConfigurationParamsWithTimeout creates a new ConfigurationParams object +// with the ability to set a timeout on a request. +func NewConfigurationParamsWithTimeout(timeout time.Duration) *ConfigurationParams { + return &ConfigurationParams{ + timeout: timeout, + } +} + +// NewConfigurationParamsWithContext creates a new ConfigurationParams object +// with the ability to set a context for a request. +func NewConfigurationParamsWithContext(ctx context.Context) *ConfigurationParams { + return &ConfigurationParams{ + Context: ctx, + } +} + +// NewConfigurationParamsWithHTTPClient creates a new ConfigurationParams object +// with the ability to set a custom HTTPClient for a request. +func NewConfigurationParamsWithHTTPClient(client *http.Client) *ConfigurationParams { + return &ConfigurationParams{ + HTTPClient: client, + } +} + +/* +ConfigurationParams contains all the parameters to send to the API endpoint + + for the configuration operation. + + Typically these are written to a http.Request. +*/ +type ConfigurationParams struct { + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the configuration params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *ConfigurationParams) WithDefaults() *ConfigurationParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the configuration params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *ConfigurationParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the configuration params +func (o *ConfigurationParams) WithTimeout(timeout time.Duration) *ConfigurationParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the configuration params +func (o *ConfigurationParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the configuration params +func (o *ConfigurationParams) WithContext(ctx context.Context) *ConfigurationParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the configuration params +func (o *ConfigurationParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the configuration params +func (o *ConfigurationParams) WithHTTPClient(client *http.Client) *ConfigurationParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the configuration params +func (o *ConfigurationParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WriteToRequest writes these params to a swagger request +func (o *ConfigurationParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/rest_client_zrok/metadata/configuration_responses.go b/rest_client_zrok/metadata/configuration_responses.go new file mode 100644 index 00000000..22e28b70 --- /dev/null +++ b/rest_client_zrok/metadata/configuration_responses.go @@ -0,0 +1,98 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package metadata + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "fmt" + "io" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + + "github.com/openziti/zrok/rest_model_zrok" +) + +// ConfigurationReader is a Reader for the Configuration structure. +type ConfigurationReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *ConfigurationReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { + switch response.Code() { + case 200: + result := NewConfigurationOK() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + default: + return nil, runtime.NewAPIError("response status code does not match any response statuses defined for this endpoint in the swagger spec", response, response.Code()) + } +} + +// NewConfigurationOK creates a ConfigurationOK with default headers values +func NewConfigurationOK() *ConfigurationOK { + return &ConfigurationOK{} +} + +/* +ConfigurationOK describes a response with status code 200, with default header values. + +current configuration +*/ +type ConfigurationOK struct { + Payload *rest_model_zrok.Configuration +} + +// IsSuccess returns true when this configuration o k response has a 2xx status code +func (o *ConfigurationOK) IsSuccess() bool { + return true +} + +// IsRedirect returns true when this configuration o k response has a 3xx status code +func (o *ConfigurationOK) IsRedirect() bool { + return false +} + +// IsClientError returns true when this configuration o k response has a 4xx status code +func (o *ConfigurationOK) IsClientError() bool { + return false +} + +// IsServerError returns true when this configuration o k response has a 5xx status code +func (o *ConfigurationOK) IsServerError() bool { + return false +} + +// IsCode returns true when this configuration o k response a status code equal to that given +func (o *ConfigurationOK) IsCode(code int) bool { + return code == 200 +} + +func (o *ConfigurationOK) Error() string { + return fmt.Sprintf("[GET /configuration][%d] configurationOK %+v", 200, o.Payload) +} + +func (o *ConfigurationOK) String() string { + return fmt.Sprintf("[GET /configuration][%d] configurationOK %+v", 200, o.Payload) +} + +func (o *ConfigurationOK) GetPayload() *rest_model_zrok.Configuration { + return o.Payload +} + +func (o *ConfigurationOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(rest_model_zrok.Configuration) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} diff --git a/rest_client_zrok/metadata/metadata_client.go b/rest_client_zrok/metadata/metadata_client.go index 751fae78..0253fbf0 100644 --- a/rest_client_zrok/metadata/metadata_client.go +++ b/rest_client_zrok/metadata/metadata_client.go @@ -30,6 +30,8 @@ type ClientOption func(*runtime.ClientOperation) // ClientService is the interface for Client methods type ClientService interface { + Configuration(params *ConfigurationParams, opts ...ClientOption) (*ConfigurationOK, error) + GetEnvironmentDetail(params *GetEnvironmentDetailParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetEnvironmentDetailOK, error) GetShareDetail(params *GetShareDetailParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetShareDetailOK, error) @@ -41,6 +43,44 @@ type ClientService interface { SetTransport(transport runtime.ClientTransport) } +/* +Configuration configuration API +*/ +func (a *Client) Configuration(params *ConfigurationParams, opts ...ClientOption) (*ConfigurationOK, error) { + // TODO: Validate the params before sending + if params == nil { + params = NewConfigurationParams() + } + op := &runtime.ClientOperation{ + ID: "configuration", + Method: "GET", + PathPattern: "/configuration", + ProducesMediaTypes: []string{"application/zrok.v1+json"}, + ConsumesMediaTypes: []string{"application/zrok.v1+json"}, + Schemes: []string{"http"}, + Params: params, + Reader: &ConfigurationReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + success, ok := result.(*ConfigurationOK) + if ok { + return success, nil + } + // unexpected success response + // safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue + msg := fmt.Sprintf("unexpected success response for configuration: API contract not enforced by server. Client expected to get an error, but got: %T", result) + panic(msg) +} + /* GetEnvironmentDetail get environment detail API */ diff --git a/rest_model_zrok/configuration.go b/rest_model_zrok/configuration.go new file mode 100644 index 00000000..60d2618a --- /dev/null +++ b/rest_model_zrok/configuration.go @@ -0,0 +1,53 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package rest_model_zrok + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// Configuration configuration +// +// swagger:model configuration +type Configuration struct { + + // tou link + TouLink string `json:"touLink,omitempty"` + + // version + Version string `json:"version,omitempty"` +} + +// Validate validates this configuration +func (m *Configuration) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this configuration based on context it is used +func (m *Configuration) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *Configuration) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *Configuration) UnmarshalBinary(b []byte) error { + var res Configuration + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/rest_server_zrok/embedded_spec.go b/rest_server_zrok/embedded_spec.go index 159eab97..15b6324f 100644 --- a/rest_server_zrok/embedded_spec.go +++ b/rest_server_zrok/embedded_spec.go @@ -74,6 +74,22 @@ func init() { } } }, + "/configuration": { + "get": { + "tags": [ + "metadata" + ], + "operationId": "configuration", + "responses": { + "200": { + "description": "current configuration", + "schema": { + "$ref": "#/definitions/configuration" + } + } + } + } + }, "/detail/environment/{envZId}": { "get": { "security": [ @@ -846,6 +862,17 @@ func init() { } } }, + "configuration": { + "type": "object", + "properties": { + "touLink": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, "createFrontendRequest": { "type": "object", "properties": { @@ -1319,6 +1346,22 @@ func init() { } } }, + "/configuration": { + "get": { + "tags": [ + "metadata" + ], + "operationId": "configuration", + "responses": { + "200": { + "description": "current configuration", + "schema": { + "$ref": "#/definitions/configuration" + } + } + } + } + }, "/detail/environment/{envZId}": { "get": { "security": [ @@ -2091,6 +2134,17 @@ func init() { } } }, + "configuration": { + "type": "object", + "properties": { + "touLink": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, "createFrontendRequest": { "type": "object", "properties": { diff --git a/rest_server_zrok/operations/metadata/configuration.go b/rest_server_zrok/operations/metadata/configuration.go new file mode 100644 index 00000000..463090a1 --- /dev/null +++ b/rest_server_zrok/operations/metadata/configuration.go @@ -0,0 +1,56 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package metadata + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime/middleware" +) + +// ConfigurationHandlerFunc turns a function with the right signature into a configuration handler +type ConfigurationHandlerFunc func(ConfigurationParams) middleware.Responder + +// Handle executing the request and returning a response +func (fn ConfigurationHandlerFunc) Handle(params ConfigurationParams) middleware.Responder { + return fn(params) +} + +// ConfigurationHandler interface for that can handle valid configuration params +type ConfigurationHandler interface { + Handle(ConfigurationParams) middleware.Responder +} + +// NewConfiguration creates a new http.Handler for the configuration operation +func NewConfiguration(ctx *middleware.Context, handler ConfigurationHandler) *Configuration { + return &Configuration{Context: ctx, Handler: handler} +} + +/* + Configuration swagger:route GET /configuration metadata configuration + +Configuration configuration API +*/ +type Configuration struct { + Context *middleware.Context + Handler ConfigurationHandler +} + +func (o *Configuration) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + *r = *rCtx + } + var Params = NewConfigurationParams() + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params) // actually handle the request + o.Context.Respond(rw, r, route.Produces, route, res) + +} diff --git a/rest_server_zrok/operations/metadata/configuration_parameters.go b/rest_server_zrok/operations/metadata/configuration_parameters.go new file mode 100644 index 00000000..413cb5d2 --- /dev/null +++ b/rest_server_zrok/operations/metadata/configuration_parameters.go @@ -0,0 +1,46 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package metadata + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime/middleware" +) + +// NewConfigurationParams creates a new ConfigurationParams object +// +// There are no default values defined in the spec. +func NewConfigurationParams() ConfigurationParams { + + return ConfigurationParams{} +} + +// ConfigurationParams contains all the bound params for the configuration operation +// typically these are obtained from a http.Request +// +// swagger:parameters configuration +type ConfigurationParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewConfigurationParams() beforehand. +func (o *ConfigurationParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/rest_server_zrok/operations/metadata/configuration_responses.go b/rest_server_zrok/operations/metadata/configuration_responses.go new file mode 100644 index 00000000..15ddb646 --- /dev/null +++ b/rest_server_zrok/operations/metadata/configuration_responses.go @@ -0,0 +1,59 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package metadata + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" + + "github.com/openziti/zrok/rest_model_zrok" +) + +// ConfigurationOKCode is the HTTP code returned for type ConfigurationOK +const ConfigurationOKCode int = 200 + +/* +ConfigurationOK current configuration + +swagger:response configurationOK +*/ +type ConfigurationOK struct { + + /* + In: Body + */ + Payload *rest_model_zrok.Configuration `json:"body,omitempty"` +} + +// NewConfigurationOK creates ConfigurationOK with default headers values +func NewConfigurationOK() *ConfigurationOK { + + return &ConfigurationOK{} +} + +// WithPayload adds the payload to the configuration o k response +func (o *ConfigurationOK) WithPayload(payload *rest_model_zrok.Configuration) *ConfigurationOK { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the configuration o k response +func (o *ConfigurationOK) SetPayload(payload *rest_model_zrok.Configuration) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *ConfigurationOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(200) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} diff --git a/rest_server_zrok/operations/metadata/configuration_urlbuilder.go b/rest_server_zrok/operations/metadata/configuration_urlbuilder.go new file mode 100644 index 00000000..68dc42b4 --- /dev/null +++ b/rest_server_zrok/operations/metadata/configuration_urlbuilder.go @@ -0,0 +1,87 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package metadata + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" +) + +// ConfigurationURL generates an URL for the configuration operation +type ConfigurationURL struct { + _basePath string +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *ConfigurationURL) WithBasePath(bp string) *ConfigurationURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *ConfigurationURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *ConfigurationURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/configuration" + + _basePath := o._basePath + if _basePath == "" { + _basePath = "/api/v1" + } + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *ConfigurationURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *ConfigurationURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *ConfigurationURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on ConfigurationURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on ConfigurationURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *ConfigurationURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/rest_server_zrok/operations/zrok_api.go b/rest_server_zrok/operations/zrok_api.go index 1eb7af7d..3424c976 100644 --- a/rest_server_zrok/operations/zrok_api.go +++ b/rest_server_zrok/operations/zrok_api.go @@ -52,6 +52,9 @@ func NewZrokAPI(spec *loads.Document) *ZrokAPI { ShareAccessHandler: share.AccessHandlerFunc(func(params share.AccessParams, principal *rest_model_zrok.Principal) middleware.Responder { return middleware.NotImplemented("operation share.Access has not yet been implemented") }), + MetadataConfigurationHandler: metadata.ConfigurationHandlerFunc(func(params metadata.ConfigurationParams) middleware.Responder { + return middleware.NotImplemented("operation metadata.Configuration has not yet been implemented") + }), AdminCreateFrontendHandler: admin.CreateFrontendHandlerFunc(func(params admin.CreateFrontendParams, principal *rest_model_zrok.Principal) middleware.Responder { return middleware.NotImplemented("operation admin.CreateFrontend has not yet been implemented") }), @@ -170,6 +173,8 @@ type ZrokAPI struct { // ShareAccessHandler sets the operation handler for the access operation ShareAccessHandler share.AccessHandler + // MetadataConfigurationHandler sets the operation handler for the configuration operation + MetadataConfigurationHandler metadata.ConfigurationHandler // AdminCreateFrontendHandler sets the operation handler for the create frontend operation AdminCreateFrontendHandler admin.CreateFrontendHandler // AdminCreateIdentityHandler sets the operation handler for the create identity operation @@ -298,6 +303,9 @@ func (o *ZrokAPI) Validate() error { if o.ShareAccessHandler == nil { unregistered = append(unregistered, "share.AccessHandler") } + if o.MetadataConfigurationHandler == nil { + unregistered = append(unregistered, "metadata.ConfigurationHandler") + } if o.AdminCreateFrontendHandler == nil { unregistered = append(unregistered, "admin.CreateFrontendHandler") } @@ -467,6 +475,10 @@ func (o *ZrokAPI) initHandlerCache() { o.handlers["POST"] = make(map[string]http.Handler) } o.handlers["POST"]["/access"] = share.NewAccess(o.context, o.ShareAccessHandler) + if o.handlers["GET"] == nil { + o.handlers["GET"] = make(map[string]http.Handler) + } + o.handlers["GET"]["/configuration"] = metadata.NewConfiguration(o.context, o.MetadataConfigurationHandler) if o.handlers["POST"] == nil { o.handlers["POST"] = make(map[string]http.Handler) } diff --git a/specs/zrok.yml b/specs/zrok.yml index d6896cf9..5bc2131b 100644 --- a/specs/zrok.yml +++ b/specs/zrok.yml @@ -314,6 +314,17 @@ paths: # # metadata # + /configuration: + get: + tags: + - metadata + operationId: configuration + responses: + 200: + description: current configuration + schema: + $ref: "#/definitions/configuration" + /detail/environment/{envZId}: get: tags: @@ -531,6 +542,14 @@ definitions: password: type: string + configuration: + type: object + properties: + version: + type: string + touLink: + type: string + createFrontendRequest: type: object properties: diff --git a/ui/src/api/metadata.js b/ui/src/api/metadata.js index 8d3d763f..16b2d86e 100644 --- a/ui/src/api/metadata.js +++ b/ui/src/api/metadata.js @@ -2,6 +2,12 @@ // Auto-generated, edits will be overwritten import * as gateway from './gateway' +/** + */ +export function configuration() { + return gateway.request(configurationOperation) +} + /** * @param {string} envZId * @return {Promise} ok @@ -40,6 +46,11 @@ export function version() { return gateway.request(versionOperation) } +const configurationOperation = { + path: '/configuration', + method: 'get' +} + const getEnvironmentDetailOperation = { path: '/detail/environment/{envZId}', method: 'get', diff --git a/ui/src/api/types.js b/ui/src/api/types.js index dac35539..1aec6b55 100644 --- a/ui/src/api/types.js +++ b/ui/src/api/types.js @@ -24,6 +24,14 @@ * @property {string} password */ +/** + * @typedef configuration + * @memberof module:types + * + * @property {string} version + * @property {string} touLink + */ + /** * @typedef createFrontendRequest * @memberof module:types diff --git a/ui/src/console/login/Login.js b/ui/src/console/login/Login.js index c3b3be59..5ace21dd 100644 --- a/ui/src/console/login/Login.js +++ b/ui/src/console/login/Login.js @@ -1,5 +1,6 @@ -import {useState} from "react"; +import {useEffect, useState} from "react"; import * as account from '../../api/account'; +import * as metadata from "../../api/metadata" import {Button, Container, Form, Row} from "react-bootstrap"; import { Link } from "react-router-dom"; @@ -7,9 +8,23 @@ const Login = (props) => { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [message, setMessage] = useState(); + const [tou, setTou] = useState(); const errorMessage =

Login Failed!

; + useEffect(() => { + metadata.configuration().then(resp => { + console.log(resp) + if(!resp.error) { + if (resp.data.touLink !== null && resp.data.touLink.trim() !== "") { + setTou(
Please read the Terms of Use
) + } + } + }).catch(err => { + console.log("err", err); + }); + }, []) + const handleSubmit = async e => { e.preventDefault() console.log(email, password); @@ -65,7 +80,7 @@ const Login = (props) => { value={password} /> - + {tou}
diff --git a/ui/src/register/SetPasswordForm.js b/ui/src/register/SetPasswordForm.js index bc2fb78d..77cf8276 100644 --- a/ui/src/register/SetPasswordForm.js +++ b/ui/src/register/SetPasswordForm.js @@ -1,5 +1,6 @@ -import React, {useState} from "react"; +import React, {useEffect, useState} from "react"; import * as account from "../api/account"; +import * as metadata from "../api/metadata" import Success from "./Success"; import {Button, Container, Form, Row} from "react-bootstrap"; @@ -9,11 +10,25 @@ const SetPasswordForm = (props) => { const [message, setMessage] = useState(); const [authToken, setAuthToken] = useState(''); const [complete, setComplete] = useState(false); + const [tou, setTou] = useState(); const passwordMismatchMessage =

Entered passwords do not match!

const passwordTooShortMessage =

Entered password too short! (4 characters, minimum)

const registerFailed =

Account creation failed!

+ useEffect(() => { + metadata.configuration().then(resp => { + console.log(resp) + if(!resp.error) { + if (resp.data.touLink !== null && resp.data.touLink.trim() !== "") { + setTou(
Please read the Terms of Use
) + } + } + }).catch(err => { + console.log("err", err); + }); + }, []) + const handleSubmit = async e => { e.preventDefault(); if(confirm.length < 4) { @@ -74,7 +89,7 @@ const SetPasswordForm = (props) => { value={confirm} /> - + {tou}