mirror of
https://github.com/openziti/zrok.git
synced 2024-11-21 23:53:19 +01:00
basic unique name implementation (#123)
This commit is contained in:
parent
ead350b442
commit
f61b2c9086
@ -6,6 +6,7 @@ import (
|
||||
"github.com/openziti/zrok/environment"
|
||||
"github.com/openziti/zrok/sdk/golang/sdk"
|
||||
"github.com/openziti/zrok/tui"
|
||||
"github.com/openziti/zrok/util"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"slices"
|
||||
@ -17,6 +18,7 @@ func init() {
|
||||
}
|
||||
|
||||
type reserveCommand struct {
|
||||
uniqueName string
|
||||
basicAuth []string
|
||||
frontendSelection []string
|
||||
backendMode string
|
||||
@ -34,6 +36,7 @@ func newReserveCommand() *reserveCommand {
|
||||
Args: cobra.ExactArgs(2),
|
||||
}
|
||||
command := &reserveCommand{cmd: cmd}
|
||||
cmd.Flags().StringVarP(&command.uniqueName, "unique-name", "n", "", "A unique name for the reserved share (defaults to generated identifier)")
|
||||
cmd.Flags().StringArrayVar(&command.frontendSelection, "frontends", []string{"public"}, "Selected frontends to use for the share")
|
||||
cmd.Flags().StringVarP(&command.backendMode, "backend-mode", "b", "proxy", "The backend mode (public|private: proxy, web, caddy, drive) (private: tcpTunnel, udpTunnel)")
|
||||
cmd.Flags().BoolVarP(&command.jsonOutput, "json-output", "j", false, "Emit JSON describing the created reserved share")
|
||||
@ -56,6 +59,10 @@ func (cmd *reserveCommand) run(_ *cobra.Command, args []string) {
|
||||
tui.Error(fmt.Sprintf("invalid sharing mode for a %s share: %s", sdk.PublicShareMode, cmd.backendMode), nil)
|
||||
}
|
||||
|
||||
if cmd.uniqueName != "" && !util.IsValidUniqueName(cmd.uniqueName) {
|
||||
tui.Error("invalid unique name; must be lowercase alphanumeric, between 4 and 32 characters in length, screened for profanity", nil)
|
||||
}
|
||||
|
||||
var target string
|
||||
switch cmd.backendMode {
|
||||
case "proxy":
|
||||
@ -95,6 +102,7 @@ func (cmd *reserveCommand) run(_ *cobra.Command, args []string) {
|
||||
|
||||
req := &sdk.ShareRequest{
|
||||
Reserved: true,
|
||||
UniqueName: cmd.uniqueName,
|
||||
BackendMode: sdk.BackendMode(cmd.backendMode),
|
||||
ShareMode: shareMode,
|
||||
BasicAuth: cmd.basicAuth,
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"github.com/openziti/zrok/rest_model_zrok"
|
||||
"github.com/openziti/zrok/rest_server_zrok/operations/share"
|
||||
"github.com/openziti/zrok/sdk/golang/sdk"
|
||||
"github.com/openziti/zrok/util"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
@ -33,14 +34,14 @@ func (h *shareHandler) Handle(params share.ShareParams, principal *rest_model_zr
|
||||
found := false
|
||||
for _, env := range envs {
|
||||
if env.ZId == envZId {
|
||||
logrus.Debugf("found identity '%v' for user '%v'", envZId, principal.Email)
|
||||
logrus.Debugf("found identity '%v' for account '%v'", envZId, principal.Email)
|
||||
envId = env.Id
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
logrus.Errorf("environment '%v' not found for user '%v'", envZId, principal.Email)
|
||||
logrus.Errorf("environment '%v' not found for account '%v'", envZId, principal.Email)
|
||||
return share.NewShareUnauthorized()
|
||||
}
|
||||
} else {
|
||||
@ -58,11 +59,21 @@ func (h *shareHandler) Handle(params share.ShareParams, principal *rest_model_zr
|
||||
logrus.Error(err)
|
||||
return share.NewShareInternalServerError()
|
||||
}
|
||||
|
||||
reserved := params.Body.Reserved
|
||||
uniqueName := params.Body.UniqueName
|
||||
shrToken, err := createShareToken()
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
return share.NewShareInternalServerError()
|
||||
}
|
||||
if reserved && uniqueName != "" {
|
||||
if !util.IsValidUniqueName(uniqueName) {
|
||||
logrus.Errorf("invalid unique name '%v' for account '%v'", uniqueName, principal.Email)
|
||||
return share.NewShareUnprocessableEntity()
|
||||
}
|
||||
shrToken = uniqueName
|
||||
}
|
||||
|
||||
var shrZId string
|
||||
var frontendEndpoints []string
|
||||
@ -94,7 +105,6 @@ func (h *shareHandler) Handle(params share.ShareParams, principal *rest_model_zr
|
||||
}
|
||||
|
||||
case string(sdk.PrivateShareMode):
|
||||
logrus.Info("doing private")
|
||||
shrZId, frontendEndpoints, err = newPrivateResourceAllocator().allocate(envZId, shrToken, params, edge)
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
@ -108,7 +118,6 @@ func (h *shareHandler) Handle(params share.ShareParams, principal *rest_model_zr
|
||||
|
||||
logrus.Debugf("allocated share '%v'", shrToken)
|
||||
|
||||
reserved := params.Body.Reserved
|
||||
sshr := &store.Share{
|
||||
ZId: shrZId,
|
||||
Token: shrToken,
|
||||
|
@ -0,0 +1,7 @@
|
||||
-- +migrate Up
|
||||
|
||||
-- remove the old unique index (which did not respect the deleted flag)
|
||||
ALTER TABLE shares DROP CONSTRAINT shares_token_key;
|
||||
|
||||
-- add a new unique index which only constrains uniqueness for not-deleted rows
|
||||
CREATE UNIQUE INDEX shares_token_idx ON shares(token) WHERE deleted is false;
|
3
go.mod
3
go.mod
@ -3,6 +3,7 @@ module github.com/openziti/zrok
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/TwiN/go-away v1.6.12
|
||||
github.com/caddyserver/caddy/v2 v2.7.5-0.20230829153420-ed8bb13c5df7
|
||||
github.com/charmbracelet/bubbles v0.14.0
|
||||
github.com/charmbracelet/bubbletea v0.23.1
|
||||
@ -226,7 +227,7 @@ require (
|
||||
golang.org/x/sync v0.3.0 // indirect
|
||||
golang.org/x/sys v0.11.0 // indirect
|
||||
golang.org/x/term v0.11.0 // indirect
|
||||
golang.org/x/text v0.12.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/tools v0.10.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 // indirect
|
||||
|
6
go.sum
6
go.sum
@ -114,6 +114,8 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/TwiN/go-away v1.6.12 h1:80AjDyeTjfQaSFYbALzRcDKMAmxKW0a5PoxwXKZlW2A=
|
||||
github.com/TwiN/go-away v1.6.12/go.mod h1:MpvIC9Li3minq+CGgbgUDvQ9tDaeW35k5IXZrF9MVas=
|
||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
||||
@ -1792,8 +1794,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
@ -22,6 +22,7 @@ const (
|
||||
|
||||
type ShareRequest struct {
|
||||
Reserved bool
|
||||
UniqueName string
|
||||
BackendMode BackendMode
|
||||
ShareMode ShareMode
|
||||
Target string
|
||||
|
@ -26,6 +26,9 @@ func CreateShare(root env_core.Root, request *ShareRequest) (*Share, error) {
|
||||
return nil, errors.Errorf("unknown share mode '%v'", request.ShareMode)
|
||||
}
|
||||
out.Body.Reserved = request.Reserved
|
||||
if request.Reserved {
|
||||
out.Body.UniqueName = request.UniqueName
|
||||
}
|
||||
|
||||
if len(request.BasicAuth) > 0 {
|
||||
out.Body.AuthScheme = string(Basic)
|
||||
|
@ -27,6 +27,8 @@ def CreateShare(root: Root, request: model.ShareRequest) -> model.Share:
|
||||
if request.OauthProvider != "":
|
||||
out.auth_scheme = model.AUTH_SCHEME_OAUTH
|
||||
|
||||
|
||||
|
||||
try:
|
||||
zrok = root.Client()
|
||||
except Exception as e:
|
||||
|
18
util/uniqueName.go
Normal file
18
util/uniqueName.go
Normal file
@ -0,0 +1,18 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
goaway "github.com/TwiN/go-away"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// IsValidUniqueName ensures that the string represents a valid unique name. Lowercase alphanumeric only. 4-32 characters.
|
||||
func IsValidUniqueName(uniqueName string) bool {
|
||||
match, err := regexp.Match("^[a-z0-9]{4,32}$", []byte(uniqueName))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if match && goaway.IsProfane(uniqueName) {
|
||||
return false
|
||||
}
|
||||
return match
|
||||
}
|
Loading…
Reference in New Issue
Block a user