From e5b749be71ed0310914ca68c0cdf67769a6787bb Mon Sep 17 00:00:00 2001 From: Cam Otts Date: Mon, 9 Jan 2023 11:00:37 -0600 Subject: [PATCH 01/13] initial rough pass for a stored token implementation --- bin/generate_rest.sh | 2 +- cmd/zrok/generate.go | 77 +++++++ controller/config.go | 1 + controller/controller.go | 3 +- controller/invite.go | 86 ++++++-- controller/store/invites.go | 61 ++++++ .../sql/postgresql/005_v0_3_0_invites.sql | 16 ++ .../store/sql/sqlite3/005_v0_3_0_invites.sql | 16 ++ go.mod | 3 +- go.sum | 2 - rest_client_zrok/invite/invite_client.go | 79 +++++++ .../invite/invite_generate_parameters.go | 150 +++++++++++++ .../invite/invite_generate_responses.go | 197 ++++++++++++++++++ rest_client_zrok/zrok_client.go | 5 + rest_model_zrok/invite_generate_request.go | 50 +++++ rest_server_zrok/embedded_spec.go | 78 +++++++ .../operations/invite/invite_generate.go | 56 +++++ .../invite/invite_generate_parameters.go | 76 +++++++ .../invite/invite_generate_responses.go | 87 ++++++++ .../invite/invite_generate_urlbuilder.go | 87 ++++++++ rest_server_zrok/operations/zrok_api.go | 13 ++ specs/zrok.yml | 29 +++ ui/src/api/invite.js | 24 +++ ui/src/api/types.js | 7 + 24 files changed, 1186 insertions(+), 19 deletions(-) create mode 100644 cmd/zrok/generate.go create mode 100644 controller/store/invites.go create mode 100644 controller/store/sql/postgresql/005_v0_3_0_invites.sql create mode 100644 controller/store/sql/sqlite3/005_v0_3_0_invites.sql create mode 100644 rest_client_zrok/invite/invite_client.go create mode 100644 rest_client_zrok/invite/invite_generate_parameters.go create mode 100644 rest_client_zrok/invite/invite_generate_responses.go create mode 100644 rest_model_zrok/invite_generate_request.go create mode 100644 rest_server_zrok/operations/invite/invite_generate.go create mode 100644 rest_server_zrok/operations/invite/invite_generate_parameters.go create mode 100644 rest_server_zrok/operations/invite/invite_generate_responses.go create mode 100644 rest_server_zrok/operations/invite/invite_generate_urlbuilder.go create mode 100644 ui/src/api/invite.js diff --git a/bin/generate_rest.sh b/bin/generate_rest.sh index 4a2625b3..18599d4f 100755 --- a/bin/generate_rest.sh +++ b/bin/generate_rest.sh @@ -27,4 +27,4 @@ swagger generate client -P rest_model_zrok.Principal -f "$zrokSpec" -c rest_clie echo "...generating js client" openapi -s specs/zrok.yml -o ui/src/api -l js -git co rest_server_zrok/configure_zrok.go +git checkout rest_server_zrok/configure_zrok.go diff --git a/cmd/zrok/generate.go b/cmd/zrok/generate.go new file mode 100644 index 00000000..4fce9500 --- /dev/null +++ b/cmd/zrok/generate.go @@ -0,0 +1,77 @@ +package main + +import ( + "fmt" + "strconv" + + "github.com/jaevor/go-nanoid" + "github.com/openziti-test-kitchen/zrok/rest_client_zrok/invite" + "github.com/openziti-test-kitchen/zrok/rest_model_zrok" + "github.com/openziti-test-kitchen/zrok/zrokdir" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(newGenerateCommand().cmd) +} + +type generateCommand struct { + cmd *cobra.Command +} + +func newGenerateCommand() *generateCommand { + cmd := &cobra.Command{ + Use: "generate ", + Short: "Generate invite tokens (default: 5)", + Args: cobra.RangeArgs(0, 1), + } + command := &generateCommand{cmd: cmd} + cmd.Run = command.run + return command +} + +func (cmd *generateCommand) run(_ *cobra.Command, args []string) { + var iterations int64 = 5 + if len(args) == 1 { + i, err := strconv.ParseInt(args[0], 10, 64) + if err != nil { + showError("unable to parse amount", err) + } + iterations = i + } + var err error + tokens := make([]string, iterations) + for i := 0; i < int(iterations); i++ { + tokens[i], err = createToken() + if err != nil { + showError("error creating token", err) + } + } + zrok, err := zrokdir.ZrokClient(apiEndpoint) + if err != nil { + if !panicInstead { + showError("error creating zrok api client", err) + } + panic(err) + } + req := invite.NewInviteGenerateParams() + req.Body = &rest_model_zrok.InviteGenerateRequest{ + Tokens: tokens, + } + _, err = zrok.Invite.InviteGenerate(req) + if err != nil { + if !panicInstead { + showError("error creating invite tokens", err) + } + panic(err) + } + fmt.Printf("generated %d tokens\n", len(tokens)) +} + +func createToken() (string, error) { + gen, err := nanoid.CustomASCII("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 12) + if err != nil { + return "", err + } + return gen(), nil +} diff --git a/controller/config.go b/controller/config.go index 929d72c2..c22c249f 100644 --- a/controller/config.go +++ b/controller/config.go @@ -39,6 +39,7 @@ type EmailConfig struct { type RegistrationConfig struct { EmailFrom string RegistrationUrlTemplate string + TokenStrategy string } type ZitiConfig struct { diff --git a/controller/controller.go b/controller/controller.go index 20acc667..dba22c01 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -26,7 +26,7 @@ func Run(inCfg *Config) error { api := operations.NewZrokAPI(swaggerSpec) api.KeyAuth = newZrokAuthenticator(cfg).authenticate - api.AccountInviteHandler = newInviteHandler() + api.AccountInviteHandler = newInviteHandler(cfg) api.AccountLoginHandler = account.LoginHandlerFunc(loginHandler) api.AccountRegisterHandler = newRegisterHandler() api.AccountVerifyHandler = newVerifyHandler() @@ -37,6 +37,7 @@ func Run(inCfg *Config) error { api.AdminUpdateFrontendHandler = newUpdateFrontendHandler() api.EnvironmentEnableHandler = newEnableHandler() api.EnvironmentDisableHandler = newDisableHandler() + api.InviteInviteGenerateHandler = newInviteGenerateHandler() api.MetadataGetEnvironmentDetailHandler = newEnvironmentDetailHandler() api.MetadataGetShareDetailHandler = newShareDetailHandler() api.MetadataOverviewHandler = metadata.OverviewHandlerFunc(overviewHandler) diff --git a/controller/invite.go b/controller/invite.go index 081e18cd..a45d7718 100644 --- a/controller/invite.go +++ b/controller/invite.go @@ -4,15 +4,19 @@ import ( "github.com/go-openapi/runtime/middleware" "github.com/openziti-test-kitchen/zrok/controller/store" "github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/account" + "github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/invite" "github.com/openziti-test-kitchen/zrok/util" "github.com/sirupsen/logrus" ) type inviteHandler struct { + cfg *Config } -func newInviteHandler() *inviteHandler { - return &inviteHandler{} +func newInviteHandler(cfg *Config) *inviteHandler { + return &inviteHandler{ + cfg: cfg, + } } func (self *inviteHandler) Handle(params account.InviteParams) middleware.Responder { @@ -25,17 +29,7 @@ func (self *inviteHandler) Handle(params account.InviteParams) middleware.Respon return account.NewInviteBadRequest() } logrus.Infof("received account request for email '%v'", params.Body.Email) - - token, err := createToken() - if err != nil { - logrus.Error(err) - return account.NewInviteInternalServerError() - } - ar := &store.AccountRequest{ - Token: token, - Email: params.Body.Email, - SourceAddress: params.HTTPRequest.RemoteAddr, - } + var token string tx, err := str.Begin() if err != nil { @@ -44,6 +38,31 @@ func (self *inviteHandler) Handle(params account.InviteParams) middleware.Respon } defer func() { _ = tx.Rollback() }() + if self.cfg.Registration.TokenStrategy == "store" { + invite, err := str.GetInvite(tx) + if err != nil { + logrus.Error(err) + return account.NewInviteInternalServerError() + } + invite.Status = store.INVITE_STATUS_TAKEN + if err := str.UpdateInvite(invite, tx); err != nil { + logrus.Error(err) + return account.NewInviteInternalServerError() + } + token = invite.Token + } else { + token, err = createToken() + if err != nil { + logrus.Error(err) + return account.NewInviteInternalServerError() + } + } + ar := &store.AccountRequest{ + Token: token, + Email: params.Body.Email, + SourceAddress: params.HTTPRequest.RemoteAddr, + } + if _, err := str.FindAccountWithEmail(params.Body.Email, tx); err == nil { logrus.Errorf("found account for '%v', cannot process account request", params.Body.Email) return account.NewInviteBadRequest() @@ -83,3 +102,44 @@ func (self *inviteHandler) Handle(params account.InviteParams) middleware.Respon return account.NewInviteCreated() } + +type inviteGenerateHandler struct { +} + +func newInviteGenerateHandler() *inviteGenerateHandler { + return &inviteGenerateHandler{} +} + +func (handler *inviteGenerateHandler) Handle(params invite.InviteGenerateParams) middleware.Responder { + if params.Body == nil || len(params.Body.Tokens) == 0 { + logrus.Error("missing tokens") + return invite.NewInviteGenerateBadRequest() + } + logrus.Infof("received invite generate request with %d tokens", len(params.Body.Tokens)) + + invites := make([]*store.Invite, len(params.Body.Tokens)) + for i, token := range params.Body.Tokens { + invites[i] = &store.Invite{ + Token: token, + Status: store.INVITE_STATUS_UNUSED, + } + } + tx, err := str.Begin() + if err != nil { + logrus.Error(err) + return invite.NewInviteGenerateInternalServerError() + } + defer func() { _ = tx.Rollback() }() + + if err := str.CreateInvites(invites, tx); err != nil { + logrus.Error(err) + return invite.NewInviteGenerateInternalServerError() + } + + if err := tx.Commit(); err != nil { + logrus.Errorf("error committing inviteGenerate request: %v", err) + return account.NewInviteInternalServerError() + } + + return invite.NewInviteGenerateCreated() +} diff --git a/controller/store/invites.go b/controller/store/invites.go new file mode 100644 index 00000000..257089ff --- /dev/null +++ b/controller/store/invites.go @@ -0,0 +1,61 @@ +package store + +import ( + "fmt" + "strings" + + "github.com/jmoiron/sqlx" + "github.com/pkg/errors" +) + +type Invite struct { + Model + Token string + Status string `db:"token_status"` +} + +const ( + INVITE_STATUS_UNUSED = "UNUSED" + INVITE_STATUS_TAKEN = "TAKEN" +) + +func (str *Store) CreateInvites(invites []*Invite, tx *sqlx.Tx) error { + sql := "insert into invites (token, token_status) values %s" + invs := make([]any, len(invites)*2) + queries := make([]string, len(invites)) + ct := 1 + for i, inv := range invites { + invs[i] = inv.Token + invs[i+1] = inv.Status + queries[i] = fmt.Sprintf("($%d, $%d)", ct, ct+1) + ct = ct + 2 + } + stmt, err := tx.Prepare(fmt.Sprintf(sql, strings.Join(queries, ","))) + if err != nil { + return errors.Wrap(err, "error preparing invites insert statement") + } + if _, err := stmt.Exec(invs...); err != nil { + return errors.Wrap(err, "error executing invites insert statement") + } + return nil +} + +func (str *Store) GetInvite(tx *sqlx.Tx) (*Invite, error) { + invite := &Invite{} + if err := tx.QueryRowx("select * from invites where token_status = $1 limit 1", INVITE_STATUS_UNUSED).StructScan(invite); err != nil { + return nil, errors.Wrap(err, "error getting unused invite") + } + return invite, nil +} + +func (str *Store) UpdateInvite(invite *Invite, tx *sqlx.Tx) error { + stmt, err := tx.Prepare("update invites set token = $1, token_status = $2") + if err != nil { + return errors.Wrap(err, "error perparing invites update statement") + } + _, err = stmt.Exec(invite.Token, invite.Status) + if err != nil { + return errors.Wrap(err, "error executing invites update statement") + } + return nil +} diff --git a/controller/store/sql/postgresql/005_v0_3_0_invites.sql b/controller/store/sql/postgresql/005_v0_3_0_invites.sql new file mode 100644 index 00000000..92894566 --- /dev/null +++ b/controller/store/sql/postgresql/005_v0_3_0_invites.sql @@ -0,0 +1,16 @@ +-- +migrate Up + +-- +-- invites +--- + +create table invites ( + id serial primary key, + token varchar(32) not null unique, + token_status varchar(1024) not null unique, + created_at timestamp not null default(current_timestamp), + updated_at timestamp not null default(current_timestamp), + + constraint chk_token check(token <> ''), + constraint chk_status check(token_status <> '') +); \ No newline at end of file diff --git a/controller/store/sql/sqlite3/005_v0_3_0_invites.sql b/controller/store/sql/sqlite3/005_v0_3_0_invites.sql new file mode 100644 index 00000000..92894566 --- /dev/null +++ b/controller/store/sql/sqlite3/005_v0_3_0_invites.sql @@ -0,0 +1,16 @@ +-- +migrate Up + +-- +-- invites +--- + +create table invites ( + id serial primary key, + token varchar(32) not null unique, + token_status varchar(1024) not null unique, + created_at timestamp not null default(current_timestamp), + updated_at timestamp not null default(current_timestamp), + + constraint chk_token check(token <> ''), + constraint chk_status check(token_status <> '') +); \ No newline at end of file diff --git a/go.mod b/go.mod index c6a3959a..b0bba662 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/iancoleman/strcase v0.2.0 github.com/influxdata/influxdb-client-go/v2 v2.11.0 github.com/jaevor/go-nanoid v1.3.0 + github.com/jedib0t/go-pretty/v6 v6.4.3 github.com/jessevdk/go-flags v1.5.0 github.com/jmoiron/sqlx v1.3.5 github.com/lib/pq v1.10.0 @@ -33,7 +34,6 @@ require ( github.com/spf13/cobra v1.5.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.1 - github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 github.com/wneessen/go-mail v0.2.7 golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 @@ -58,7 +58,6 @@ require ( github.com/google/uuid v1.3.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect - github.com/jedib0t/go-pretty/v6 v6.4.3 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect diff --git a/go.sum b/go.sum index a0feeb01..e3241d8d 100644 --- a/go.sum +++ b/go.sum @@ -520,8 +520,6 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 h1:xzABM9let0HLLqFypcxvLmlvEciCHL7+Lv+4vwZqecI= -github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569/go.mod h1:2Ly+NIftZN4de9zRmENdYbvPQeaVIYKWpLFStLFEBgI= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= diff --git a/rest_client_zrok/invite/invite_client.go b/rest_client_zrok/invite/invite_client.go new file mode 100644 index 00000000..f64b51ab --- /dev/null +++ b/rest_client_zrok/invite/invite_client.go @@ -0,0 +1,79 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package invite + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "fmt" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" +) + +// New creates a new invite API client. +func New(transport runtime.ClientTransport, formats strfmt.Registry) ClientService { + return &Client{transport: transport, formats: formats} +} + +/* +Client for invite API +*/ +type Client struct { + transport runtime.ClientTransport + formats strfmt.Registry +} + +// ClientOption is the option for Client methods +type ClientOption func(*runtime.ClientOperation) + +// ClientService is the interface for Client methods +type ClientService interface { + InviteGenerate(params *InviteGenerateParams, opts ...ClientOption) (*InviteGenerateCreated, error) + + SetTransport(transport runtime.ClientTransport) +} + +/* +InviteGenerate invite generate API +*/ +func (a *Client) InviteGenerate(params *InviteGenerateParams, opts ...ClientOption) (*InviteGenerateCreated, error) { + // TODO: Validate the params before sending + if params == nil { + params = NewInviteGenerateParams() + } + op := &runtime.ClientOperation{ + ID: "inviteGenerate", + Method: "POST", + PathPattern: "/invite/generate", + ProducesMediaTypes: []string{"application/zrok.v1+json"}, + ConsumesMediaTypes: []string{"application/zrok.v1+json"}, + Schemes: []string{"http"}, + Params: params, + Reader: &InviteGenerateReader{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.(*InviteGenerateCreated) + 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 inviteGenerate: API contract not enforced by server. Client expected to get an error, but got: %T", result) + panic(msg) +} + +// SetTransport changes the transport on the client +func (a *Client) SetTransport(transport runtime.ClientTransport) { + a.transport = transport +} diff --git a/rest_client_zrok/invite/invite_generate_parameters.go b/rest_client_zrok/invite/invite_generate_parameters.go new file mode 100644 index 00000000..e585966d --- /dev/null +++ b/rest_client_zrok/invite/invite_generate_parameters.go @@ -0,0 +1,150 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package invite + +// 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" + + "github.com/openziti-test-kitchen/zrok/rest_model_zrok" +) + +// NewInviteGenerateParams creates a new InviteGenerateParams 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 NewInviteGenerateParams() *InviteGenerateParams { + return &InviteGenerateParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewInviteGenerateParamsWithTimeout creates a new InviteGenerateParams object +// with the ability to set a timeout on a request. +func NewInviteGenerateParamsWithTimeout(timeout time.Duration) *InviteGenerateParams { + return &InviteGenerateParams{ + timeout: timeout, + } +} + +// NewInviteGenerateParamsWithContext creates a new InviteGenerateParams object +// with the ability to set a context for a request. +func NewInviteGenerateParamsWithContext(ctx context.Context) *InviteGenerateParams { + return &InviteGenerateParams{ + Context: ctx, + } +} + +// NewInviteGenerateParamsWithHTTPClient creates a new InviteGenerateParams object +// with the ability to set a custom HTTPClient for a request. +func NewInviteGenerateParamsWithHTTPClient(client *http.Client) *InviteGenerateParams { + return &InviteGenerateParams{ + HTTPClient: client, + } +} + +/* +InviteGenerateParams contains all the parameters to send to the API endpoint + + for the invite generate operation. + + Typically these are written to a http.Request. +*/ +type InviteGenerateParams struct { + + // Body. + Body *rest_model_zrok.InviteGenerateRequest + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the invite generate params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *InviteGenerateParams) WithDefaults() *InviteGenerateParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the invite generate params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *InviteGenerateParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the invite generate params +func (o *InviteGenerateParams) WithTimeout(timeout time.Duration) *InviteGenerateParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the invite generate params +func (o *InviteGenerateParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the invite generate params +func (o *InviteGenerateParams) WithContext(ctx context.Context) *InviteGenerateParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the invite generate params +func (o *InviteGenerateParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the invite generate params +func (o *InviteGenerateParams) WithHTTPClient(client *http.Client) *InviteGenerateParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the invite generate params +func (o *InviteGenerateParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithBody adds the body to the invite generate params +func (o *InviteGenerateParams) WithBody(body *rest_model_zrok.InviteGenerateRequest) *InviteGenerateParams { + o.SetBody(body) + return o +} + +// SetBody adds the body to the invite generate params +func (o *InviteGenerateParams) SetBody(body *rest_model_zrok.InviteGenerateRequest) { + o.Body = body +} + +// WriteToRequest writes these params to a swagger request +func (o *InviteGenerateParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + if o.Body != nil { + if err := r.SetBodyParam(o.Body); err != nil { + return err + } + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/rest_client_zrok/invite/invite_generate_responses.go b/rest_client_zrok/invite/invite_generate_responses.go new file mode 100644 index 00000000..763a70df --- /dev/null +++ b/rest_client_zrok/invite/invite_generate_responses.go @@ -0,0 +1,197 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package invite + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "fmt" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" +) + +// InviteGenerateReader is a Reader for the InviteGenerate structure. +type InviteGenerateReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *InviteGenerateReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { + switch response.Code() { + case 201: + result := NewInviteGenerateCreated() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + case 400: + result := NewInviteGenerateBadRequest() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 500: + result := NewInviteGenerateInternalServerError() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + 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()) + } +} + +// NewInviteGenerateCreated creates a InviteGenerateCreated with default headers values +func NewInviteGenerateCreated() *InviteGenerateCreated { + return &InviteGenerateCreated{} +} + +/* +InviteGenerateCreated describes a response with status code 201, with default header values. + +invitation tokens created +*/ +type InviteGenerateCreated struct { +} + +// IsSuccess returns true when this invite generate created response has a 2xx status code +func (o *InviteGenerateCreated) IsSuccess() bool { + return true +} + +// IsRedirect returns true when this invite generate created response has a 3xx status code +func (o *InviteGenerateCreated) IsRedirect() bool { + return false +} + +// IsClientError returns true when this invite generate created response has a 4xx status code +func (o *InviteGenerateCreated) IsClientError() bool { + return false +} + +// IsServerError returns true when this invite generate created response has a 5xx status code +func (o *InviteGenerateCreated) IsServerError() bool { + return false +} + +// IsCode returns true when this invite generate created response a status code equal to that given +func (o *InviteGenerateCreated) IsCode(code int) bool { + return code == 201 +} + +func (o *InviteGenerateCreated) Error() string { + return fmt.Sprintf("[POST /invite/generate][%d] inviteGenerateCreated ", 201) +} + +func (o *InviteGenerateCreated) String() string { + return fmt.Sprintf("[POST /invite/generate][%d] inviteGenerateCreated ", 201) +} + +func (o *InviteGenerateCreated) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + return nil +} + +// NewInviteGenerateBadRequest creates a InviteGenerateBadRequest with default headers values +func NewInviteGenerateBadRequest() *InviteGenerateBadRequest { + return &InviteGenerateBadRequest{} +} + +/* +InviteGenerateBadRequest describes a response with status code 400, with default header values. + +invitation tokens not created +*/ +type InviteGenerateBadRequest struct { +} + +// IsSuccess returns true when this invite generate bad request response has a 2xx status code +func (o *InviteGenerateBadRequest) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this invite generate bad request response has a 3xx status code +func (o *InviteGenerateBadRequest) IsRedirect() bool { + return false +} + +// IsClientError returns true when this invite generate bad request response has a 4xx status code +func (o *InviteGenerateBadRequest) IsClientError() bool { + return true +} + +// IsServerError returns true when this invite generate bad request response has a 5xx status code +func (o *InviteGenerateBadRequest) IsServerError() bool { + return false +} + +// IsCode returns true when this invite generate bad request response a status code equal to that given +func (o *InviteGenerateBadRequest) IsCode(code int) bool { + return code == 400 +} + +func (o *InviteGenerateBadRequest) Error() string { + return fmt.Sprintf("[POST /invite/generate][%d] inviteGenerateBadRequest ", 400) +} + +func (o *InviteGenerateBadRequest) String() string { + return fmt.Sprintf("[POST /invite/generate][%d] inviteGenerateBadRequest ", 400) +} + +func (o *InviteGenerateBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + return nil +} + +// NewInviteGenerateInternalServerError creates a InviteGenerateInternalServerError with default headers values +func NewInviteGenerateInternalServerError() *InviteGenerateInternalServerError { + return &InviteGenerateInternalServerError{} +} + +/* +InviteGenerateInternalServerError describes a response with status code 500, with default header values. + +internal server error +*/ +type InviteGenerateInternalServerError struct { +} + +// IsSuccess returns true when this invite generate internal server error response has a 2xx status code +func (o *InviteGenerateInternalServerError) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this invite generate internal server error response has a 3xx status code +func (o *InviteGenerateInternalServerError) IsRedirect() bool { + return false +} + +// IsClientError returns true when this invite generate internal server error response has a 4xx status code +func (o *InviteGenerateInternalServerError) IsClientError() bool { + return false +} + +// IsServerError returns true when this invite generate internal server error response has a 5xx status code +func (o *InviteGenerateInternalServerError) IsServerError() bool { + return true +} + +// IsCode returns true when this invite generate internal server error response a status code equal to that given +func (o *InviteGenerateInternalServerError) IsCode(code int) bool { + return code == 500 +} + +func (o *InviteGenerateInternalServerError) Error() string { + return fmt.Sprintf("[POST /invite/generate][%d] inviteGenerateInternalServerError ", 500) +} + +func (o *InviteGenerateInternalServerError) String() string { + return fmt.Sprintf("[POST /invite/generate][%d] inviteGenerateInternalServerError ", 500) +} + +func (o *InviteGenerateInternalServerError) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + return nil +} diff --git a/rest_client_zrok/zrok_client.go b/rest_client_zrok/zrok_client.go index 2aaac3fd..379b6717 100644 --- a/rest_client_zrok/zrok_client.go +++ b/rest_client_zrok/zrok_client.go @@ -13,6 +13,7 @@ import ( "github.com/openziti-test-kitchen/zrok/rest_client_zrok/account" "github.com/openziti-test-kitchen/zrok/rest_client_zrok/admin" "github.com/openziti-test-kitchen/zrok/rest_client_zrok/environment" + "github.com/openziti-test-kitchen/zrok/rest_client_zrok/invite" "github.com/openziti-test-kitchen/zrok/rest_client_zrok/metadata" "github.com/openziti-test-kitchen/zrok/rest_client_zrok/share" ) @@ -62,6 +63,7 @@ func New(transport runtime.ClientTransport, formats strfmt.Registry) *Zrok { cli.Account = account.New(transport, formats) cli.Admin = admin.New(transport, formats) cli.Environment = environment.New(transport, formats) + cli.Invite = invite.New(transport, formats) cli.Metadata = metadata.New(transport, formats) cli.Share = share.New(transport, formats) return cli @@ -114,6 +116,8 @@ type Zrok struct { Environment environment.ClientService + Invite invite.ClientService + Metadata metadata.ClientService Share share.ClientService @@ -127,6 +131,7 @@ func (c *Zrok) SetTransport(transport runtime.ClientTransport) { c.Account.SetTransport(transport) c.Admin.SetTransport(transport) c.Environment.SetTransport(transport) + c.Invite.SetTransport(transport) c.Metadata.SetTransport(transport) c.Share.SetTransport(transport) } diff --git a/rest_model_zrok/invite_generate_request.go b/rest_model_zrok/invite_generate_request.go new file mode 100644 index 00000000..f662c3d5 --- /dev/null +++ b/rest_model_zrok/invite_generate_request.go @@ -0,0 +1,50 @@ +// 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" +) + +// InviteGenerateRequest invite generate request +// +// swagger:model inviteGenerateRequest +type InviteGenerateRequest struct { + + // tokens + Tokens []string `json:"tokens"` +} + +// Validate validates this invite generate request +func (m *InviteGenerateRequest) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this invite generate request based on context it is used +func (m *InviteGenerateRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *InviteGenerateRequest) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *InviteGenerateRequest) UnmarshalBinary(b []byte) error { + var res InviteGenerateRequest + 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 704194d9..b8466732 100644 --- a/rest_server_zrok/embedded_spec.go +++ b/rest_server_zrok/embedded_spec.go @@ -431,6 +431,34 @@ func init() { } } }, + "/invite/generate": { + "post": { + "tags": [ + "invite" + ], + "operationId": "inviteGenerate", + "parameters": [ + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/inviteGenerateRequest" + } + } + ], + "responses": { + "201": { + "description": "invitation tokens created" + }, + "400": { + "description": "invitation tokens not created" + }, + "500": { + "description": "internal server error" + } + } + } + }, "/login": { "post": { "tags": [ @@ -859,6 +887,17 @@ func init() { "errorMessage": { "type": "string" }, + "inviteGenerateRequest": { + "type": "object", + "properties": { + "tokens": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, "inviteRequest": { "type": "object", "properties": { @@ -1549,6 +1588,34 @@ func init() { } } }, + "/invite/generate": { + "post": { + "tags": [ + "invite" + ], + "operationId": "inviteGenerate", + "parameters": [ + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/inviteGenerateRequest" + } + } + ], + "responses": { + "201": { + "description": "invitation tokens created" + }, + "400": { + "description": "invitation tokens not created" + }, + "500": { + "description": "internal server error" + } + } + } + }, "/login": { "post": { "tags": [ @@ -1977,6 +2044,17 @@ func init() { "errorMessage": { "type": "string" }, + "inviteGenerateRequest": { + "type": "object", + "properties": { + "tokens": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, "inviteRequest": { "type": "object", "properties": { diff --git a/rest_server_zrok/operations/invite/invite_generate.go b/rest_server_zrok/operations/invite/invite_generate.go new file mode 100644 index 00000000..7718776c --- /dev/null +++ b/rest_server_zrok/operations/invite/invite_generate.go @@ -0,0 +1,56 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package invite + +// 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" +) + +// InviteGenerateHandlerFunc turns a function with the right signature into a invite generate handler +type InviteGenerateHandlerFunc func(InviteGenerateParams) middleware.Responder + +// Handle executing the request and returning a response +func (fn InviteGenerateHandlerFunc) Handle(params InviteGenerateParams) middleware.Responder { + return fn(params) +} + +// InviteGenerateHandler interface for that can handle valid invite generate params +type InviteGenerateHandler interface { + Handle(InviteGenerateParams) middleware.Responder +} + +// NewInviteGenerate creates a new http.Handler for the invite generate operation +func NewInviteGenerate(ctx *middleware.Context, handler InviteGenerateHandler) *InviteGenerate { + return &InviteGenerate{Context: ctx, Handler: handler} +} + +/* + InviteGenerate swagger:route POST /invite/generate invite inviteGenerate + +InviteGenerate invite generate API +*/ +type InviteGenerate struct { + Context *middleware.Context + Handler InviteGenerateHandler +} + +func (o *InviteGenerate) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + *r = *rCtx + } + var Params = NewInviteGenerateParams() + 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/invite/invite_generate_parameters.go b/rest_server_zrok/operations/invite/invite_generate_parameters.go new file mode 100644 index 00000000..df0d20cc --- /dev/null +++ b/rest_server_zrok/operations/invite/invite_generate_parameters.go @@ -0,0 +1,76 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package invite + +// 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" + "github.com/go-openapi/runtime/middleware" + "github.com/go-openapi/validate" + + "github.com/openziti-test-kitchen/zrok/rest_model_zrok" +) + +// NewInviteGenerateParams creates a new InviteGenerateParams object +// +// There are no default values defined in the spec. +func NewInviteGenerateParams() InviteGenerateParams { + + return InviteGenerateParams{} +} + +// InviteGenerateParams contains all the bound params for the invite generate operation +// typically these are obtained from a http.Request +// +// swagger:parameters inviteGenerate +type InviteGenerateParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` + + /* + In: body + */ + Body *rest_model_zrok.InviteGenerateRequest +} + +// 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 NewInviteGenerateParams() beforehand. +func (o *InviteGenerateParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + if runtime.HasBody(r) { + defer r.Body.Close() + var body rest_model_zrok.InviteGenerateRequest + if err := route.Consumer.Consume(r.Body, &body); err != nil { + res = append(res, errors.NewParseError("body", "body", "", err)) + } else { + // validate body object + if err := body.Validate(route.Formats); err != nil { + res = append(res, err) + } + + ctx := validate.WithOperationRequest(r.Context()) + if err := body.ContextValidate(ctx, route.Formats); err != nil { + res = append(res, err) + } + + if len(res) == 0 { + o.Body = &body + } + } + } + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/rest_server_zrok/operations/invite/invite_generate_responses.go b/rest_server_zrok/operations/invite/invite_generate_responses.go new file mode 100644 index 00000000..5c08ddc6 --- /dev/null +++ b/rest_server_zrok/operations/invite/invite_generate_responses.go @@ -0,0 +1,87 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package invite + +// 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" +) + +// InviteGenerateCreatedCode is the HTTP code returned for type InviteGenerateCreated +const InviteGenerateCreatedCode int = 201 + +/* +InviteGenerateCreated invitation tokens created + +swagger:response inviteGenerateCreated +*/ +type InviteGenerateCreated struct { +} + +// NewInviteGenerateCreated creates InviteGenerateCreated with default headers values +func NewInviteGenerateCreated() *InviteGenerateCreated { + + return &InviteGenerateCreated{} +} + +// WriteResponse to the client +func (o *InviteGenerateCreated) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + + rw.WriteHeader(201) +} + +// InviteGenerateBadRequestCode is the HTTP code returned for type InviteGenerateBadRequest +const InviteGenerateBadRequestCode int = 400 + +/* +InviteGenerateBadRequest invitation tokens not created + +swagger:response inviteGenerateBadRequest +*/ +type InviteGenerateBadRequest struct { +} + +// NewInviteGenerateBadRequest creates InviteGenerateBadRequest with default headers values +func NewInviteGenerateBadRequest() *InviteGenerateBadRequest { + + return &InviteGenerateBadRequest{} +} + +// WriteResponse to the client +func (o *InviteGenerateBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + + rw.WriteHeader(400) +} + +// InviteGenerateInternalServerErrorCode is the HTTP code returned for type InviteGenerateInternalServerError +const InviteGenerateInternalServerErrorCode int = 500 + +/* +InviteGenerateInternalServerError internal server error + +swagger:response inviteGenerateInternalServerError +*/ +type InviteGenerateInternalServerError struct { +} + +// NewInviteGenerateInternalServerError creates InviteGenerateInternalServerError with default headers values +func NewInviteGenerateInternalServerError() *InviteGenerateInternalServerError { + + return &InviteGenerateInternalServerError{} +} + +// WriteResponse to the client +func (o *InviteGenerateInternalServerError) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + + rw.WriteHeader(500) +} diff --git a/rest_server_zrok/operations/invite/invite_generate_urlbuilder.go b/rest_server_zrok/operations/invite/invite_generate_urlbuilder.go new file mode 100644 index 00000000..ea9a40f1 --- /dev/null +++ b/rest_server_zrok/operations/invite/invite_generate_urlbuilder.go @@ -0,0 +1,87 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package invite + +// 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" +) + +// InviteGenerateURL generates an URL for the invite generate operation +type InviteGenerateURL 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 *InviteGenerateURL) WithBasePath(bp string) *InviteGenerateURL { + 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 *InviteGenerateURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *InviteGenerateURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/invite/generate" + + _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 *InviteGenerateURL) 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 *InviteGenerateURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *InviteGenerateURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on InviteGenerateURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on InviteGenerateURL") + } + + 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 *InviteGenerateURL) 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 ee0ced95..f1304d2d 100644 --- a/rest_server_zrok/operations/zrok_api.go +++ b/rest_server_zrok/operations/zrok_api.go @@ -23,6 +23,7 @@ import ( "github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/account" "github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/admin" "github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/environment" + "github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/invite" "github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/metadata" "github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/share" ) @@ -76,6 +77,9 @@ func NewZrokAPI(spec *loads.Document) *ZrokAPI { AccountInviteHandler: account.InviteHandlerFunc(func(params account.InviteParams) middleware.Responder { return middleware.NotImplemented("operation account.Invite has not yet been implemented") }), + InviteInviteGenerateHandler: invite.InviteGenerateHandlerFunc(func(params invite.InviteGenerateParams) middleware.Responder { + return middleware.NotImplemented("operation invite.InviteGenerate has not yet been implemented") + }), AdminListFrontendsHandler: admin.ListFrontendsHandlerFunc(func(params admin.ListFrontendsParams, principal *rest_model_zrok.Principal) middleware.Responder { return middleware.NotImplemented("operation admin.ListFrontends has not yet been implemented") }), @@ -177,6 +181,8 @@ type ZrokAPI struct { MetadataGetShareDetailHandler metadata.GetShareDetailHandler // AccountInviteHandler sets the operation handler for the invite operation AccountInviteHandler account.InviteHandler + // InviteInviteGenerateHandler sets the operation handler for the invite generate operation + InviteInviteGenerateHandler invite.InviteGenerateHandler // AdminListFrontendsHandler sets the operation handler for the list frontends operation AdminListFrontendsHandler admin.ListFrontendsHandler // AccountLoginHandler sets the operation handler for the login operation @@ -307,6 +313,9 @@ func (o *ZrokAPI) Validate() error { if o.AccountInviteHandler == nil { unregistered = append(unregistered, "account.InviteHandler") } + if o.InviteInviteGenerateHandler == nil { + unregistered = append(unregistered, "invite.InviteGenerateHandler") + } if o.AdminListFrontendsHandler == nil { unregistered = append(unregistered, "admin.ListFrontendsHandler") } @@ -475,6 +484,10 @@ func (o *ZrokAPI) initHandlerCache() { o.handlers["POST"] = make(map[string]http.Handler) } o.handlers["POST"]["/invite"] = account.NewInvite(o.context, o.AccountInviteHandler) + if o.handlers["POST"] == nil { + o.handlers["POST"] = make(map[string]http.Handler) + } + o.handlers["POST"]["/invite/generate"] = invite.NewInviteGenerate(o.context, o.InviteInviteGenerateHandler) if o.handlers["GET"] == nil { o.handlers["GET"] = make(map[string]http.Handler) } diff --git a/specs/zrok.yml b/specs/zrok.yml index fe3512e6..3e134d63 100644 --- a/specs/zrok.yml +++ b/specs/zrok.yml @@ -446,6 +446,27 @@ paths: schema: $ref: "#/definitions/errorMessage" + # + # invite + # + /invite/generate: + post: + tags: + - invite + operationId: inviteGenerate + parameters: + - name: body + in: body + schema: + $ref: "#/definitions/inviteGenerateRequest" + responses: + 201: + description: invitation tokens created + 400: + description: invitation tokens not created + 500: + description: internal server error + definitions: accessRequest: type: object @@ -740,6 +761,14 @@ definitions: version: type: string + inviteGenerateRequest: + type: object + properties: + tokens: + type: array + items: + type: string + produces: - application/zrok.v1+json consumes: diff --git a/ui/src/api/invite.js b/ui/src/api/invite.js new file mode 100644 index 00000000..4dd4704f --- /dev/null +++ b/ui/src/api/invite.js @@ -0,0 +1,24 @@ +/** @module invite */ +// Auto-generated, edits will be overwritten +import * as gateway from './gateway' + +/** + * @param {object} options Optional options + * @param {module:types.inviteGenerateRequest} [options.body] + * @return {Promise} invitation tokens created + */ +export function inviteGenerate(options) { + if (!options) options = {} + const parameters = { + body: { + body: options.body + } + } + return gateway.request(inviteGenerateOperation, parameters) +} + +const inviteGenerateOperation = { + path: '/invite/generate', + contentTypes: ['application/zrok.v1+json'], + method: 'post' +} diff --git a/ui/src/api/types.js b/ui/src/api/types.js index a7f66df0..92c482a1 100644 --- a/ui/src/api/types.js +++ b/ui/src/api/types.js @@ -230,3 +230,10 @@ * * @property {string} email */ + +/** + * @typedef inviteGenerateRequest + * @memberof module:types + * + * @property {string[]} tokens + */ From 0734e7b511a3b3fe8ac292dc9d617b1a79f9e269 Mon Sep 17 00:00:00 2001 From: Cam Otts Date: Mon, 9 Jan 2023 13:23:02 -0600 Subject: [PATCH 02/13] pr comments --- cmd/zrok/generate.go | 25 +++++-------- cmd/zrok/invite.go | 9 ++++- controller/invite.go | 23 +++++------- controller/store/invites.go | 37 ++++++++++--------- .../sql/postgresql/005_v0_3_0_invites.sql | 12 +++--- .../store/sql/sqlite3/005_v0_3_0_invites.sql | 10 ++--- rest_model_zrok/invite_request.go | 3 ++ rest_server_zrok/embedded_spec.go | 6 +++ specs/zrok.yml | 2 + ui/src/api/types.js | 1 + 10 files changed, 69 insertions(+), 59 deletions(-) diff --git a/cmd/zrok/generate.go b/cmd/zrok/generate.go index 4fce9500..5da73cf4 100644 --- a/cmd/zrok/generate.go +++ b/cmd/zrok/generate.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "strconv" "github.com/jaevor/go-nanoid" "github.com/openziti-test-kitchen/zrok/rest_client_zrok/invite" @@ -12,36 +11,32 @@ import ( ) func init() { - rootCmd.AddCommand(newGenerateCommand().cmd) + adminCmd.AddCommand(newGenerateCommand().cmd) } type generateCommand struct { - cmd *cobra.Command + cmd *cobra.Command + amount int } func newGenerateCommand() *generateCommand { cmd := &cobra.Command{ - Use: "generate ", + Use: "generate", Short: "Generate invite tokens (default: 5)", - Args: cobra.RangeArgs(0, 1), + Args: cobra.ExactArgs(0), } command := &generateCommand{cmd: cmd} cmd.Run = command.run + + cmd.Flags().IntVar(&command.amount, "amount", 5, "Amount of tokens to generate") + return command } func (cmd *generateCommand) run(_ *cobra.Command, args []string) { - var iterations int64 = 5 - if len(args) == 1 { - i, err := strconv.ParseInt(args[0], 10, 64) - if err != nil { - showError("unable to parse amount", err) - } - iterations = i - } var err error - tokens := make([]string, iterations) - for i := 0; i < int(iterations); i++ { + tokens := make([]string, cmd.amount) + for i := 0; i < int(cmd.amount); i++ { tokens[i], err = createToken() if err != nil { showError("error creating token", err) diff --git a/cmd/zrok/invite.go b/cmd/zrok/invite.go index 668884f9..e560a4ff 100644 --- a/cmd/zrok/invite.go +++ b/cmd/zrok/invite.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "github.com/openziti-test-kitchen/zrok/rest_client_zrok/account" "github.com/openziti-test-kitchen/zrok/rest_model_zrok" "github.com/openziti-test-kitchen/zrok/util" @@ -15,7 +16,8 @@ func init() { } type inviteCommand struct { - cmd *cobra.Command + cmd *cobra.Command + Token string } func newInviteCommand() *inviteCommand { @@ -24,8 +26,12 @@ func newInviteCommand() *inviteCommand { Short: "Invite a new user to zrok", Args: cobra.ExactArgs(0), } + command := &inviteCommand{cmd: cmd} cmd.Run = command.run + + cmd.Flags().StringVar(&command.Token, "token", "", "Invite token required when Zrok running in token store mode") + return command } @@ -55,6 +61,7 @@ func (cmd *inviteCommand) run(_ *cobra.Command, _ []string) { req := account.NewInviteParams() req.Body = &rest_model_zrok.InviteRequest{ Email: email, + Token: cmd.Token, } _, err = zrok.Account.Invite(req) if err != nil { diff --git a/controller/invite.go b/controller/invite.go index a45d7718..0d04a0d3 100644 --- a/controller/invite.go +++ b/controller/invite.go @@ -39,24 +39,22 @@ func (self *inviteHandler) Handle(params account.InviteParams) middleware.Respon defer func() { _ = tx.Rollback() }() if self.cfg.Registration.TokenStrategy == "store" { - invite, err := str.GetInvite(tx) + invite, err := str.GetInviteByToken(params.Body.Token, tx) if err != nil { logrus.Error(err) - return account.NewInviteInternalServerError() + return account.NewInviteBadRequest() } - invite.Status = store.INVITE_STATUS_TAKEN - if err := str.UpdateInvite(invite, tx); err != nil { - logrus.Error(err) - return account.NewInviteInternalServerError() - } - token = invite.Token - } else { - token, err = createToken() - if err != nil { + if err := str.DeleteInvite(invite.Id, tx); err != nil { logrus.Error(err) return account.NewInviteInternalServerError() } } + + token, err = createToken() + if err != nil { + logrus.Error(err) + return account.NewInviteInternalServerError() + } ar := &store.AccountRequest{ Token: token, Email: params.Body.Email, @@ -120,8 +118,7 @@ func (handler *inviteGenerateHandler) Handle(params invite.InviteGenerateParams) invites := make([]*store.Invite, len(params.Body.Tokens)) for i, token := range params.Body.Tokens { invites[i] = &store.Invite{ - Token: token, - Status: store.INVITE_STATUS_UNUSED, + Token: token, } } tx, err := str.Begin() diff --git a/controller/store/invites.go b/controller/store/invites.go index 257089ff..7de49e1b 100644 --- a/controller/store/invites.go +++ b/controller/store/invites.go @@ -10,25 +10,16 @@ import ( type Invite struct { Model - Token string - Status string `db:"token_status"` + Token string } -const ( - INVITE_STATUS_UNUSED = "UNUSED" - INVITE_STATUS_TAKEN = "TAKEN" -) - func (str *Store) CreateInvites(invites []*Invite, tx *sqlx.Tx) error { - sql := "insert into invites (token, token_status) values %s" - invs := make([]any, len(invites)*2) + sql := "insert into invites (token) values %s" + invs := make([]any, len(invites)) queries := make([]string, len(invites)) - ct := 1 for i, inv := range invites { invs[i] = inv.Token - invs[i+1] = inv.Status - queries[i] = fmt.Sprintf("($%d, $%d)", ct, ct+1) - ct = ct + 2 + queries[i] = fmt.Sprintf("($%d)", i+1) } stmt, err := tx.Prepare(fmt.Sprintf(sql, strings.Join(queries, ","))) if err != nil { @@ -40,22 +31,34 @@ func (str *Store) CreateInvites(invites []*Invite, tx *sqlx.Tx) error { return nil } -func (str *Store) GetInvite(tx *sqlx.Tx) (*Invite, error) { +func (str *Store) GetInviteByToken(token string, tx *sqlx.Tx) (*Invite, error) { invite := &Invite{} - if err := tx.QueryRowx("select * from invites where token_status = $1 limit 1", INVITE_STATUS_UNUSED).StructScan(invite); err != nil { + if err := tx.QueryRowx("select * from invites where token = $1", token).StructScan(invite); err != nil { return nil, errors.Wrap(err, "error getting unused invite") } return invite, nil } func (str *Store) UpdateInvite(invite *Invite, tx *sqlx.Tx) error { - stmt, err := tx.Prepare("update invites set token = $1, token_status = $2") + stmt, err := tx.Prepare("update invites set token = $1") if err != nil { return errors.Wrap(err, "error perparing invites update statement") } - _, err = stmt.Exec(invite.Token, invite.Status) + _, err = stmt.Exec(invite.Token) if err != nil { return errors.Wrap(err, "error executing invites update statement") } return nil } + +func (str *Store) DeleteInvite(id int, tx *sqlx.Tx) error { + stmt, err := tx.Prepare("delete from invites where id = $1") + if err != nil { + return errors.Wrap(err, "error preparing invites delete statement") + } + _, err = stmt.Exec(id) + if err != nil { + return errors.Wrap(err, "error executing invites delete statement") + } + return nil +} diff --git a/controller/store/sql/postgresql/005_v0_3_0_invites.sql b/controller/store/sql/postgresql/005_v0_3_0_invites.sql index 92894566..42eec093 100644 --- a/controller/store/sql/postgresql/005_v0_3_0_invites.sql +++ b/controller/store/sql/postgresql/005_v0_3_0_invites.sql @@ -5,12 +5,10 @@ --- create table invites ( - id serial primary key, - token varchar(32) not null unique, - token_status varchar(1024) not null unique, - created_at timestamp not null default(current_timestamp), - updated_at timestamp not null default(current_timestamp), + id serial primary key, + token varchar(32) not null unique, + created_at timestamptz not null default(current_timestamp), + updated_at timestamptz not null default(current_timestamp), - constraint chk_token check(token <> ''), - constraint chk_status check(token_status <> '') + constraint chk_token check(token <> '') ); \ No newline at end of file diff --git a/controller/store/sql/sqlite3/005_v0_3_0_invites.sql b/controller/store/sql/sqlite3/005_v0_3_0_invites.sql index 92894566..1917729d 100644 --- a/controller/store/sql/sqlite3/005_v0_3_0_invites.sql +++ b/controller/store/sql/sqlite3/005_v0_3_0_invites.sql @@ -5,12 +5,10 @@ --- create table invites ( - id serial primary key, - token varchar(32) not null unique, - token_status varchar(1024) not null unique, - created_at timestamp not null default(current_timestamp), - updated_at timestamp not null default(current_timestamp), + id integer primary key, + token string not null unique, + created_at datetime not null default(strftime('%Y-%m-%d %H:%M:%f', 'now')), + updated_at datetime not null default(strftime('%Y-%m-%d %H:%M:%f', 'now')), constraint chk_token check(token <> ''), - constraint chk_status check(token_status <> '') ); \ No newline at end of file diff --git a/rest_model_zrok/invite_request.go b/rest_model_zrok/invite_request.go index 970d4f0a..936c5c3e 100644 --- a/rest_model_zrok/invite_request.go +++ b/rest_model_zrok/invite_request.go @@ -19,6 +19,9 @@ type InviteRequest struct { // email Email string `json:"email,omitempty"` + + // token + Token string `json:"token,omitempty"` } // Validate validates this invite request diff --git a/rest_server_zrok/embedded_spec.go b/rest_server_zrok/embedded_spec.go index b8466732..cf04ad8f 100644 --- a/rest_server_zrok/embedded_spec.go +++ b/rest_server_zrok/embedded_spec.go @@ -903,6 +903,9 @@ func init() { "properties": { "email": { "type": "string" + }, + "token": { + "type": "string" } } }, @@ -2060,6 +2063,9 @@ func init() { "properties": { "email": { "type": "string" + }, + "token": { + "type": "string" } } }, diff --git a/specs/zrok.yml b/specs/zrok.yml index 3e134d63..bf9cbe08 100644 --- a/specs/zrok.yml +++ b/specs/zrok.yml @@ -578,6 +578,8 @@ definitions: properties: email: type: string + token: + type: string loginRequest: type: object diff --git a/ui/src/api/types.js b/ui/src/api/types.js index 92c482a1..f34b8a2c 100644 --- a/ui/src/api/types.js +++ b/ui/src/api/types.js @@ -96,6 +96,7 @@ * @memberof module:types * * @property {string} email + * @property {string} token */ /** From 354ccb853fd5ba06bed18dc257dc886d4df39858 Mon Sep 17 00:00:00 2001 From: Cam Otts Date: Mon, 9 Jan 2023 13:40:32 -0600 Subject: [PATCH 03/13] sqlite typo --- controller/store/sql/sqlite3/005_v0_3_0_invites.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controller/store/sql/sqlite3/005_v0_3_0_invites.sql b/controller/store/sql/sqlite3/005_v0_3_0_invites.sql index 1917729d..f1f94ef0 100644 --- a/controller/store/sql/sqlite3/005_v0_3_0_invites.sql +++ b/controller/store/sql/sqlite3/005_v0_3_0_invites.sql @@ -10,5 +10,5 @@ create table invites ( created_at datetime not null default(strftime('%Y-%m-%d %H:%M:%f', 'now')), updated_at datetime not null default(strftime('%Y-%m-%d %H:%M:%f', 'now')), - constraint chk_token check(token <> ''), + constraint chk_token check(token <> '') ); \ No newline at end of file From bb3d4882120a34054f5af261025f55989a8f3099 Mon Sep 17 00:00:00 2001 From: Cam Otts Date: Tue, 10 Jan 2023 09:53:41 -0600 Subject: [PATCH 04/13] move token generation to admin and add needed security to it --- cmd/zrok/generate.go | 6 +- controller/controller.go | 2 +- controller/invite.go | 18 +++-- rest_client_zrok/admin/admin_client.go | 41 ++++++++++ .../invite_generate_parameters.go | 2 +- .../invite_generate_responses.go | 59 +++++++++++++- rest_client_zrok/invite/invite_client.go | 79 ------------------- rest_client_zrok/zrok_client.go | 5 -- rest_server_zrok/embedded_spec.go | 20 ++++- .../{invite => admin}/invite_generate.go | 29 +++++-- .../invite_generate_parameters.go | 2 +- .../invite_generate_responses.go | 27 ++++++- .../invite_generate_urlbuilder.go | 2 +- rest_server_zrok/operations/zrok_api.go | 15 ++-- specs/zrok.yml | 43 +++++----- ui/src/api/admin.js | 26 ++++++ ui/src/api/invite.js | 24 ------ 17 files changed, 239 insertions(+), 161 deletions(-) rename rest_client_zrok/{invite => admin}/invite_generate_parameters.go (99%) rename rest_client_zrok/{invite => admin}/invite_generate_responses.go (77%) delete mode 100644 rest_client_zrok/invite/invite_client.go rename rest_server_zrok/operations/{invite => admin}/invite_generate.go (62%) rename rest_server_zrok/operations/{invite => admin}/invite_generate_parameters.go (99%) rename rest_server_zrok/operations/{invite => admin}/invite_generate_responses.go (76%) rename rest_server_zrok/operations/{invite => admin}/invite_generate_urlbuilder.go (99%) delete mode 100644 ui/src/api/invite.js diff --git a/cmd/zrok/generate.go b/cmd/zrok/generate.go index 5da73cf4..1c8f2271 100644 --- a/cmd/zrok/generate.go +++ b/cmd/zrok/generate.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/jaevor/go-nanoid" - "github.com/openziti-test-kitchen/zrok/rest_client_zrok/invite" + "github.com/openziti-test-kitchen/zrok/rest_client_zrok/admin" "github.com/openziti-test-kitchen/zrok/rest_model_zrok" "github.com/openziti-test-kitchen/zrok/zrokdir" "github.com/spf13/cobra" @@ -49,11 +49,11 @@ func (cmd *generateCommand) run(_ *cobra.Command, args []string) { } panic(err) } - req := invite.NewInviteGenerateParams() + req := admin.NewInviteGenerateParams() req.Body = &rest_model_zrok.InviteGenerateRequest{ Tokens: tokens, } - _, err = zrok.Invite.InviteGenerate(req) + _, err = zrok.Admin.InviteGenerate(req, mustGetAdminAuth()) if err != nil { if !panicInstead { showError("error creating invite tokens", err) diff --git a/controller/controller.go b/controller/controller.go index dba22c01..1ec3c8db 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -33,11 +33,11 @@ func Run(inCfg *Config) error { api.AdminCreateFrontendHandler = newCreateFrontendHandler() api.AdminCreateIdentityHandler = newCreateIdentityHandler() api.AdminDeleteFrontendHandler = newDeleteFrontendHandler() + api.AdminInviteGenerateHandler = newInviteGenerateHandler() api.AdminListFrontendsHandler = newListFrontendsHandler() api.AdminUpdateFrontendHandler = newUpdateFrontendHandler() api.EnvironmentEnableHandler = newEnableHandler() api.EnvironmentDisableHandler = newDisableHandler() - api.InviteInviteGenerateHandler = newInviteGenerateHandler() api.MetadataGetEnvironmentDetailHandler = newEnvironmentDetailHandler() api.MetadataGetShareDetailHandler = newShareDetailHandler() api.MetadataOverviewHandler = metadata.OverviewHandlerFunc(overviewHandler) diff --git a/controller/invite.go b/controller/invite.go index 0d04a0d3..437f8174 100644 --- a/controller/invite.go +++ b/controller/invite.go @@ -3,8 +3,9 @@ package controller import ( "github.com/go-openapi/runtime/middleware" "github.com/openziti-test-kitchen/zrok/controller/store" + "github.com/openziti-test-kitchen/zrok/rest_model_zrok" "github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/account" - "github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/invite" + "github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/admin" "github.com/openziti-test-kitchen/zrok/util" "github.com/sirupsen/logrus" ) @@ -108,10 +109,15 @@ func newInviteGenerateHandler() *inviteGenerateHandler { return &inviteGenerateHandler{} } -func (handler *inviteGenerateHandler) Handle(params invite.InviteGenerateParams) middleware.Responder { +func (handler *inviteGenerateHandler) Handle(params admin.InviteGenerateParams, principal *rest_model_zrok.Principal) middleware.Responder { + if !principal.Admin { + logrus.Errorf("invalid admin principal") + return admin.NewListFrontendsUnauthorized() + } + if params.Body == nil || len(params.Body.Tokens) == 0 { logrus.Error("missing tokens") - return invite.NewInviteGenerateBadRequest() + return admin.NewInviteGenerateBadRequest() } logrus.Infof("received invite generate request with %d tokens", len(params.Body.Tokens)) @@ -124,13 +130,13 @@ func (handler *inviteGenerateHandler) Handle(params invite.InviteGenerateParams) tx, err := str.Begin() if err != nil { logrus.Error(err) - return invite.NewInviteGenerateInternalServerError() + return admin.NewInviteGenerateInternalServerError() } defer func() { _ = tx.Rollback() }() if err := str.CreateInvites(invites, tx); err != nil { logrus.Error(err) - return invite.NewInviteGenerateInternalServerError() + return admin.NewInviteGenerateInternalServerError() } if err := tx.Commit(); err != nil { @@ -138,5 +144,5 @@ func (handler *inviteGenerateHandler) Handle(params invite.InviteGenerateParams) return account.NewInviteInternalServerError() } - return invite.NewInviteGenerateCreated() + return admin.NewInviteGenerateCreated() } diff --git a/rest_client_zrok/admin/admin_client.go b/rest_client_zrok/admin/admin_client.go index 0179e2f1..e67503f8 100644 --- a/rest_client_zrok/admin/admin_client.go +++ b/rest_client_zrok/admin/admin_client.go @@ -36,6 +36,8 @@ type ClientService interface { DeleteFrontend(params *DeleteFrontendParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*DeleteFrontendOK, error) + InviteGenerate(params *InviteGenerateParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*InviteGenerateCreated, error) + ListFrontends(params *ListFrontendsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*ListFrontendsOK, error) UpdateFrontend(params *UpdateFrontendParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*UpdateFrontendOK, error) @@ -160,6 +162,45 @@ func (a *Client) DeleteFrontend(params *DeleteFrontendParams, authInfo runtime.C panic(msg) } +/* +InviteGenerate invite generate API +*/ +func (a *Client) InviteGenerate(params *InviteGenerateParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*InviteGenerateCreated, error) { + // TODO: Validate the params before sending + if params == nil { + params = NewInviteGenerateParams() + } + op := &runtime.ClientOperation{ + ID: "inviteGenerate", + Method: "POST", + PathPattern: "/invite/generate", + ProducesMediaTypes: []string{"application/zrok.v1+json"}, + ConsumesMediaTypes: []string{"application/zrok.v1+json"}, + Schemes: []string{"http"}, + Params: params, + Reader: &InviteGenerateReader{formats: a.formats}, + AuthInfo: authInfo, + 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.(*InviteGenerateCreated) + 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 inviteGenerate: API contract not enforced by server. Client expected to get an error, but got: %T", result) + panic(msg) +} + /* ListFrontends list frontends API */ diff --git a/rest_client_zrok/invite/invite_generate_parameters.go b/rest_client_zrok/admin/invite_generate_parameters.go similarity index 99% rename from rest_client_zrok/invite/invite_generate_parameters.go rename to rest_client_zrok/admin/invite_generate_parameters.go index e585966d..031edf8f 100644 --- a/rest_client_zrok/invite/invite_generate_parameters.go +++ b/rest_client_zrok/admin/invite_generate_parameters.go @@ -1,6 +1,6 @@ // Code generated by go-swagger; DO NOT EDIT. -package invite +package admin // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command diff --git a/rest_client_zrok/invite/invite_generate_responses.go b/rest_client_zrok/admin/invite_generate_responses.go similarity index 77% rename from rest_client_zrok/invite/invite_generate_responses.go rename to rest_client_zrok/admin/invite_generate_responses.go index 763a70df..0fa45d45 100644 --- a/rest_client_zrok/invite/invite_generate_responses.go +++ b/rest_client_zrok/admin/invite_generate_responses.go @@ -1,6 +1,6 @@ // Code generated by go-swagger; DO NOT EDIT. -package invite +package admin // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command @@ -32,6 +32,12 @@ func (o *InviteGenerateReader) ReadResponse(response runtime.ClientResponse, con return nil, err } return nil, result + case 401: + result := NewInviteGenerateUnauthorized() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result case 500: result := NewInviteGenerateInternalServerError() if err := result.readResponse(response, consumer, o.formats); err != nil { @@ -145,6 +151,57 @@ func (o *InviteGenerateBadRequest) readResponse(response runtime.ClientResponse, return nil } +// NewInviteGenerateUnauthorized creates a InviteGenerateUnauthorized with default headers values +func NewInviteGenerateUnauthorized() *InviteGenerateUnauthorized { + return &InviteGenerateUnauthorized{} +} + +/* +InviteGenerateUnauthorized describes a response with status code 401, with default header values. + +unauthorized +*/ +type InviteGenerateUnauthorized struct { +} + +// IsSuccess returns true when this invite generate unauthorized response has a 2xx status code +func (o *InviteGenerateUnauthorized) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this invite generate unauthorized response has a 3xx status code +func (o *InviteGenerateUnauthorized) IsRedirect() bool { + return false +} + +// IsClientError returns true when this invite generate unauthorized response has a 4xx status code +func (o *InviteGenerateUnauthorized) IsClientError() bool { + return true +} + +// IsServerError returns true when this invite generate unauthorized response has a 5xx status code +func (o *InviteGenerateUnauthorized) IsServerError() bool { + return false +} + +// IsCode returns true when this invite generate unauthorized response a status code equal to that given +func (o *InviteGenerateUnauthorized) IsCode(code int) bool { + return code == 401 +} + +func (o *InviteGenerateUnauthorized) Error() string { + return fmt.Sprintf("[POST /invite/generate][%d] inviteGenerateUnauthorized ", 401) +} + +func (o *InviteGenerateUnauthorized) String() string { + return fmt.Sprintf("[POST /invite/generate][%d] inviteGenerateUnauthorized ", 401) +} + +func (o *InviteGenerateUnauthorized) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + return nil +} + // NewInviteGenerateInternalServerError creates a InviteGenerateInternalServerError with default headers values func NewInviteGenerateInternalServerError() *InviteGenerateInternalServerError { return &InviteGenerateInternalServerError{} diff --git a/rest_client_zrok/invite/invite_client.go b/rest_client_zrok/invite/invite_client.go deleted file mode 100644 index f64b51ab..00000000 --- a/rest_client_zrok/invite/invite_client.go +++ /dev/null @@ -1,79 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package invite - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - "fmt" - - "github.com/go-openapi/runtime" - "github.com/go-openapi/strfmt" -) - -// New creates a new invite API client. -func New(transport runtime.ClientTransport, formats strfmt.Registry) ClientService { - return &Client{transport: transport, formats: formats} -} - -/* -Client for invite API -*/ -type Client struct { - transport runtime.ClientTransport - formats strfmt.Registry -} - -// ClientOption is the option for Client methods -type ClientOption func(*runtime.ClientOperation) - -// ClientService is the interface for Client methods -type ClientService interface { - InviteGenerate(params *InviteGenerateParams, opts ...ClientOption) (*InviteGenerateCreated, error) - - SetTransport(transport runtime.ClientTransport) -} - -/* -InviteGenerate invite generate API -*/ -func (a *Client) InviteGenerate(params *InviteGenerateParams, opts ...ClientOption) (*InviteGenerateCreated, error) { - // TODO: Validate the params before sending - if params == nil { - params = NewInviteGenerateParams() - } - op := &runtime.ClientOperation{ - ID: "inviteGenerate", - Method: "POST", - PathPattern: "/invite/generate", - ProducesMediaTypes: []string{"application/zrok.v1+json"}, - ConsumesMediaTypes: []string{"application/zrok.v1+json"}, - Schemes: []string{"http"}, - Params: params, - Reader: &InviteGenerateReader{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.(*InviteGenerateCreated) - 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 inviteGenerate: API contract not enforced by server. Client expected to get an error, but got: %T", result) - panic(msg) -} - -// SetTransport changes the transport on the client -func (a *Client) SetTransport(transport runtime.ClientTransport) { - a.transport = transport -} diff --git a/rest_client_zrok/zrok_client.go b/rest_client_zrok/zrok_client.go index 379b6717..2aaac3fd 100644 --- a/rest_client_zrok/zrok_client.go +++ b/rest_client_zrok/zrok_client.go @@ -13,7 +13,6 @@ import ( "github.com/openziti-test-kitchen/zrok/rest_client_zrok/account" "github.com/openziti-test-kitchen/zrok/rest_client_zrok/admin" "github.com/openziti-test-kitchen/zrok/rest_client_zrok/environment" - "github.com/openziti-test-kitchen/zrok/rest_client_zrok/invite" "github.com/openziti-test-kitchen/zrok/rest_client_zrok/metadata" "github.com/openziti-test-kitchen/zrok/rest_client_zrok/share" ) @@ -63,7 +62,6 @@ func New(transport runtime.ClientTransport, formats strfmt.Registry) *Zrok { cli.Account = account.New(transport, formats) cli.Admin = admin.New(transport, formats) cli.Environment = environment.New(transport, formats) - cli.Invite = invite.New(transport, formats) cli.Metadata = metadata.New(transport, formats) cli.Share = share.New(transport, formats) return cli @@ -116,8 +114,6 @@ type Zrok struct { Environment environment.ClientService - Invite invite.ClientService - Metadata metadata.ClientService Share share.ClientService @@ -131,7 +127,6 @@ func (c *Zrok) SetTransport(transport runtime.ClientTransport) { c.Account.SetTransport(transport) c.Admin.SetTransport(transport) c.Environment.SetTransport(transport) - c.Invite.SetTransport(transport) c.Metadata.SetTransport(transport) c.Share.SetTransport(transport) } diff --git a/rest_server_zrok/embedded_spec.go b/rest_server_zrok/embedded_spec.go index cf04ad8f..ecc14e22 100644 --- a/rest_server_zrok/embedded_spec.go +++ b/rest_server_zrok/embedded_spec.go @@ -433,8 +433,13 @@ func init() { }, "/invite/generate": { "post": { + "security": [ + { + "key": [] + } + ], "tags": [ - "invite" + "admin" ], "operationId": "inviteGenerate", "parameters": [ @@ -453,6 +458,9 @@ func init() { "400": { "description": "invitation tokens not created" }, + "401": { + "description": "unauthorized" + }, "500": { "description": "internal server error" } @@ -1593,8 +1601,13 @@ func init() { }, "/invite/generate": { "post": { + "security": [ + { + "key": [] + } + ], "tags": [ - "invite" + "admin" ], "operationId": "inviteGenerate", "parameters": [ @@ -1613,6 +1626,9 @@ func init() { "400": { "description": "invitation tokens not created" }, + "401": { + "description": "unauthorized" + }, "500": { "description": "internal server error" } diff --git a/rest_server_zrok/operations/invite/invite_generate.go b/rest_server_zrok/operations/admin/invite_generate.go similarity index 62% rename from rest_server_zrok/operations/invite/invite_generate.go rename to rest_server_zrok/operations/admin/invite_generate.go index 7718776c..a881fc0d 100644 --- a/rest_server_zrok/operations/invite/invite_generate.go +++ b/rest_server_zrok/operations/admin/invite_generate.go @@ -1,6 +1,6 @@ // Code generated by go-swagger; DO NOT EDIT. -package invite +package admin // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the generate command @@ -9,19 +9,21 @@ import ( "net/http" "github.com/go-openapi/runtime/middleware" + + "github.com/openziti-test-kitchen/zrok/rest_model_zrok" ) // InviteGenerateHandlerFunc turns a function with the right signature into a invite generate handler -type InviteGenerateHandlerFunc func(InviteGenerateParams) middleware.Responder +type InviteGenerateHandlerFunc func(InviteGenerateParams, *rest_model_zrok.Principal) middleware.Responder // Handle executing the request and returning a response -func (fn InviteGenerateHandlerFunc) Handle(params InviteGenerateParams) middleware.Responder { - return fn(params) +func (fn InviteGenerateHandlerFunc) Handle(params InviteGenerateParams, principal *rest_model_zrok.Principal) middleware.Responder { + return fn(params, principal) } // InviteGenerateHandler interface for that can handle valid invite generate params type InviteGenerateHandler interface { - Handle(InviteGenerateParams) middleware.Responder + Handle(InviteGenerateParams, *rest_model_zrok.Principal) middleware.Responder } // NewInviteGenerate creates a new http.Handler for the invite generate operation @@ -30,7 +32,7 @@ func NewInviteGenerate(ctx *middleware.Context, handler InviteGenerateHandler) * } /* - InviteGenerate swagger:route POST /invite/generate invite inviteGenerate + InviteGenerate swagger:route POST /invite/generate admin inviteGenerate InviteGenerate invite generate API */ @@ -45,12 +47,25 @@ func (o *InviteGenerate) ServeHTTP(rw http.ResponseWriter, r *http.Request) { *r = *rCtx } var Params = NewInviteGenerateParams() + uprinc, aCtx, err := o.Context.Authorize(r, route) + if err != nil { + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + if aCtx != nil { + *r = *aCtx + } + var principal *rest_model_zrok.Principal + if uprinc != nil { + principal = uprinc.(*rest_model_zrok.Principal) // this is really a rest_model_zrok.Principal, I promise + } + 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 + res := o.Handler.Handle(Params, principal) // actually handle the request o.Context.Respond(rw, r, route.Produces, route, res) } diff --git a/rest_server_zrok/operations/invite/invite_generate_parameters.go b/rest_server_zrok/operations/admin/invite_generate_parameters.go similarity index 99% rename from rest_server_zrok/operations/invite/invite_generate_parameters.go rename to rest_server_zrok/operations/admin/invite_generate_parameters.go index df0d20cc..845c04cf 100644 --- a/rest_server_zrok/operations/invite/invite_generate_parameters.go +++ b/rest_server_zrok/operations/admin/invite_generate_parameters.go @@ -1,6 +1,6 @@ // Code generated by go-swagger; DO NOT EDIT. -package invite +package admin // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command diff --git a/rest_server_zrok/operations/invite/invite_generate_responses.go b/rest_server_zrok/operations/admin/invite_generate_responses.go similarity index 76% rename from rest_server_zrok/operations/invite/invite_generate_responses.go rename to rest_server_zrok/operations/admin/invite_generate_responses.go index 5c08ddc6..9aaf1cec 100644 --- a/rest_server_zrok/operations/invite/invite_generate_responses.go +++ b/rest_server_zrok/operations/admin/invite_generate_responses.go @@ -1,6 +1,6 @@ // Code generated by go-swagger; DO NOT EDIT. -package invite +package admin // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command @@ -61,6 +61,31 @@ func (o *InviteGenerateBadRequest) WriteResponse(rw http.ResponseWriter, produce rw.WriteHeader(400) } +// InviteGenerateUnauthorizedCode is the HTTP code returned for type InviteGenerateUnauthorized +const InviteGenerateUnauthorizedCode int = 401 + +/* +InviteGenerateUnauthorized unauthorized + +swagger:response inviteGenerateUnauthorized +*/ +type InviteGenerateUnauthorized struct { +} + +// NewInviteGenerateUnauthorized creates InviteGenerateUnauthorized with default headers values +func NewInviteGenerateUnauthorized() *InviteGenerateUnauthorized { + + return &InviteGenerateUnauthorized{} +} + +// WriteResponse to the client +func (o *InviteGenerateUnauthorized) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + + rw.WriteHeader(401) +} + // InviteGenerateInternalServerErrorCode is the HTTP code returned for type InviteGenerateInternalServerError const InviteGenerateInternalServerErrorCode int = 500 diff --git a/rest_server_zrok/operations/invite/invite_generate_urlbuilder.go b/rest_server_zrok/operations/admin/invite_generate_urlbuilder.go similarity index 99% rename from rest_server_zrok/operations/invite/invite_generate_urlbuilder.go rename to rest_server_zrok/operations/admin/invite_generate_urlbuilder.go index ea9a40f1..15c48dc1 100644 --- a/rest_server_zrok/operations/invite/invite_generate_urlbuilder.go +++ b/rest_server_zrok/operations/admin/invite_generate_urlbuilder.go @@ -1,6 +1,6 @@ // Code generated by go-swagger; DO NOT EDIT. -package invite +package admin // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the generate command diff --git a/rest_server_zrok/operations/zrok_api.go b/rest_server_zrok/operations/zrok_api.go index f1304d2d..60b210ed 100644 --- a/rest_server_zrok/operations/zrok_api.go +++ b/rest_server_zrok/operations/zrok_api.go @@ -23,7 +23,6 @@ import ( "github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/account" "github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/admin" "github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/environment" - "github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/invite" "github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/metadata" "github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/share" ) @@ -77,8 +76,8 @@ func NewZrokAPI(spec *loads.Document) *ZrokAPI { AccountInviteHandler: account.InviteHandlerFunc(func(params account.InviteParams) middleware.Responder { return middleware.NotImplemented("operation account.Invite has not yet been implemented") }), - InviteInviteGenerateHandler: invite.InviteGenerateHandlerFunc(func(params invite.InviteGenerateParams) middleware.Responder { - return middleware.NotImplemented("operation invite.InviteGenerate has not yet been implemented") + AdminInviteGenerateHandler: admin.InviteGenerateHandlerFunc(func(params admin.InviteGenerateParams, principal *rest_model_zrok.Principal) middleware.Responder { + return middleware.NotImplemented("operation admin.InviteGenerate has not yet been implemented") }), AdminListFrontendsHandler: admin.ListFrontendsHandlerFunc(func(params admin.ListFrontendsParams, principal *rest_model_zrok.Principal) middleware.Responder { return middleware.NotImplemented("operation admin.ListFrontends has not yet been implemented") @@ -181,8 +180,8 @@ type ZrokAPI struct { MetadataGetShareDetailHandler metadata.GetShareDetailHandler // AccountInviteHandler sets the operation handler for the invite operation AccountInviteHandler account.InviteHandler - // InviteInviteGenerateHandler sets the operation handler for the invite generate operation - InviteInviteGenerateHandler invite.InviteGenerateHandler + // AdminInviteGenerateHandler sets the operation handler for the invite generate operation + AdminInviteGenerateHandler admin.InviteGenerateHandler // AdminListFrontendsHandler sets the operation handler for the list frontends operation AdminListFrontendsHandler admin.ListFrontendsHandler // AccountLoginHandler sets the operation handler for the login operation @@ -313,8 +312,8 @@ func (o *ZrokAPI) Validate() error { if o.AccountInviteHandler == nil { unregistered = append(unregistered, "account.InviteHandler") } - if o.InviteInviteGenerateHandler == nil { - unregistered = append(unregistered, "invite.InviteGenerateHandler") + if o.AdminInviteGenerateHandler == nil { + unregistered = append(unregistered, "admin.InviteGenerateHandler") } if o.AdminListFrontendsHandler == nil { unregistered = append(unregistered, "admin.ListFrontendsHandler") @@ -487,7 +486,7 @@ func (o *ZrokAPI) initHandlerCache() { if o.handlers["POST"] == nil { o.handlers["POST"] = make(map[string]http.Handler) } - o.handlers["POST"]["/invite/generate"] = invite.NewInviteGenerate(o.context, o.InviteInviteGenerateHandler) + o.handlers["POST"]["/invite/generate"] = admin.NewInviteGenerate(o.context, o.AdminInviteGenerateHandler) if o.handlers["GET"] == nil { o.handlers["GET"] = make(map[string]http.Handler) } diff --git a/specs/zrok.yml b/specs/zrok.yml index bf9cbe08..b86b8111 100644 --- a/specs/zrok.yml +++ b/specs/zrok.yml @@ -202,6 +202,28 @@ paths: description: unauthorized 500: description: internal server error + + /invite/generate: + post: + tags: + - admin + security: + - key: [] + operationId: inviteGenerate + parameters: + - name: body + in: body + schema: + $ref: "#/definitions/inviteGenerateRequest" + responses: + 201: + description: invitation tokens created + 400: + description: invitation tokens not created + 401: + description: unauthorized + 500: + description: internal server error # # environment # @@ -446,27 +468,6 @@ paths: schema: $ref: "#/definitions/errorMessage" - # - # invite - # - /invite/generate: - post: - tags: - - invite - operationId: inviteGenerate - parameters: - - name: body - in: body - schema: - $ref: "#/definitions/inviteGenerateRequest" - responses: - 201: - description: invitation tokens created - 400: - description: invitation tokens not created - 500: - description: internal server error - definitions: accessRequest: type: object diff --git a/ui/src/api/admin.js b/ui/src/api/admin.js index f12a8eb8..ca9a4d54 100644 --- a/ui/src/api/admin.js +++ b/ui/src/api/admin.js @@ -68,6 +68,21 @@ export function createIdentity(options) { return gateway.request(createIdentityOperation, parameters) } +/** + * @param {object} options Optional options + * @param {module:types.inviteGenerateRequest} [options.body] + * @return {Promise} invitation tokens created + */ +export function inviteGenerate(options) { + if (!options) options = {} + const parameters = { + body: { + body: options.body + } + } + return gateway.request(inviteGenerateOperation, parameters) +} + const createFrontendOperation = { path: '/frontend', contentTypes: ['application/zrok.v1+json'], @@ -121,3 +136,14 @@ const createIdentityOperation = { } ] } + +const inviteGenerateOperation = { + path: '/invite/generate', + contentTypes: ['application/zrok.v1+json'], + method: 'post', + security: [ + { + id: 'key' + } + ] +} diff --git a/ui/src/api/invite.js b/ui/src/api/invite.js deleted file mode 100644 index 4dd4704f..00000000 --- a/ui/src/api/invite.js +++ /dev/null @@ -1,24 +0,0 @@ -/** @module invite */ -// Auto-generated, edits will be overwritten -import * as gateway from './gateway' - -/** - * @param {object} options Optional options - * @param {module:types.inviteGenerateRequest} [options.body] - * @return {Promise} invitation tokens created - */ -export function inviteGenerate(options) { - if (!options) options = {} - const parameters = { - body: { - body: options.body - } - } - return gateway.request(inviteGenerateOperation, parameters) -} - -const inviteGenerateOperation = { - path: '/invite/generate', - contentTypes: ['application/zrok.v1+json'], - method: 'post' -} From 049ef6c9e983eb76be67e1dd4c0ba086287bf152 Mon Sep 17 00:00:00 2001 From: Cam Otts Date: Tue, 10 Jan 2023 10:05:57 -0600 Subject: [PATCH 05/13] send correct unauthorized error --- controller/invite.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controller/invite.go b/controller/invite.go index 437f8174..5444f822 100644 --- a/controller/invite.go +++ b/controller/invite.go @@ -112,7 +112,7 @@ func newInviteGenerateHandler() *inviteGenerateHandler { func (handler *inviteGenerateHandler) Handle(params admin.InviteGenerateParams, principal *rest_model_zrok.Principal) middleware.Responder { if !principal.Admin { logrus.Errorf("invalid admin principal") - return admin.NewListFrontendsUnauthorized() + return admin.NewInviteGenerateUnauthorized() } if params.Body == nil || len(params.Body.Tokens) == 0 { From ee078a9e10666c971b023c82e47795a867ba6c2a Mon Sep 17 00:00:00 2001 From: Cam Otts Date: Tue, 10 Jan 2023 12:26:22 -0600 Subject: [PATCH 06/13] pr comments --- cmd/zrok/{generate.go => adminGenerate.go} | 16 +- cmd/zrok/invite.go | 6 +- controller/controller.go | 2 +- controller/invite.go | 51 +--- controller/inviteTokenGenerate.go | 55 ++++ controller/store/invite_tokens.go | 52 ++++ controller/store/invites.go | 64 ----- .../sql/postgresql/005_v0_3_0_invites.sql | 4 +- .../store/sql/sqlite3/005_v0_3_0_invites.sql | 4 +- rest_client_zrok/admin/admin_client.go | 18 +- .../admin/invite_generate_parameters.go | 150 ----------- .../admin/invite_generate_responses.go | 254 ------------------ .../admin/invite_token_generate_parameters.go | 150 +++++++++++ .../admin/invite_token_generate_responses.go | 254 ++++++++++++++++++ rest_model_zrok/invite_generate_request.go | 50 ---- .../invite_token_generate_request.go | 50 ++++ rest_server_zrok/embedded_spec.go | 56 ++-- .../operations/admin/invite_generate.go | 71 ----- .../admin/invite_generate_responses.go | 112 -------- .../operations/admin/invite_token_generate.go | 71 +++++ ...go => invite_token_generate_parameters.go} | 20 +- .../admin/invite_token_generate_responses.go | 112 ++++++++ ...go => invite_token_generate_urlbuilder.go} | 24 +- rest_server_zrok/operations/zrok_api.go | 14 +- specs/zrok.yml | 22 +- ui/src/api/admin.js | 10 +- ui/src/api/types.js | 14 +- 27 files changed, 851 insertions(+), 855 deletions(-) rename cmd/zrok/{generate.go => adminGenerate.go} (75%) create mode 100644 controller/inviteTokenGenerate.go create mode 100644 controller/store/invite_tokens.go delete mode 100644 controller/store/invites.go delete mode 100644 rest_client_zrok/admin/invite_generate_parameters.go delete mode 100644 rest_client_zrok/admin/invite_generate_responses.go create mode 100644 rest_client_zrok/admin/invite_token_generate_parameters.go create mode 100644 rest_client_zrok/admin/invite_token_generate_responses.go delete mode 100644 rest_model_zrok/invite_generate_request.go create mode 100644 rest_model_zrok/invite_token_generate_request.go delete mode 100644 rest_server_zrok/operations/admin/invite_generate.go delete mode 100644 rest_server_zrok/operations/admin/invite_generate_responses.go create mode 100644 rest_server_zrok/operations/admin/invite_token_generate.go rename rest_server_zrok/operations/admin/{invite_generate_parameters.go => invite_token_generate_parameters.go} (71%) create mode 100644 rest_server_zrok/operations/admin/invite_token_generate_responses.go rename rest_server_zrok/operations/admin/{invite_generate_urlbuilder.go => invite_token_generate_urlbuilder.go} (71%) diff --git a/cmd/zrok/generate.go b/cmd/zrok/adminGenerate.go similarity index 75% rename from cmd/zrok/generate.go rename to cmd/zrok/adminGenerate.go index 1c8f2271..b083256c 100644 --- a/cmd/zrok/generate.go +++ b/cmd/zrok/adminGenerate.go @@ -11,21 +11,21 @@ import ( ) func init() { - adminCmd.AddCommand(newGenerateCommand().cmd) + adminCmd.AddCommand(newAdminGenerateCommand().cmd) } -type generateCommand struct { +type adminGenerateCommand struct { cmd *cobra.Command amount int } -func newGenerateCommand() *generateCommand { +func newAdminGenerateCommand() *adminGenerateCommand { cmd := &cobra.Command{ Use: "generate", Short: "Generate invite tokens (default: 5)", Args: cobra.ExactArgs(0), } - command := &generateCommand{cmd: cmd} + command := &adminGenerateCommand{cmd: cmd} cmd.Run = command.run cmd.Flags().IntVar(&command.amount, "amount", 5, "Amount of tokens to generate") @@ -33,7 +33,7 @@ func newGenerateCommand() *generateCommand { return command } -func (cmd *generateCommand) run(_ *cobra.Command, args []string) { +func (cmd *adminGenerateCommand) run(_ *cobra.Command, args []string) { var err error tokens := make([]string, cmd.amount) for i := 0; i < int(cmd.amount); i++ { @@ -49,11 +49,11 @@ func (cmd *generateCommand) run(_ *cobra.Command, args []string) { } panic(err) } - req := admin.NewInviteGenerateParams() - req.Body = &rest_model_zrok.InviteGenerateRequest{ + req := admin.NewInviteTokenGenerateParams() + req.Body = &rest_model_zrok.InviteTokenGenerateRequest{ Tokens: tokens, } - _, err = zrok.Admin.InviteGenerate(req, mustGetAdminAuth()) + _, err = zrok.Admin.InviteTokenGenerate(req, mustGetAdminAuth()) if err != nil { if !panicInstead { showError("error creating invite tokens", err) diff --git a/cmd/zrok/invite.go b/cmd/zrok/invite.go index e560a4ff..a8ea0b66 100644 --- a/cmd/zrok/invite.go +++ b/cmd/zrok/invite.go @@ -17,7 +17,7 @@ func init() { type inviteCommand struct { cmd *cobra.Command - Token string + token string } func newInviteCommand() *inviteCommand { @@ -30,7 +30,7 @@ func newInviteCommand() *inviteCommand { command := &inviteCommand{cmd: cmd} cmd.Run = command.run - cmd.Flags().StringVar(&command.Token, "token", "", "Invite token required when Zrok running in token store mode") + cmd.Flags().StringVar(&command.token, "token", "", "Invite token required when zrok running in token store mode") return command } @@ -61,7 +61,7 @@ func (cmd *inviteCommand) run(_ *cobra.Command, _ []string) { req := account.NewInviteParams() req.Body = &rest_model_zrok.InviteRequest{ Email: email, - Token: cmd.Token, + Token: cmd.token, } _, err = zrok.Account.Invite(req) if err != nil { diff --git a/controller/controller.go b/controller/controller.go index 1ec3c8db..d048622b 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -33,7 +33,7 @@ func Run(inCfg *Config) error { api.AdminCreateFrontendHandler = newCreateFrontendHandler() api.AdminCreateIdentityHandler = newCreateIdentityHandler() api.AdminDeleteFrontendHandler = newDeleteFrontendHandler() - api.AdminInviteGenerateHandler = newInviteGenerateHandler() + api.AdminInviteTokenGenerateHandler = newInviteTokenGenerateHandler() api.AdminListFrontendsHandler = newListFrontendsHandler() api.AdminUpdateFrontendHandler = newUpdateFrontendHandler() api.EnvironmentEnableHandler = newEnableHandler() diff --git a/controller/invite.go b/controller/invite.go index 5444f822..41d7bd21 100644 --- a/controller/invite.go +++ b/controller/invite.go @@ -3,9 +3,7 @@ package controller import ( "github.com/go-openapi/runtime/middleware" "github.com/openziti-test-kitchen/zrok/controller/store" - "github.com/openziti-test-kitchen/zrok/rest_model_zrok" "github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/account" - "github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/admin" "github.com/openziti-test-kitchen/zrok/util" "github.com/sirupsen/logrus" ) @@ -40,12 +38,12 @@ func (self *inviteHandler) Handle(params account.InviteParams) middleware.Respon defer func() { _ = tx.Rollback() }() if self.cfg.Registration.TokenStrategy == "store" { - invite, err := str.GetInviteByToken(params.Body.Token, tx) + invite, err := str.GetInviteTokenByToken(params.Body.Token, tx) if err != nil { logrus.Error(err) return account.NewInviteBadRequest() } - if err := str.DeleteInvite(invite.Id, tx); err != nil { + if err := str.DeleteInviteToken(invite.Id, tx); err != nil { logrus.Error(err) return account.NewInviteInternalServerError() } @@ -101,48 +99,3 @@ func (self *inviteHandler) Handle(params account.InviteParams) middleware.Respon return account.NewInviteCreated() } - -type inviteGenerateHandler struct { -} - -func newInviteGenerateHandler() *inviteGenerateHandler { - return &inviteGenerateHandler{} -} - -func (handler *inviteGenerateHandler) Handle(params admin.InviteGenerateParams, principal *rest_model_zrok.Principal) middleware.Responder { - if !principal.Admin { - logrus.Errorf("invalid admin principal") - return admin.NewInviteGenerateUnauthorized() - } - - if params.Body == nil || len(params.Body.Tokens) == 0 { - logrus.Error("missing tokens") - return admin.NewInviteGenerateBadRequest() - } - logrus.Infof("received invite generate request with %d tokens", len(params.Body.Tokens)) - - invites := make([]*store.Invite, len(params.Body.Tokens)) - for i, token := range params.Body.Tokens { - invites[i] = &store.Invite{ - Token: token, - } - } - tx, err := str.Begin() - if err != nil { - logrus.Error(err) - return admin.NewInviteGenerateInternalServerError() - } - defer func() { _ = tx.Rollback() }() - - if err := str.CreateInvites(invites, tx); err != nil { - logrus.Error(err) - return admin.NewInviteGenerateInternalServerError() - } - - if err := tx.Commit(); err != nil { - logrus.Errorf("error committing inviteGenerate request: %v", err) - return account.NewInviteInternalServerError() - } - - return admin.NewInviteGenerateCreated() -} diff --git a/controller/inviteTokenGenerate.go b/controller/inviteTokenGenerate.go new file mode 100644 index 00000000..db1ca853 --- /dev/null +++ b/controller/inviteTokenGenerate.go @@ -0,0 +1,55 @@ +package controller + +import ( + "github.com/go-openapi/runtime/middleware" + "github.com/openziti-test-kitchen/zrok/controller/store" + "github.com/openziti-test-kitchen/zrok/rest_model_zrok" + "github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/account" + "github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/admin" + "github.com/sirupsen/logrus" +) + +type inviteTokenGenerateHandler struct { +} + +func newInviteTokenGenerateHandler() *inviteTokenGenerateHandler { + return &inviteTokenGenerateHandler{} +} + +func (handler *inviteTokenGenerateHandler) Handle(params admin.InviteTokenGenerateParams, principal *rest_model_zrok.Principal) middleware.Responder { + if !principal.Admin { + logrus.Errorf("invalid admin principal") + return admin.NewInviteTokenGenerateUnauthorized() + } + + if params.Body == nil || len(params.Body.Tokens) == 0 { + logrus.Error("missing tokens") + return admin.NewInviteTokenGenerateBadRequest() + } + logrus.Infof("received invite generate request with %d tokens", len(params.Body.Tokens)) + + invites := make([]*store.InviteToken, len(params.Body.Tokens)) + for i, token := range params.Body.Tokens { + invites[i] = &store.InviteToken{ + Token: token, + } + } + tx, err := str.Begin() + if err != nil { + logrus.Error(err) + return admin.NewInviteTokenGenerateInternalServerError() + } + defer func() { _ = tx.Rollback() }() + + if err := str.CreateInviteTokens(invites, tx); err != nil { + logrus.Error(err) + return admin.NewInviteTokenGenerateInternalServerError() + } + + if err := tx.Commit(); err != nil { + logrus.Errorf("error committing inviteGenerate request: %v", err) + return account.NewInviteInternalServerError() + } + + return admin.NewInviteTokenGenerateCreated() +} diff --git a/controller/store/invite_tokens.go b/controller/store/invite_tokens.go new file mode 100644 index 00000000..5f381705 --- /dev/null +++ b/controller/store/invite_tokens.go @@ -0,0 +1,52 @@ +package store + +import ( + "fmt" + "strings" + + "github.com/jmoiron/sqlx" + "github.com/pkg/errors" +) + +type InviteToken struct { + Model + Token string +} + +func (str *Store) CreateInviteTokens(inviteTokens []*InviteToken, tx *sqlx.Tx) error { + sql := "insert into invite_tokens (token) values %s" + invs := make([]any, len(inviteTokens)) + queries := make([]string, len(inviteTokens)) + for i, inv := range inviteTokens { + invs[i] = inv.Token + queries[i] = fmt.Sprintf("($%d)", i+1) + } + stmt, err := tx.Prepare(fmt.Sprintf(sql, strings.Join(queries, ","))) + if err != nil { + return errors.Wrap(err, "error preparing invite_tokenss insert statement") + } + if _, err := stmt.Exec(invs...); err != nil { + return errors.Wrap(err, "error executing invites_tokens insert statement") + } + return nil +} + +func (str *Store) GetInviteTokenByToken(token string, tx *sqlx.Tx) (*InviteToken, error) { + inviteToken := &InviteToken{} + if err := tx.QueryRowx("select * from invite_tokens where token = $1", token).StructScan(inviteToken); err != nil { + return nil, errors.Wrap(err, "error getting unused invite_token") + } + return inviteToken, nil +} + +func (str *Store) DeleteInviteToken(id int, tx *sqlx.Tx) error { + stmt, err := tx.Prepare("delete from invite_tokens where id = $1") + if err != nil { + return errors.Wrap(err, "error preparing invite_tokens delete statement") + } + _, err = stmt.Exec(id) + if err != nil { + return errors.Wrap(err, "error executing invite_tokens delete statement") + } + return nil +} diff --git a/controller/store/invites.go b/controller/store/invites.go deleted file mode 100644 index 7de49e1b..00000000 --- a/controller/store/invites.go +++ /dev/null @@ -1,64 +0,0 @@ -package store - -import ( - "fmt" - "strings" - - "github.com/jmoiron/sqlx" - "github.com/pkg/errors" -) - -type Invite struct { - Model - Token string -} - -func (str *Store) CreateInvites(invites []*Invite, tx *sqlx.Tx) error { - sql := "insert into invites (token) values %s" - invs := make([]any, len(invites)) - queries := make([]string, len(invites)) - for i, inv := range invites { - invs[i] = inv.Token - queries[i] = fmt.Sprintf("($%d)", i+1) - } - stmt, err := tx.Prepare(fmt.Sprintf(sql, strings.Join(queries, ","))) - if err != nil { - return errors.Wrap(err, "error preparing invites insert statement") - } - if _, err := stmt.Exec(invs...); err != nil { - return errors.Wrap(err, "error executing invites insert statement") - } - return nil -} - -func (str *Store) GetInviteByToken(token string, tx *sqlx.Tx) (*Invite, error) { - invite := &Invite{} - if err := tx.QueryRowx("select * from invites where token = $1", token).StructScan(invite); err != nil { - return nil, errors.Wrap(err, "error getting unused invite") - } - return invite, nil -} - -func (str *Store) UpdateInvite(invite *Invite, tx *sqlx.Tx) error { - stmt, err := tx.Prepare("update invites set token = $1") - if err != nil { - return errors.Wrap(err, "error perparing invites update statement") - } - _, err = stmt.Exec(invite.Token) - if err != nil { - return errors.Wrap(err, "error executing invites update statement") - } - return nil -} - -func (str *Store) DeleteInvite(id int, tx *sqlx.Tx) error { - stmt, err := tx.Prepare("delete from invites where id = $1") - if err != nil { - return errors.Wrap(err, "error preparing invites delete statement") - } - _, err = stmt.Exec(id) - if err != nil { - return errors.Wrap(err, "error executing invites delete statement") - } - return nil -} diff --git a/controller/store/sql/postgresql/005_v0_3_0_invites.sql b/controller/store/sql/postgresql/005_v0_3_0_invites.sql index 42eec093..4765e3b7 100644 --- a/controller/store/sql/postgresql/005_v0_3_0_invites.sql +++ b/controller/store/sql/postgresql/005_v0_3_0_invites.sql @@ -1,10 +1,10 @@ -- +migrate Up -- --- invites +-- invite_tokens --- -create table invites ( +create table invite_tokens ( id serial primary key, token varchar(32) not null unique, created_at timestamptz not null default(current_timestamp), diff --git a/controller/store/sql/sqlite3/005_v0_3_0_invites.sql b/controller/store/sql/sqlite3/005_v0_3_0_invites.sql index f1f94ef0..a2932500 100644 --- a/controller/store/sql/sqlite3/005_v0_3_0_invites.sql +++ b/controller/store/sql/sqlite3/005_v0_3_0_invites.sql @@ -1,10 +1,10 @@ -- +migrate Up -- --- invites +-- invite_tokens --- -create table invites ( +create table invite_tokens ( id integer primary key, token string not null unique, created_at datetime not null default(strftime('%Y-%m-%d %H:%M:%f', 'now')), diff --git a/rest_client_zrok/admin/admin_client.go b/rest_client_zrok/admin/admin_client.go index e67503f8..6a329434 100644 --- a/rest_client_zrok/admin/admin_client.go +++ b/rest_client_zrok/admin/admin_client.go @@ -36,7 +36,7 @@ type ClientService interface { DeleteFrontend(params *DeleteFrontendParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*DeleteFrontendOK, error) - InviteGenerate(params *InviteGenerateParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*InviteGenerateCreated, error) + InviteTokenGenerate(params *InviteTokenGenerateParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*InviteTokenGenerateCreated, error) ListFrontends(params *ListFrontendsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*ListFrontendsOK, error) @@ -163,22 +163,22 @@ func (a *Client) DeleteFrontend(params *DeleteFrontendParams, authInfo runtime.C } /* -InviteGenerate invite generate API +InviteTokenGenerate invite token generate API */ -func (a *Client) InviteGenerate(params *InviteGenerateParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*InviteGenerateCreated, error) { +func (a *Client) InviteTokenGenerate(params *InviteTokenGenerateParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*InviteTokenGenerateCreated, error) { // TODO: Validate the params before sending if params == nil { - params = NewInviteGenerateParams() + params = NewInviteTokenGenerateParams() } op := &runtime.ClientOperation{ - ID: "inviteGenerate", + ID: "inviteTokenGenerate", Method: "POST", - PathPattern: "/invite/generate", + PathPattern: "/invite/token/generate", ProducesMediaTypes: []string{"application/zrok.v1+json"}, ConsumesMediaTypes: []string{"application/zrok.v1+json"}, Schemes: []string{"http"}, Params: params, - Reader: &InviteGenerateReader{formats: a.formats}, + Reader: &InviteTokenGenerateReader{formats: a.formats}, AuthInfo: authInfo, Context: params.Context, Client: params.HTTPClient, @@ -191,13 +191,13 @@ func (a *Client) InviteGenerate(params *InviteGenerateParams, authInfo runtime.C if err != nil { return nil, err } - success, ok := result.(*InviteGenerateCreated) + success, ok := result.(*InviteTokenGenerateCreated) 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 inviteGenerate: API contract not enforced by server. Client expected to get an error, but got: %T", result) + msg := fmt.Sprintf("unexpected success response for inviteTokenGenerate: API contract not enforced by server. Client expected to get an error, but got: %T", result) panic(msg) } diff --git a/rest_client_zrok/admin/invite_generate_parameters.go b/rest_client_zrok/admin/invite_generate_parameters.go deleted file mode 100644 index 031edf8f..00000000 --- a/rest_client_zrok/admin/invite_generate_parameters.go +++ /dev/null @@ -1,150 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package admin - -// 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" - - "github.com/openziti-test-kitchen/zrok/rest_model_zrok" -) - -// NewInviteGenerateParams creates a new InviteGenerateParams 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 NewInviteGenerateParams() *InviteGenerateParams { - return &InviteGenerateParams{ - timeout: cr.DefaultTimeout, - } -} - -// NewInviteGenerateParamsWithTimeout creates a new InviteGenerateParams object -// with the ability to set a timeout on a request. -func NewInviteGenerateParamsWithTimeout(timeout time.Duration) *InviteGenerateParams { - return &InviteGenerateParams{ - timeout: timeout, - } -} - -// NewInviteGenerateParamsWithContext creates a new InviteGenerateParams object -// with the ability to set a context for a request. -func NewInviteGenerateParamsWithContext(ctx context.Context) *InviteGenerateParams { - return &InviteGenerateParams{ - Context: ctx, - } -} - -// NewInviteGenerateParamsWithHTTPClient creates a new InviteGenerateParams object -// with the ability to set a custom HTTPClient for a request. -func NewInviteGenerateParamsWithHTTPClient(client *http.Client) *InviteGenerateParams { - return &InviteGenerateParams{ - HTTPClient: client, - } -} - -/* -InviteGenerateParams contains all the parameters to send to the API endpoint - - for the invite generate operation. - - Typically these are written to a http.Request. -*/ -type InviteGenerateParams struct { - - // Body. - Body *rest_model_zrok.InviteGenerateRequest - - timeout time.Duration - Context context.Context - HTTPClient *http.Client -} - -// WithDefaults hydrates default values in the invite generate params (not the query body). -// -// All values with no default are reset to their zero value. -func (o *InviteGenerateParams) WithDefaults() *InviteGenerateParams { - o.SetDefaults() - return o -} - -// SetDefaults hydrates default values in the invite generate params (not the query body). -// -// All values with no default are reset to their zero value. -func (o *InviteGenerateParams) SetDefaults() { - // no default values defined for this parameter -} - -// WithTimeout adds the timeout to the invite generate params -func (o *InviteGenerateParams) WithTimeout(timeout time.Duration) *InviteGenerateParams { - o.SetTimeout(timeout) - return o -} - -// SetTimeout adds the timeout to the invite generate params -func (o *InviteGenerateParams) SetTimeout(timeout time.Duration) { - o.timeout = timeout -} - -// WithContext adds the context to the invite generate params -func (o *InviteGenerateParams) WithContext(ctx context.Context) *InviteGenerateParams { - o.SetContext(ctx) - return o -} - -// SetContext adds the context to the invite generate params -func (o *InviteGenerateParams) SetContext(ctx context.Context) { - o.Context = ctx -} - -// WithHTTPClient adds the HTTPClient to the invite generate params -func (o *InviteGenerateParams) WithHTTPClient(client *http.Client) *InviteGenerateParams { - o.SetHTTPClient(client) - return o -} - -// SetHTTPClient adds the HTTPClient to the invite generate params -func (o *InviteGenerateParams) SetHTTPClient(client *http.Client) { - o.HTTPClient = client -} - -// WithBody adds the body to the invite generate params -func (o *InviteGenerateParams) WithBody(body *rest_model_zrok.InviteGenerateRequest) *InviteGenerateParams { - o.SetBody(body) - return o -} - -// SetBody adds the body to the invite generate params -func (o *InviteGenerateParams) SetBody(body *rest_model_zrok.InviteGenerateRequest) { - o.Body = body -} - -// WriteToRequest writes these params to a swagger request -func (o *InviteGenerateParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { - - if err := r.SetTimeout(o.timeout); err != nil { - return err - } - var res []error - if o.Body != nil { - if err := r.SetBodyParam(o.Body); err != nil { - return err - } - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} diff --git a/rest_client_zrok/admin/invite_generate_responses.go b/rest_client_zrok/admin/invite_generate_responses.go deleted file mode 100644 index 0fa45d45..00000000 --- a/rest_client_zrok/admin/invite_generate_responses.go +++ /dev/null @@ -1,254 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package admin - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - "fmt" - - "github.com/go-openapi/runtime" - "github.com/go-openapi/strfmt" -) - -// InviteGenerateReader is a Reader for the InviteGenerate structure. -type InviteGenerateReader struct { - formats strfmt.Registry -} - -// ReadResponse reads a server response into the received o. -func (o *InviteGenerateReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { - switch response.Code() { - case 201: - result := NewInviteGenerateCreated() - if err := result.readResponse(response, consumer, o.formats); err != nil { - return nil, err - } - return result, nil - case 400: - result := NewInviteGenerateBadRequest() - if err := result.readResponse(response, consumer, o.formats); err != nil { - return nil, err - } - return nil, result - case 401: - result := NewInviteGenerateUnauthorized() - if err := result.readResponse(response, consumer, o.formats); err != nil { - return nil, err - } - return nil, result - case 500: - result := NewInviteGenerateInternalServerError() - if err := result.readResponse(response, consumer, o.formats); err != nil { - return nil, err - } - return nil, result - 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()) - } -} - -// NewInviteGenerateCreated creates a InviteGenerateCreated with default headers values -func NewInviteGenerateCreated() *InviteGenerateCreated { - return &InviteGenerateCreated{} -} - -/* -InviteGenerateCreated describes a response with status code 201, with default header values. - -invitation tokens created -*/ -type InviteGenerateCreated struct { -} - -// IsSuccess returns true when this invite generate created response has a 2xx status code -func (o *InviteGenerateCreated) IsSuccess() bool { - return true -} - -// IsRedirect returns true when this invite generate created response has a 3xx status code -func (o *InviteGenerateCreated) IsRedirect() bool { - return false -} - -// IsClientError returns true when this invite generate created response has a 4xx status code -func (o *InviteGenerateCreated) IsClientError() bool { - return false -} - -// IsServerError returns true when this invite generate created response has a 5xx status code -func (o *InviteGenerateCreated) IsServerError() bool { - return false -} - -// IsCode returns true when this invite generate created response a status code equal to that given -func (o *InviteGenerateCreated) IsCode(code int) bool { - return code == 201 -} - -func (o *InviteGenerateCreated) Error() string { - return fmt.Sprintf("[POST /invite/generate][%d] inviteGenerateCreated ", 201) -} - -func (o *InviteGenerateCreated) String() string { - return fmt.Sprintf("[POST /invite/generate][%d] inviteGenerateCreated ", 201) -} - -func (o *InviteGenerateCreated) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { - - return nil -} - -// NewInviteGenerateBadRequest creates a InviteGenerateBadRequest with default headers values -func NewInviteGenerateBadRequest() *InviteGenerateBadRequest { - return &InviteGenerateBadRequest{} -} - -/* -InviteGenerateBadRequest describes a response with status code 400, with default header values. - -invitation tokens not created -*/ -type InviteGenerateBadRequest struct { -} - -// IsSuccess returns true when this invite generate bad request response has a 2xx status code -func (o *InviteGenerateBadRequest) IsSuccess() bool { - return false -} - -// IsRedirect returns true when this invite generate bad request response has a 3xx status code -func (o *InviteGenerateBadRequest) IsRedirect() bool { - return false -} - -// IsClientError returns true when this invite generate bad request response has a 4xx status code -func (o *InviteGenerateBadRequest) IsClientError() bool { - return true -} - -// IsServerError returns true when this invite generate bad request response has a 5xx status code -func (o *InviteGenerateBadRequest) IsServerError() bool { - return false -} - -// IsCode returns true when this invite generate bad request response a status code equal to that given -func (o *InviteGenerateBadRequest) IsCode(code int) bool { - return code == 400 -} - -func (o *InviteGenerateBadRequest) Error() string { - return fmt.Sprintf("[POST /invite/generate][%d] inviteGenerateBadRequest ", 400) -} - -func (o *InviteGenerateBadRequest) String() string { - return fmt.Sprintf("[POST /invite/generate][%d] inviteGenerateBadRequest ", 400) -} - -func (o *InviteGenerateBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { - - return nil -} - -// NewInviteGenerateUnauthorized creates a InviteGenerateUnauthorized with default headers values -func NewInviteGenerateUnauthorized() *InviteGenerateUnauthorized { - return &InviteGenerateUnauthorized{} -} - -/* -InviteGenerateUnauthorized describes a response with status code 401, with default header values. - -unauthorized -*/ -type InviteGenerateUnauthorized struct { -} - -// IsSuccess returns true when this invite generate unauthorized response has a 2xx status code -func (o *InviteGenerateUnauthorized) IsSuccess() bool { - return false -} - -// IsRedirect returns true when this invite generate unauthorized response has a 3xx status code -func (o *InviteGenerateUnauthorized) IsRedirect() bool { - return false -} - -// IsClientError returns true when this invite generate unauthorized response has a 4xx status code -func (o *InviteGenerateUnauthorized) IsClientError() bool { - return true -} - -// IsServerError returns true when this invite generate unauthorized response has a 5xx status code -func (o *InviteGenerateUnauthorized) IsServerError() bool { - return false -} - -// IsCode returns true when this invite generate unauthorized response a status code equal to that given -func (o *InviteGenerateUnauthorized) IsCode(code int) bool { - return code == 401 -} - -func (o *InviteGenerateUnauthorized) Error() string { - return fmt.Sprintf("[POST /invite/generate][%d] inviteGenerateUnauthorized ", 401) -} - -func (o *InviteGenerateUnauthorized) String() string { - return fmt.Sprintf("[POST /invite/generate][%d] inviteGenerateUnauthorized ", 401) -} - -func (o *InviteGenerateUnauthorized) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { - - return nil -} - -// NewInviteGenerateInternalServerError creates a InviteGenerateInternalServerError with default headers values -func NewInviteGenerateInternalServerError() *InviteGenerateInternalServerError { - return &InviteGenerateInternalServerError{} -} - -/* -InviteGenerateInternalServerError describes a response with status code 500, with default header values. - -internal server error -*/ -type InviteGenerateInternalServerError struct { -} - -// IsSuccess returns true when this invite generate internal server error response has a 2xx status code -func (o *InviteGenerateInternalServerError) IsSuccess() bool { - return false -} - -// IsRedirect returns true when this invite generate internal server error response has a 3xx status code -func (o *InviteGenerateInternalServerError) IsRedirect() bool { - return false -} - -// IsClientError returns true when this invite generate internal server error response has a 4xx status code -func (o *InviteGenerateInternalServerError) IsClientError() bool { - return false -} - -// IsServerError returns true when this invite generate internal server error response has a 5xx status code -func (o *InviteGenerateInternalServerError) IsServerError() bool { - return true -} - -// IsCode returns true when this invite generate internal server error response a status code equal to that given -func (o *InviteGenerateInternalServerError) IsCode(code int) bool { - return code == 500 -} - -func (o *InviteGenerateInternalServerError) Error() string { - return fmt.Sprintf("[POST /invite/generate][%d] inviteGenerateInternalServerError ", 500) -} - -func (o *InviteGenerateInternalServerError) String() string { - return fmt.Sprintf("[POST /invite/generate][%d] inviteGenerateInternalServerError ", 500) -} - -func (o *InviteGenerateInternalServerError) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { - - return nil -} diff --git a/rest_client_zrok/admin/invite_token_generate_parameters.go b/rest_client_zrok/admin/invite_token_generate_parameters.go new file mode 100644 index 00000000..ae9fdef6 --- /dev/null +++ b/rest_client_zrok/admin/invite_token_generate_parameters.go @@ -0,0 +1,150 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package admin + +// 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" + + "github.com/openziti-test-kitchen/zrok/rest_model_zrok" +) + +// NewInviteTokenGenerateParams creates a new InviteTokenGenerateParams 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 NewInviteTokenGenerateParams() *InviteTokenGenerateParams { + return &InviteTokenGenerateParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewInviteTokenGenerateParamsWithTimeout creates a new InviteTokenGenerateParams object +// with the ability to set a timeout on a request. +func NewInviteTokenGenerateParamsWithTimeout(timeout time.Duration) *InviteTokenGenerateParams { + return &InviteTokenGenerateParams{ + timeout: timeout, + } +} + +// NewInviteTokenGenerateParamsWithContext creates a new InviteTokenGenerateParams object +// with the ability to set a context for a request. +func NewInviteTokenGenerateParamsWithContext(ctx context.Context) *InviteTokenGenerateParams { + return &InviteTokenGenerateParams{ + Context: ctx, + } +} + +// NewInviteTokenGenerateParamsWithHTTPClient creates a new InviteTokenGenerateParams object +// with the ability to set a custom HTTPClient for a request. +func NewInviteTokenGenerateParamsWithHTTPClient(client *http.Client) *InviteTokenGenerateParams { + return &InviteTokenGenerateParams{ + HTTPClient: client, + } +} + +/* +InviteTokenGenerateParams contains all the parameters to send to the API endpoint + + for the invite token generate operation. + + Typically these are written to a http.Request. +*/ +type InviteTokenGenerateParams struct { + + // Body. + Body *rest_model_zrok.InviteTokenGenerateRequest + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the invite token generate params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *InviteTokenGenerateParams) WithDefaults() *InviteTokenGenerateParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the invite token generate params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *InviteTokenGenerateParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the invite token generate params +func (o *InviteTokenGenerateParams) WithTimeout(timeout time.Duration) *InviteTokenGenerateParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the invite token generate params +func (o *InviteTokenGenerateParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the invite token generate params +func (o *InviteTokenGenerateParams) WithContext(ctx context.Context) *InviteTokenGenerateParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the invite token generate params +func (o *InviteTokenGenerateParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the invite token generate params +func (o *InviteTokenGenerateParams) WithHTTPClient(client *http.Client) *InviteTokenGenerateParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the invite token generate params +func (o *InviteTokenGenerateParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithBody adds the body to the invite token generate params +func (o *InviteTokenGenerateParams) WithBody(body *rest_model_zrok.InviteTokenGenerateRequest) *InviteTokenGenerateParams { + o.SetBody(body) + return o +} + +// SetBody adds the body to the invite token generate params +func (o *InviteTokenGenerateParams) SetBody(body *rest_model_zrok.InviteTokenGenerateRequest) { + o.Body = body +} + +// WriteToRequest writes these params to a swagger request +func (o *InviteTokenGenerateParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + if o.Body != nil { + if err := r.SetBodyParam(o.Body); err != nil { + return err + } + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/rest_client_zrok/admin/invite_token_generate_responses.go b/rest_client_zrok/admin/invite_token_generate_responses.go new file mode 100644 index 00000000..c1394db8 --- /dev/null +++ b/rest_client_zrok/admin/invite_token_generate_responses.go @@ -0,0 +1,254 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package admin + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "fmt" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" +) + +// InviteTokenGenerateReader is a Reader for the InviteTokenGenerate structure. +type InviteTokenGenerateReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *InviteTokenGenerateReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { + switch response.Code() { + case 201: + result := NewInviteTokenGenerateCreated() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + case 400: + result := NewInviteTokenGenerateBadRequest() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 401: + result := NewInviteTokenGenerateUnauthorized() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 500: + result := NewInviteTokenGenerateInternalServerError() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + 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()) + } +} + +// NewInviteTokenGenerateCreated creates a InviteTokenGenerateCreated with default headers values +func NewInviteTokenGenerateCreated() *InviteTokenGenerateCreated { + return &InviteTokenGenerateCreated{} +} + +/* +InviteTokenGenerateCreated describes a response with status code 201, with default header values. + +invitation tokens created +*/ +type InviteTokenGenerateCreated struct { +} + +// IsSuccess returns true when this invite token generate created response has a 2xx status code +func (o *InviteTokenGenerateCreated) IsSuccess() bool { + return true +} + +// IsRedirect returns true when this invite token generate created response has a 3xx status code +func (o *InviteTokenGenerateCreated) IsRedirect() bool { + return false +} + +// IsClientError returns true when this invite token generate created response has a 4xx status code +func (o *InviteTokenGenerateCreated) IsClientError() bool { + return false +} + +// IsServerError returns true when this invite token generate created response has a 5xx status code +func (o *InviteTokenGenerateCreated) IsServerError() bool { + return false +} + +// IsCode returns true when this invite token generate created response a status code equal to that given +func (o *InviteTokenGenerateCreated) IsCode(code int) bool { + return code == 201 +} + +func (o *InviteTokenGenerateCreated) Error() string { + return fmt.Sprintf("[POST /invite/token/generate][%d] inviteTokenGenerateCreated ", 201) +} + +func (o *InviteTokenGenerateCreated) String() string { + return fmt.Sprintf("[POST /invite/token/generate][%d] inviteTokenGenerateCreated ", 201) +} + +func (o *InviteTokenGenerateCreated) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + return nil +} + +// NewInviteTokenGenerateBadRequest creates a InviteTokenGenerateBadRequest with default headers values +func NewInviteTokenGenerateBadRequest() *InviteTokenGenerateBadRequest { + return &InviteTokenGenerateBadRequest{} +} + +/* +InviteTokenGenerateBadRequest describes a response with status code 400, with default header values. + +invitation tokens not created +*/ +type InviteTokenGenerateBadRequest struct { +} + +// IsSuccess returns true when this invite token generate bad request response has a 2xx status code +func (o *InviteTokenGenerateBadRequest) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this invite token generate bad request response has a 3xx status code +func (o *InviteTokenGenerateBadRequest) IsRedirect() bool { + return false +} + +// IsClientError returns true when this invite token generate bad request response has a 4xx status code +func (o *InviteTokenGenerateBadRequest) IsClientError() bool { + return true +} + +// IsServerError returns true when this invite token generate bad request response has a 5xx status code +func (o *InviteTokenGenerateBadRequest) IsServerError() bool { + return false +} + +// IsCode returns true when this invite token generate bad request response a status code equal to that given +func (o *InviteTokenGenerateBadRequest) IsCode(code int) bool { + return code == 400 +} + +func (o *InviteTokenGenerateBadRequest) Error() string { + return fmt.Sprintf("[POST /invite/token/generate][%d] inviteTokenGenerateBadRequest ", 400) +} + +func (o *InviteTokenGenerateBadRequest) String() string { + return fmt.Sprintf("[POST /invite/token/generate][%d] inviteTokenGenerateBadRequest ", 400) +} + +func (o *InviteTokenGenerateBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + return nil +} + +// NewInviteTokenGenerateUnauthorized creates a InviteTokenGenerateUnauthorized with default headers values +func NewInviteTokenGenerateUnauthorized() *InviteTokenGenerateUnauthorized { + return &InviteTokenGenerateUnauthorized{} +} + +/* +InviteTokenGenerateUnauthorized describes a response with status code 401, with default header values. + +unauthorized +*/ +type InviteTokenGenerateUnauthorized struct { +} + +// IsSuccess returns true when this invite token generate unauthorized response has a 2xx status code +func (o *InviteTokenGenerateUnauthorized) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this invite token generate unauthorized response has a 3xx status code +func (o *InviteTokenGenerateUnauthorized) IsRedirect() bool { + return false +} + +// IsClientError returns true when this invite token generate unauthorized response has a 4xx status code +func (o *InviteTokenGenerateUnauthorized) IsClientError() bool { + return true +} + +// IsServerError returns true when this invite token generate unauthorized response has a 5xx status code +func (o *InviteTokenGenerateUnauthorized) IsServerError() bool { + return false +} + +// IsCode returns true when this invite token generate unauthorized response a status code equal to that given +func (o *InviteTokenGenerateUnauthorized) IsCode(code int) bool { + return code == 401 +} + +func (o *InviteTokenGenerateUnauthorized) Error() string { + return fmt.Sprintf("[POST /invite/token/generate][%d] inviteTokenGenerateUnauthorized ", 401) +} + +func (o *InviteTokenGenerateUnauthorized) String() string { + return fmt.Sprintf("[POST /invite/token/generate][%d] inviteTokenGenerateUnauthorized ", 401) +} + +func (o *InviteTokenGenerateUnauthorized) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + return nil +} + +// NewInviteTokenGenerateInternalServerError creates a InviteTokenGenerateInternalServerError with default headers values +func NewInviteTokenGenerateInternalServerError() *InviteTokenGenerateInternalServerError { + return &InviteTokenGenerateInternalServerError{} +} + +/* +InviteTokenGenerateInternalServerError describes a response with status code 500, with default header values. + +internal server error +*/ +type InviteTokenGenerateInternalServerError struct { +} + +// IsSuccess returns true when this invite token generate internal server error response has a 2xx status code +func (o *InviteTokenGenerateInternalServerError) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this invite token generate internal server error response has a 3xx status code +func (o *InviteTokenGenerateInternalServerError) IsRedirect() bool { + return false +} + +// IsClientError returns true when this invite token generate internal server error response has a 4xx status code +func (o *InviteTokenGenerateInternalServerError) IsClientError() bool { + return false +} + +// IsServerError returns true when this invite token generate internal server error response has a 5xx status code +func (o *InviteTokenGenerateInternalServerError) IsServerError() bool { + return true +} + +// IsCode returns true when this invite token generate internal server error response a status code equal to that given +func (o *InviteTokenGenerateInternalServerError) IsCode(code int) bool { + return code == 500 +} + +func (o *InviteTokenGenerateInternalServerError) Error() string { + return fmt.Sprintf("[POST /invite/token/generate][%d] inviteTokenGenerateInternalServerError ", 500) +} + +func (o *InviteTokenGenerateInternalServerError) String() string { + return fmt.Sprintf("[POST /invite/token/generate][%d] inviteTokenGenerateInternalServerError ", 500) +} + +func (o *InviteTokenGenerateInternalServerError) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + return nil +} diff --git a/rest_model_zrok/invite_generate_request.go b/rest_model_zrok/invite_generate_request.go deleted file mode 100644 index f662c3d5..00000000 --- a/rest_model_zrok/invite_generate_request.go +++ /dev/null @@ -1,50 +0,0 @@ -// 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" -) - -// InviteGenerateRequest invite generate request -// -// swagger:model inviteGenerateRequest -type InviteGenerateRequest struct { - - // tokens - Tokens []string `json:"tokens"` -} - -// Validate validates this invite generate request -func (m *InviteGenerateRequest) Validate(formats strfmt.Registry) error { - return nil -} - -// ContextValidate validates this invite generate request based on context it is used -func (m *InviteGenerateRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error { - return nil -} - -// MarshalBinary interface implementation -func (m *InviteGenerateRequest) MarshalBinary() ([]byte, error) { - if m == nil { - return nil, nil - } - return swag.WriteJSON(m) -} - -// UnmarshalBinary interface implementation -func (m *InviteGenerateRequest) UnmarshalBinary(b []byte) error { - var res InviteGenerateRequest - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *m = res - return nil -} diff --git a/rest_model_zrok/invite_token_generate_request.go b/rest_model_zrok/invite_token_generate_request.go new file mode 100644 index 00000000..94ae7072 --- /dev/null +++ b/rest_model_zrok/invite_token_generate_request.go @@ -0,0 +1,50 @@ +// 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" +) + +// InviteTokenGenerateRequest invite token generate request +// +// swagger:model inviteTokenGenerateRequest +type InviteTokenGenerateRequest struct { + + // tokens + Tokens []string `json:"tokens"` +} + +// Validate validates this invite token generate request +func (m *InviteTokenGenerateRequest) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this invite token generate request based on context it is used +func (m *InviteTokenGenerateRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *InviteTokenGenerateRequest) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *InviteTokenGenerateRequest) UnmarshalBinary(b []byte) error { + var res InviteTokenGenerateRequest + 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 ecc14e22..2db04dae 100644 --- a/rest_server_zrok/embedded_spec.go +++ b/rest_server_zrok/embedded_spec.go @@ -431,7 +431,7 @@ func init() { } } }, - "/invite/generate": { + "/invite/token/generate": { "post": { "security": [ { @@ -441,13 +441,13 @@ func init() { "tags": [ "admin" ], - "operationId": "inviteGenerate", + "operationId": "inviteTokenGenerate", "parameters": [ { "name": "body", "in": "body", "schema": { - "$ref": "#/definitions/inviteGenerateRequest" + "$ref": "#/definitions/inviteTokenGenerateRequest" } } ], @@ -895,17 +895,6 @@ func init() { "errorMessage": { "type": "string" }, - "inviteGenerateRequest": { - "type": "object", - "properties": { - "tokens": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, "inviteRequest": { "type": "object", "properties": { @@ -917,6 +906,17 @@ func init() { } } }, + "inviteTokenGenerateRequest": { + "type": "object", + "properties": { + "tokens": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, "loginRequest": { "type": "object", "properties": { @@ -1599,7 +1599,7 @@ func init() { } } }, - "/invite/generate": { + "/invite/token/generate": { "post": { "security": [ { @@ -1609,13 +1609,13 @@ func init() { "tags": [ "admin" ], - "operationId": "inviteGenerate", + "operationId": "inviteTokenGenerate", "parameters": [ { "name": "body", "in": "body", "schema": { - "$ref": "#/definitions/inviteGenerateRequest" + "$ref": "#/definitions/inviteTokenGenerateRequest" } } ], @@ -2063,17 +2063,6 @@ func init() { "errorMessage": { "type": "string" }, - "inviteGenerateRequest": { - "type": "object", - "properties": { - "tokens": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, "inviteRequest": { "type": "object", "properties": { @@ -2085,6 +2074,17 @@ func init() { } } }, + "inviteTokenGenerateRequest": { + "type": "object", + "properties": { + "tokens": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, "loginRequest": { "type": "object", "properties": { diff --git a/rest_server_zrok/operations/admin/invite_generate.go b/rest_server_zrok/operations/admin/invite_generate.go deleted file mode 100644 index a881fc0d..00000000 --- a/rest_server_zrok/operations/admin/invite_generate.go +++ /dev/null @@ -1,71 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package admin - -// 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" - - "github.com/openziti-test-kitchen/zrok/rest_model_zrok" -) - -// InviteGenerateHandlerFunc turns a function with the right signature into a invite generate handler -type InviteGenerateHandlerFunc func(InviteGenerateParams, *rest_model_zrok.Principal) middleware.Responder - -// Handle executing the request and returning a response -func (fn InviteGenerateHandlerFunc) Handle(params InviteGenerateParams, principal *rest_model_zrok.Principal) middleware.Responder { - return fn(params, principal) -} - -// InviteGenerateHandler interface for that can handle valid invite generate params -type InviteGenerateHandler interface { - Handle(InviteGenerateParams, *rest_model_zrok.Principal) middleware.Responder -} - -// NewInviteGenerate creates a new http.Handler for the invite generate operation -func NewInviteGenerate(ctx *middleware.Context, handler InviteGenerateHandler) *InviteGenerate { - return &InviteGenerate{Context: ctx, Handler: handler} -} - -/* - InviteGenerate swagger:route POST /invite/generate admin inviteGenerate - -InviteGenerate invite generate API -*/ -type InviteGenerate struct { - Context *middleware.Context - Handler InviteGenerateHandler -} - -func (o *InviteGenerate) ServeHTTP(rw http.ResponseWriter, r *http.Request) { - route, rCtx, _ := o.Context.RouteInfo(r) - if rCtx != nil { - *r = *rCtx - } - var Params = NewInviteGenerateParams() - uprinc, aCtx, err := o.Context.Authorize(r, route) - if err != nil { - o.Context.Respond(rw, r, route.Produces, route, err) - return - } - if aCtx != nil { - *r = *aCtx - } - var principal *rest_model_zrok.Principal - if uprinc != nil { - principal = uprinc.(*rest_model_zrok.Principal) // this is really a rest_model_zrok.Principal, I promise - } - - 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, principal) // actually handle the request - o.Context.Respond(rw, r, route.Produces, route, res) - -} diff --git a/rest_server_zrok/operations/admin/invite_generate_responses.go b/rest_server_zrok/operations/admin/invite_generate_responses.go deleted file mode 100644 index 9aaf1cec..00000000 --- a/rest_server_zrok/operations/admin/invite_generate_responses.go +++ /dev/null @@ -1,112 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package admin - -// 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" -) - -// InviteGenerateCreatedCode is the HTTP code returned for type InviteGenerateCreated -const InviteGenerateCreatedCode int = 201 - -/* -InviteGenerateCreated invitation tokens created - -swagger:response inviteGenerateCreated -*/ -type InviteGenerateCreated struct { -} - -// NewInviteGenerateCreated creates InviteGenerateCreated with default headers values -func NewInviteGenerateCreated() *InviteGenerateCreated { - - return &InviteGenerateCreated{} -} - -// WriteResponse to the client -func (o *InviteGenerateCreated) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { - - rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses - - rw.WriteHeader(201) -} - -// InviteGenerateBadRequestCode is the HTTP code returned for type InviteGenerateBadRequest -const InviteGenerateBadRequestCode int = 400 - -/* -InviteGenerateBadRequest invitation tokens not created - -swagger:response inviteGenerateBadRequest -*/ -type InviteGenerateBadRequest struct { -} - -// NewInviteGenerateBadRequest creates InviteGenerateBadRequest with default headers values -func NewInviteGenerateBadRequest() *InviteGenerateBadRequest { - - return &InviteGenerateBadRequest{} -} - -// WriteResponse to the client -func (o *InviteGenerateBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { - - rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses - - rw.WriteHeader(400) -} - -// InviteGenerateUnauthorizedCode is the HTTP code returned for type InviteGenerateUnauthorized -const InviteGenerateUnauthorizedCode int = 401 - -/* -InviteGenerateUnauthorized unauthorized - -swagger:response inviteGenerateUnauthorized -*/ -type InviteGenerateUnauthorized struct { -} - -// NewInviteGenerateUnauthorized creates InviteGenerateUnauthorized with default headers values -func NewInviteGenerateUnauthorized() *InviteGenerateUnauthorized { - - return &InviteGenerateUnauthorized{} -} - -// WriteResponse to the client -func (o *InviteGenerateUnauthorized) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { - - rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses - - rw.WriteHeader(401) -} - -// InviteGenerateInternalServerErrorCode is the HTTP code returned for type InviteGenerateInternalServerError -const InviteGenerateInternalServerErrorCode int = 500 - -/* -InviteGenerateInternalServerError internal server error - -swagger:response inviteGenerateInternalServerError -*/ -type InviteGenerateInternalServerError struct { -} - -// NewInviteGenerateInternalServerError creates InviteGenerateInternalServerError with default headers values -func NewInviteGenerateInternalServerError() *InviteGenerateInternalServerError { - - return &InviteGenerateInternalServerError{} -} - -// WriteResponse to the client -func (o *InviteGenerateInternalServerError) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { - - rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses - - rw.WriteHeader(500) -} diff --git a/rest_server_zrok/operations/admin/invite_token_generate.go b/rest_server_zrok/operations/admin/invite_token_generate.go new file mode 100644 index 00000000..ade6d94c --- /dev/null +++ b/rest_server_zrok/operations/admin/invite_token_generate.go @@ -0,0 +1,71 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package admin + +// 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" + + "github.com/openziti-test-kitchen/zrok/rest_model_zrok" +) + +// InviteTokenGenerateHandlerFunc turns a function with the right signature into a invite token generate handler +type InviteTokenGenerateHandlerFunc func(InviteTokenGenerateParams, *rest_model_zrok.Principal) middleware.Responder + +// Handle executing the request and returning a response +func (fn InviteTokenGenerateHandlerFunc) Handle(params InviteTokenGenerateParams, principal *rest_model_zrok.Principal) middleware.Responder { + return fn(params, principal) +} + +// InviteTokenGenerateHandler interface for that can handle valid invite token generate params +type InviteTokenGenerateHandler interface { + Handle(InviteTokenGenerateParams, *rest_model_zrok.Principal) middleware.Responder +} + +// NewInviteTokenGenerate creates a new http.Handler for the invite token generate operation +func NewInviteTokenGenerate(ctx *middleware.Context, handler InviteTokenGenerateHandler) *InviteTokenGenerate { + return &InviteTokenGenerate{Context: ctx, Handler: handler} +} + +/* + InviteTokenGenerate swagger:route POST /invite/token/generate admin inviteTokenGenerate + +InviteTokenGenerate invite token generate API +*/ +type InviteTokenGenerate struct { + Context *middleware.Context + Handler InviteTokenGenerateHandler +} + +func (o *InviteTokenGenerate) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + *r = *rCtx + } + var Params = NewInviteTokenGenerateParams() + uprinc, aCtx, err := o.Context.Authorize(r, route) + if err != nil { + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + if aCtx != nil { + *r = *aCtx + } + var principal *rest_model_zrok.Principal + if uprinc != nil { + principal = uprinc.(*rest_model_zrok.Principal) // this is really a rest_model_zrok.Principal, I promise + } + + 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, principal) // actually handle the request + o.Context.Respond(rw, r, route.Produces, route, res) + +} diff --git a/rest_server_zrok/operations/admin/invite_generate_parameters.go b/rest_server_zrok/operations/admin/invite_token_generate_parameters.go similarity index 71% rename from rest_server_zrok/operations/admin/invite_generate_parameters.go rename to rest_server_zrok/operations/admin/invite_token_generate_parameters.go index 845c04cf..bbab6f6e 100644 --- a/rest_server_zrok/operations/admin/invite_generate_parameters.go +++ b/rest_server_zrok/operations/admin/invite_token_generate_parameters.go @@ -16,19 +16,19 @@ import ( "github.com/openziti-test-kitchen/zrok/rest_model_zrok" ) -// NewInviteGenerateParams creates a new InviteGenerateParams object +// NewInviteTokenGenerateParams creates a new InviteTokenGenerateParams object // // There are no default values defined in the spec. -func NewInviteGenerateParams() InviteGenerateParams { +func NewInviteTokenGenerateParams() InviteTokenGenerateParams { - return InviteGenerateParams{} + return InviteTokenGenerateParams{} } -// InviteGenerateParams contains all the bound params for the invite generate operation +// InviteTokenGenerateParams contains all the bound params for the invite token generate operation // typically these are obtained from a http.Request // -// swagger:parameters inviteGenerate -type InviteGenerateParams struct { +// swagger:parameters inviteTokenGenerate +type InviteTokenGenerateParams struct { // HTTP Request Object HTTPRequest *http.Request `json:"-"` @@ -36,21 +36,21 @@ type InviteGenerateParams struct { /* In: body */ - Body *rest_model_zrok.InviteGenerateRequest + Body *rest_model_zrok.InviteTokenGenerateRequest } // 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 NewInviteGenerateParams() beforehand. -func (o *InviteGenerateParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { +// To ensure default values, the struct must have been initialized with NewInviteTokenGenerateParams() beforehand. +func (o *InviteTokenGenerateParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { var res []error o.HTTPRequest = r if runtime.HasBody(r) { defer r.Body.Close() - var body rest_model_zrok.InviteGenerateRequest + var body rest_model_zrok.InviteTokenGenerateRequest if err := route.Consumer.Consume(r.Body, &body); err != nil { res = append(res, errors.NewParseError("body", "body", "", err)) } else { diff --git a/rest_server_zrok/operations/admin/invite_token_generate_responses.go b/rest_server_zrok/operations/admin/invite_token_generate_responses.go new file mode 100644 index 00000000..2126a9cc --- /dev/null +++ b/rest_server_zrok/operations/admin/invite_token_generate_responses.go @@ -0,0 +1,112 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package admin + +// 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" +) + +// InviteTokenGenerateCreatedCode is the HTTP code returned for type InviteTokenGenerateCreated +const InviteTokenGenerateCreatedCode int = 201 + +/* +InviteTokenGenerateCreated invitation tokens created + +swagger:response inviteTokenGenerateCreated +*/ +type InviteTokenGenerateCreated struct { +} + +// NewInviteTokenGenerateCreated creates InviteTokenGenerateCreated with default headers values +func NewInviteTokenGenerateCreated() *InviteTokenGenerateCreated { + + return &InviteTokenGenerateCreated{} +} + +// WriteResponse to the client +func (o *InviteTokenGenerateCreated) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + + rw.WriteHeader(201) +} + +// InviteTokenGenerateBadRequestCode is the HTTP code returned for type InviteTokenGenerateBadRequest +const InviteTokenGenerateBadRequestCode int = 400 + +/* +InviteTokenGenerateBadRequest invitation tokens not created + +swagger:response inviteTokenGenerateBadRequest +*/ +type InviteTokenGenerateBadRequest struct { +} + +// NewInviteTokenGenerateBadRequest creates InviteTokenGenerateBadRequest with default headers values +func NewInviteTokenGenerateBadRequest() *InviteTokenGenerateBadRequest { + + return &InviteTokenGenerateBadRequest{} +} + +// WriteResponse to the client +func (o *InviteTokenGenerateBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + + rw.WriteHeader(400) +} + +// InviteTokenGenerateUnauthorizedCode is the HTTP code returned for type InviteTokenGenerateUnauthorized +const InviteTokenGenerateUnauthorizedCode int = 401 + +/* +InviteTokenGenerateUnauthorized unauthorized + +swagger:response inviteTokenGenerateUnauthorized +*/ +type InviteTokenGenerateUnauthorized struct { +} + +// NewInviteTokenGenerateUnauthorized creates InviteTokenGenerateUnauthorized with default headers values +func NewInviteTokenGenerateUnauthorized() *InviteTokenGenerateUnauthorized { + + return &InviteTokenGenerateUnauthorized{} +} + +// WriteResponse to the client +func (o *InviteTokenGenerateUnauthorized) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + + rw.WriteHeader(401) +} + +// InviteTokenGenerateInternalServerErrorCode is the HTTP code returned for type InviteTokenGenerateInternalServerError +const InviteTokenGenerateInternalServerErrorCode int = 500 + +/* +InviteTokenGenerateInternalServerError internal server error + +swagger:response inviteTokenGenerateInternalServerError +*/ +type InviteTokenGenerateInternalServerError struct { +} + +// NewInviteTokenGenerateInternalServerError creates InviteTokenGenerateInternalServerError with default headers values +func NewInviteTokenGenerateInternalServerError() *InviteTokenGenerateInternalServerError { + + return &InviteTokenGenerateInternalServerError{} +} + +// WriteResponse to the client +func (o *InviteTokenGenerateInternalServerError) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + + rw.WriteHeader(500) +} diff --git a/rest_server_zrok/operations/admin/invite_generate_urlbuilder.go b/rest_server_zrok/operations/admin/invite_token_generate_urlbuilder.go similarity index 71% rename from rest_server_zrok/operations/admin/invite_generate_urlbuilder.go rename to rest_server_zrok/operations/admin/invite_token_generate_urlbuilder.go index 15c48dc1..be3e757e 100644 --- a/rest_server_zrok/operations/admin/invite_generate_urlbuilder.go +++ b/rest_server_zrok/operations/admin/invite_token_generate_urlbuilder.go @@ -11,15 +11,15 @@ import ( golangswaggerpaths "path" ) -// InviteGenerateURL generates an URL for the invite generate operation -type InviteGenerateURL struct { +// InviteTokenGenerateURL generates an URL for the invite token generate operation +type InviteTokenGenerateURL 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 *InviteGenerateURL) WithBasePath(bp string) *InviteGenerateURL { +func (o *InviteTokenGenerateURL) WithBasePath(bp string) *InviteTokenGenerateURL { o.SetBasePath(bp) return o } @@ -27,15 +27,15 @@ func (o *InviteGenerateURL) WithBasePath(bp string) *InviteGenerateURL { // 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 *InviteGenerateURL) SetBasePath(bp string) { +func (o *InviteTokenGenerateURL) SetBasePath(bp string) { o._basePath = bp } // Build a url path and query string -func (o *InviteGenerateURL) Build() (*url.URL, error) { +func (o *InviteTokenGenerateURL) Build() (*url.URL, error) { var _result url.URL - var _path = "/invite/generate" + var _path = "/invite/token/generate" _basePath := o._basePath if _basePath == "" { @@ -47,7 +47,7 @@ func (o *InviteGenerateURL) Build() (*url.URL, error) { } // Must is a helper function to panic when the url builder returns an error -func (o *InviteGenerateURL) Must(u *url.URL, err error) *url.URL { +func (o *InviteTokenGenerateURL) Must(u *url.URL, err error) *url.URL { if err != nil { panic(err) } @@ -58,17 +58,17 @@ func (o *InviteGenerateURL) Must(u *url.URL, err error) *url.URL { } // String returns the string representation of the path with query string -func (o *InviteGenerateURL) String() string { +func (o *InviteTokenGenerateURL) String() string { return o.Must(o.Build()).String() } // BuildFull builds a full url with scheme, host, path and query string -func (o *InviteGenerateURL) BuildFull(scheme, host string) (*url.URL, error) { +func (o *InviteTokenGenerateURL) BuildFull(scheme, host string) (*url.URL, error) { if scheme == "" { - return nil, errors.New("scheme is required for a full url on InviteGenerateURL") + return nil, errors.New("scheme is required for a full url on InviteTokenGenerateURL") } if host == "" { - return nil, errors.New("host is required for a full url on InviteGenerateURL") + return nil, errors.New("host is required for a full url on InviteTokenGenerateURL") } base, err := o.Build() @@ -82,6 +82,6 @@ func (o *InviteGenerateURL) BuildFull(scheme, host string) (*url.URL, error) { } // StringFull returns the string representation of a complete url -func (o *InviteGenerateURL) StringFull(scheme, host string) string { +func (o *InviteTokenGenerateURL) 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 60b210ed..d13c7cfa 100644 --- a/rest_server_zrok/operations/zrok_api.go +++ b/rest_server_zrok/operations/zrok_api.go @@ -76,8 +76,8 @@ func NewZrokAPI(spec *loads.Document) *ZrokAPI { AccountInviteHandler: account.InviteHandlerFunc(func(params account.InviteParams) middleware.Responder { return middleware.NotImplemented("operation account.Invite has not yet been implemented") }), - AdminInviteGenerateHandler: admin.InviteGenerateHandlerFunc(func(params admin.InviteGenerateParams, principal *rest_model_zrok.Principal) middleware.Responder { - return middleware.NotImplemented("operation admin.InviteGenerate has not yet been implemented") + AdminInviteTokenGenerateHandler: admin.InviteTokenGenerateHandlerFunc(func(params admin.InviteTokenGenerateParams, principal *rest_model_zrok.Principal) middleware.Responder { + return middleware.NotImplemented("operation admin.InviteTokenGenerate has not yet been implemented") }), AdminListFrontendsHandler: admin.ListFrontendsHandlerFunc(func(params admin.ListFrontendsParams, principal *rest_model_zrok.Principal) middleware.Responder { return middleware.NotImplemented("operation admin.ListFrontends has not yet been implemented") @@ -180,8 +180,8 @@ type ZrokAPI struct { MetadataGetShareDetailHandler metadata.GetShareDetailHandler // AccountInviteHandler sets the operation handler for the invite operation AccountInviteHandler account.InviteHandler - // AdminInviteGenerateHandler sets the operation handler for the invite generate operation - AdminInviteGenerateHandler admin.InviteGenerateHandler + // AdminInviteTokenGenerateHandler sets the operation handler for the invite token generate operation + AdminInviteTokenGenerateHandler admin.InviteTokenGenerateHandler // AdminListFrontendsHandler sets the operation handler for the list frontends operation AdminListFrontendsHandler admin.ListFrontendsHandler // AccountLoginHandler sets the operation handler for the login operation @@ -312,8 +312,8 @@ func (o *ZrokAPI) Validate() error { if o.AccountInviteHandler == nil { unregistered = append(unregistered, "account.InviteHandler") } - if o.AdminInviteGenerateHandler == nil { - unregistered = append(unregistered, "admin.InviteGenerateHandler") + if o.AdminInviteTokenGenerateHandler == nil { + unregistered = append(unregistered, "admin.InviteTokenGenerateHandler") } if o.AdminListFrontendsHandler == nil { unregistered = append(unregistered, "admin.ListFrontendsHandler") @@ -486,7 +486,7 @@ func (o *ZrokAPI) initHandlerCache() { if o.handlers["POST"] == nil { o.handlers["POST"] = make(map[string]http.Handler) } - o.handlers["POST"]["/invite/generate"] = admin.NewInviteGenerate(o.context, o.AdminInviteGenerateHandler) + o.handlers["POST"]["/invite/token/generate"] = admin.NewInviteTokenGenerate(o.context, o.AdminInviteTokenGenerateHandler) if o.handlers["GET"] == nil { o.handlers["GET"] = make(map[string]http.Handler) } diff --git a/specs/zrok.yml b/specs/zrok.yml index b86b8111..4780f9cb 100644 --- a/specs/zrok.yml +++ b/specs/zrok.yml @@ -203,18 +203,18 @@ paths: 500: description: internal server error - /invite/generate: + /invite/token/generate: post: tags: - admin security: - key: [] - operationId: inviteGenerate + operationId: inviteTokenGenerate parameters: - name: body in: body schema: - $ref: "#/definitions/inviteGenerateRequest" + $ref: "#/definitions/inviteTokenGenerateRequest" responses: 201: description: invitation tokens created @@ -574,6 +574,14 @@ definitions: errorMessage: type: string + inviteTokenGenerateRequest: + type: object + properties: + tokens: + type: array + items: + type: string + inviteRequest: type: object properties: @@ -764,14 +772,6 @@ definitions: version: type: string - inviteGenerateRequest: - type: object - properties: - tokens: - type: array - items: - type: string - produces: - application/zrok.v1+json consumes: diff --git a/ui/src/api/admin.js b/ui/src/api/admin.js index ca9a4d54..14974e5e 100644 --- a/ui/src/api/admin.js +++ b/ui/src/api/admin.js @@ -70,17 +70,17 @@ export function createIdentity(options) { /** * @param {object} options Optional options - * @param {module:types.inviteGenerateRequest} [options.body] + * @param {module:types.inviteTokenGenerateRequest} [options.body] * @return {Promise} invitation tokens created */ -export function inviteGenerate(options) { +export function inviteTokenGenerate(options) { if (!options) options = {} const parameters = { body: { body: options.body } } - return gateway.request(inviteGenerateOperation, parameters) + return gateway.request(inviteTokenGenerateOperation, parameters) } const createFrontendOperation = { @@ -137,8 +137,8 @@ const createIdentityOperation = { ] } -const inviteGenerateOperation = { - path: '/invite/generate', +const inviteTokenGenerateOperation = { + path: '/invite/token/generate', contentTypes: ['application/zrok.v1+json'], method: 'post', security: [ diff --git a/ui/src/api/types.js b/ui/src/api/types.js index f34b8a2c..0990b59a 100644 --- a/ui/src/api/types.js +++ b/ui/src/api/types.js @@ -91,6 +91,13 @@ * @property {module:types.shares} shares */ +/** + * @typedef inviteTokenGenerateRequest + * @memberof module:types + * + * @property {string[]} tokens + */ + /** * @typedef inviteRequest * @memberof module:types @@ -231,10 +238,3 @@ * * @property {string} email */ - -/** - * @typedef inviteGenerateRequest - * @memberof module:types - * - * @property {string[]} tokens - */ From bdb2b9c6f0c01fcf25fd65d257d3acfc4b5ce54b Mon Sep 17 00:00:00 2001 From: Cam Otts Date: Thu, 12 Jan 2023 10:11:37 -0600 Subject: [PATCH 07/13] updated to use new zrokdir --- cmd/zrok/adminGenerate.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/cmd/zrok/adminGenerate.go b/cmd/zrok/adminGenerate.go index b083256c..918ca4c2 100644 --- a/cmd/zrok/adminGenerate.go +++ b/cmd/zrok/adminGenerate.go @@ -7,6 +7,7 @@ import ( "github.com/openziti-test-kitchen/zrok/rest_client_zrok/admin" "github.com/openziti-test-kitchen/zrok/rest_model_zrok" "github.com/openziti-test-kitchen/zrok/zrokdir" + "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -39,13 +40,19 @@ func (cmd *adminGenerateCommand) run(_ *cobra.Command, args []string) { for i := 0; i < int(cmd.amount); i++ { tokens[i], err = createToken() if err != nil { - showError("error creating token", err) + logrus.Error("error creating token", err) } } - zrok, err := zrokdir.ZrokClient(apiEndpoint) + + zrd, err := zrokdir.Load() + if err != nil { + logrus.Error("error loading zrokdir", err) + } + + zrok, err := zrd.Client() if err != nil { if !panicInstead { - showError("error creating zrok api client", err) + logrus.Error("error creating zrok api client", err) } panic(err) } @@ -56,7 +63,7 @@ func (cmd *adminGenerateCommand) run(_ *cobra.Command, args []string) { _, err = zrok.Admin.InviteTokenGenerate(req, mustGetAdminAuth()) if err != nil { if !panicInstead { - showError("error creating invite tokens", err) + logrus.Error("error creating invite tokens", err) } panic(err) } From 6035207f2e4e00a82952cd130e96fb1e478ef110 Mon Sep 17 00:00:00 2001 From: Michael Quigley Date: Thu, 12 Jan 2023 13:02:32 -0500 Subject: [PATCH 08/13] improved self-service error messages for zrok invite and zrok enable (#145) --- cmd/zrok/enable.go | 12 +++++++++++- cmd/zrok/invite.go | 40 ++++++++++++++++++++++++---------------- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/cmd/zrok/enable.go b/cmd/zrok/enable.go index 043895d4..2fb3f100 100644 --- a/cmd/zrok/enable.go +++ b/cmd/zrok/enable.go @@ -57,7 +57,8 @@ func (cmd *enableCommand) run(_ *cobra.Command, args []string) { } zrok, err := zrd.Client() if err != nil { - panic(err) + cmd.endpointError(zrd.ApiEndpoint()) + tui.Error("error creating service client", err) } auth := httptransport.APIKeyAuth("X-TOKEN", "header", token) req := environment.NewEnableParams() @@ -87,6 +88,7 @@ func (cmd *enableCommand) run(_ *cobra.Command, args []string) { prg.Send(fmt.Sprintf("the zrok service returned an error: %v", err)) prg.Quit() <-done + cmd.endpointError(zrd.ApiEndpoint()) os.Exit(1) } prg.Send("writing the environment details...") @@ -110,6 +112,14 @@ func (cmd *enableCommand) run(_ *cobra.Command, args []string) { <-done } +func (cmd *enableCommand) endpointError(apiEndpoint, _ string) { + fmt.Printf("%v\n\n", tui.ErrorStyle.Render("there was a problem enabling your environment!")) + fmt.Printf("you are trying to use the zrok service at: %v\n\n", tui.CodeStyle.Render(apiEndpoint)) + fmt.Printf("you can change your zrok service endpoint using this command:\n\n") + fmt.Printf("%v\n\n", tui.CodeStyle.Render("$ zrok config set apiEndpoint ")) + fmt.Printf("(where newEndpoint is something like: %v)\n\n", tui.CodeStyle.Render("https://some.zrok.io")) +} + func getHost() (string, string, error) { info, err := host.Info() if err != nil { diff --git a/cmd/zrok/invite.go b/cmd/zrok/invite.go index 49628980..1d714a43 100644 --- a/cmd/zrok/invite.go +++ b/cmd/zrok/invite.go @@ -44,6 +44,20 @@ func newInviteCommand() *inviteCommand { } func (cmd *inviteCommand) run(_ *cobra.Command, _ []string) { + zrd, err := zrokdir.Load() + if err != nil { + tui.Error("error loading zrokdir", err) + } + + zrok, err := zrd.Client() + if err != nil { + if !panicInstead { + cmd.endpointError(zrd.ApiEndpoint()) + tui.Error("error creating zrok api client", err) + } + panic(err) + } + if _, err := tea.NewProgram(&cmd.tui).Run(); err != nil { tui.Error("unable to run interface", err) os.Exit(1) @@ -51,18 +65,6 @@ func (cmd *inviteCommand) run(_ *cobra.Command, _ []string) { if cmd.tui.done { email := cmd.tui.inputs[0].Value() - zrd, err := zrokdir.Load() - if err != nil { - tui.Error("error loading zrokdir", err) - } - - zrok, err := zrd.Client() - if err != nil { - if !panicInstead { - tui.Error("error creating zrok api client", err) - } - panic(err) - } req := account.NewInviteParams() req.Body = &rest_model_zrok.InviteRequest{ Email: email, @@ -70,16 +72,22 @@ func (cmd *inviteCommand) run(_ *cobra.Command, _ []string) { } _, err = zrok.Account.Invite(req) if err != nil { - if !panicInstead { - tui.Error("error creating invitation", err) - } - panic(err) + cmd.endpointError(zrd.ApiEndpoint()) + tui.Error("error creating invitation", err) } fmt.Printf("invitation sent to '%v'!\n", email) } } +func (cmd *inviteCommand) endpointError(apiEndpoint, _ string) { + fmt.Printf("%v\n\n", tui.ErrorStyle.Render("there was a problem creating an invitation!")) + fmt.Printf("you are trying to use the zrok service at: %v\n\n", tui.CodeStyle.Render(apiEndpoint)) + fmt.Printf("you can change your zrok service endpoint using this command:\n\n") + fmt.Printf("%v\n\n", tui.CodeStyle.Render("$ zrok config set apiEndpoint ")) + fmt.Printf("(where newEndpoint is something like: %v)\n\n", tui.CodeStyle.Render("https://some.zrok.io")) +} + type inviteTui struct { focusIndex int msg string From 6a4f2b86bec7b36b9eb20be685e3715dec2a7cb2 Mon Sep 17 00:00:00 2001 From: Michael Quigley Date: Thu, 12 Jan 2023 13:10:20 -0500 Subject: [PATCH 09/13] don't just use some generic 'red' (#56) --- cmd/zrok/invite.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/zrok/invite.go b/cmd/zrok/invite.go index 1d714a43..27bf0659 100644 --- a/cmd/zrok/invite.go +++ b/cmd/zrok/invite.go @@ -111,9 +111,9 @@ func newInviteTui() inviteTui { m := inviteTui{ inputs: make([]textinput.Model, 2), } - m.focusedStyle = tui.WarningStyle - m.blurredStyle = tui.CodeStyle - m.errorStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#F00")) + m.focusedStyle = tui.WarningStyle.Copy() + m.blurredStyle = tui.CodeStyle.Copy() + m.errorStyle = tui.ErrorStyle.Copy() m.cursorStyle = m.focusedStyle.Copy() m.noStyle = lipgloss.NewStyle() m.helpStyle = m.blurredStyle.Copy() From 627d9eb882a404adcf92e0d4094b64733365adde Mon Sep 17 00:00:00 2001 From: Michael Quigley Date: Thu, 12 Jan 2023 14:17:09 -0500 Subject: [PATCH 10/13] the 'registration' stanza should not be required (#147) --- controller/invite.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controller/invite.go b/controller/invite.go index 41d7bd21..a91b50cb 100644 --- a/controller/invite.go +++ b/controller/invite.go @@ -37,7 +37,7 @@ func (self *inviteHandler) Handle(params account.InviteParams) middleware.Respon } defer func() { _ = tx.Rollback() }() - if self.cfg.Registration.TokenStrategy == "store" { + if self.cfg.Registration != nil && self.cfg.Registration.TokenStrategy == "store" { invite, err := str.GetInviteTokenByToken(params.Body.Token, tx) if err != nil { logrus.Error(err) From f40e6efb24716b85462438a4dd5124335ea6c4c1 Mon Sep 17 00:00:00 2001 From: Michael Quigley Date: Thu, 12 Jan 2023 14:48:50 -0500 Subject: [PATCH 11/13] ui lint --- ui/src/console/detail/Detail.js | 9 +++++---- ui/src/console/detail/account/AccountDetail.js | 2 +- ui/src/console/detail/environment/SharesTab.js | 2 -- ui/src/console/detail/share/ShareDetail.js | 8 +++++--- ui/src/console/visualizer/Network.js | 13 ++++++++----- ui/src/register/InvalidRequest.js | 2 +- 6 files changed, 20 insertions(+), 16 deletions(-) diff --git a/ui/src/console/detail/Detail.js b/ui/src/console/detail/Detail.js index 18959f34..3c5b1aea 100644 --- a/ui/src/console/detail/Detail.js +++ b/ui/src/console/detail/Detail.js @@ -6,16 +6,17 @@ const Detail = (props) => { let detailComponent =

{props.selection.id} ({props.selection.type})

; switch(props.selection.type) { - case "account": - detailComponent = ; - break; - case "environment": detailComponent = ; break; case "share": detailComponent = ; + break; + + default: + detailComponent = ; + break; } return ( diff --git a/ui/src/console/detail/account/AccountDetail.js b/ui/src/console/detail/account/AccountDetail.js index a2c0a627..cad7bcef 100644 --- a/ui/src/console/detail/account/AccountDetail.js +++ b/ui/src/console/detail/account/AccountDetail.js @@ -1,4 +1,4 @@ -import {mdiCardAccountDetails, mdiEyeOutline, mdiEyeOffOutline} from "@mdi/js"; +import {mdiCardAccountDetails} from "@mdi/js"; import Icon from "@mdi/react"; import PropertyTable from "../../PropertyTable"; import {Tab, Tabs} from "react-bootstrap"; diff --git a/ui/src/console/detail/environment/SharesTab.js b/ui/src/console/detail/environment/SharesTab.js index f2087b80..333c8c7c 100644 --- a/ui/src/console/detail/environment/SharesTab.js +++ b/ui/src/console/detail/environment/SharesTab.js @@ -2,8 +2,6 @@ import * as metadata from "../../../api/metadata"; import {useEffect, useState} from "react"; import DataTable from 'react-data-table-component'; import {Sparklines, SparklinesLine, SparklinesSpots} from "react-sparklines"; -import {mdiConsoleNetwork} from "@mdi/js"; -import Icon from "@mdi/react"; const SharesTab = (props) => { const [detail, setDetail] = useState({}); diff --git a/ui/src/console/detail/share/ShareDetail.js b/ui/src/console/detail/share/ShareDetail.js index dbbf820a..be78206b 100644 --- a/ui/src/console/detail/share/ShareDetail.js +++ b/ui/src/console/detail/share/ShareDetail.js @@ -25,9 +25,11 @@ const ShareDetail = (props) => { let interval = setInterval(() => { metadata.getShareDetail(props.selection.id) .then(resp => { - let detail = resp.data; - detail.envZId = props.selection.envZId; - setDetail(detail); + if(mounted) { + let detail = resp.data; + detail.envZId = props.selection.envZId; + setDetail(detail); + } }); }, 1000); return () => { diff --git a/ui/src/console/visualizer/Network.js b/ui/src/console/visualizer/Network.js index 382b318f..62819e59 100644 --- a/ui/src/console/visualizer/Network.js +++ b/ui/src/console/visualizer/Network.js @@ -22,9 +22,13 @@ const Network = (props) => { case "environment": nodeColor = "#444"; break; - case "share": + + case "share": // share nodeColor = "#291A66"; break; + + default: + // } ctx.textBaseline = "middle"; @@ -41,10 +45,9 @@ const Network = (props) => { ctx.strokeStyle = "#c4bdde"; ctx.stroke(); } else { - switch(node.type) { - case "share": - ctx.strokeStyle = "#433482"; - ctx.stroke(); + if(node.type === "share") { + ctx.strokeStyle = "#433482"; + ctx.stroke(); } } diff --git a/ui/src/register/InvalidRequest.js b/ui/src/register/InvalidRequest.js index 32d0c824..e90a8892 100644 --- a/ui/src/register/InvalidRequest.js +++ b/ui/src/register/InvalidRequest.js @@ -1,4 +1,4 @@ -import {Button, Container, Row} from "react-bootstrap"; +import {Container, Row} from "react-bootstrap"; const InvalidRequest = () => { return ( From 63edd0ed486fc18cedbb0a287664961167c5c86b Mon Sep 17 00:00:00 2001 From: Michael Quigley Date: Thu, 12 Jan 2023 15:01:34 -0500 Subject: [PATCH 12/13] logging improvements --- controller/invite.go | 7 ++++--- controller/store/invite_tokens.go | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/controller/invite.go b/controller/invite.go index a91b50cb..0979cb2f 100644 --- a/controller/invite.go +++ b/controller/invite.go @@ -38,15 +38,16 @@ func (self *inviteHandler) Handle(params account.InviteParams) middleware.Respon defer func() { _ = tx.Rollback() }() if self.cfg.Registration != nil && self.cfg.Registration.TokenStrategy == "store" { - invite, err := str.GetInviteTokenByToken(params.Body.Token, tx) + inviteToken, err := str.GetInviteTokenByToken(params.Body.Token, tx) if err != nil { - logrus.Error(err) + logrus.Errorf("cannot get invite token '%v' for '%v': %v", params.Body.Token, params.Body.Email, err) return account.NewInviteBadRequest() } - if err := str.DeleteInviteToken(invite.Id, tx); err != nil { + if err := str.DeleteInviteToken(inviteToken.Id, tx); err != nil { logrus.Error(err) return account.NewInviteInternalServerError() } + logrus.Infof("using invite token '%v' to process invite request for '%v'", inviteToken.Token, params.Body.Email) } token, err = createToken() diff --git a/controller/store/invite_tokens.go b/controller/store/invite_tokens.go index 5f381705..3ffa14c3 100644 --- a/controller/store/invite_tokens.go +++ b/controller/store/invite_tokens.go @@ -23,7 +23,7 @@ func (str *Store) CreateInviteTokens(inviteTokens []*InviteToken, tx *sqlx.Tx) e } stmt, err := tx.Prepare(fmt.Sprintf(sql, strings.Join(queries, ","))) if err != nil { - return errors.Wrap(err, "error preparing invite_tokenss insert statement") + return errors.Wrap(err, "error preparing invite_tokens insert statement") } if _, err := stmt.Exec(invs...); err != nil { return errors.Wrap(err, "error executing invites_tokens insert statement") From 7324c01fe8999404caa22793e334faa6463a4bab Mon Sep 17 00:00:00 2001 From: Michael Quigley Date: Thu, 12 Jan 2023 15:12:48 -0500 Subject: [PATCH 13/13] controller config defaults --- controller/config.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/controller/config.go b/controller/config.go index c22c249f..fcb9ef1f 100644 --- a/controller/config.go +++ b/controller/config.go @@ -59,10 +59,14 @@ type InfluxConfig struct { Token string `cf:"+secret"` } -func LoadConfig(path string) (*Config, error) { - cfg := &Config{ +func DefaultConfig() *Config { + return &Config{ Metrics: &MetricsConfig{ServiceName: "metrics"}, } +} + +func LoadConfig(path string) (*Config, error) { + cfg := DefaultConfig() if err := cf.BindYaml(cfg, path, cf.DefaultOptions()); err != nil { return nil, errors.Wrapf(err, "error loading controller config '%v'", path) }