cmd/uplink: fix some issues with share

Because --readonly is default true, passing something like
--disallow-deletes=false would not actually update that
value because the readonly flag would override. this makes it
so that the --disallow-* flags override the --readonly and
--writeonly flags.

Also fixes some minor formatting issues with share like an
extra space after the "Public Access:" entry.

Simplifies the handling of the explicit "none" by making the
flags for the dates optional and using nil to signify that
the value was left unset.

Bump the go.mod to go1.18 to enable the use of generics and
add a small generic function. This can easily be backed out
if it causes problems.

Change-Id: I1c5f1321ad17b8ace778ce55561cbbfc24321a68
This commit is contained in:
Jeff Wendling 2022-12-05 11:08:28 -05:00 committed by Storj Robot
parent 66b4509276
commit f2fdd6ca33
5 changed files with 49 additions and 68 deletions

View File

@ -19,16 +19,16 @@ import (
type accessPermissions struct {
prefixes []uplink.SharePrefix // prefixes is the set of path prefixes that the grant will be limited to
readonly bool // implies disallowWrites and disallowDeletes
writeonly bool // implies disallowReads and disallowLists
readonly bool
writeonly bool
disallowDeletes bool
disallowLists bool
disallowReads bool
disallowWrites bool
disallowDeletes *bool
disallowLists *bool
disallowReads *bool
disallowWrites *bool
notBefore time.Time
notAfter NoneDate
notBefore *time.Time
notAfter *time.Time
}
func (ap *accessPermissions) Setup(params clingy.Parameters, prefixFlags bool) {
@ -45,21 +45,25 @@ func (ap *accessPermissions) Setup(params clingy.Parameters, prefixFlags bool) {
ap.writeonly = params.Flag("writeonly", "Implies --disallow-reads and --disallow-lists", false,
clingy.Transform(strconv.ParseBool), clingy.Boolean).(bool)
ap.disallowDeletes = params.Flag("disallow-deletes", "Disallow deletes with the access", false,
clingy.Transform(strconv.ParseBool), clingy.Boolean).(bool)
ap.disallowLists = params.Flag("disallow-lists", "Disallow lists with the access", false,
clingy.Transform(strconv.ParseBool), clingy.Boolean).(bool)
ap.disallowReads = params.Flag("disallow-reads", "Disallow reads with the access", false,
clingy.Transform(strconv.ParseBool), clingy.Boolean).(bool)
ap.disallowWrites = params.Flag("disallow-writes", "Disallow writes with the access", false,
clingy.Transform(strconv.ParseBool), clingy.Boolean).(bool)
params.Break()
ap.disallowDeletes = params.Flag("disallow-deletes", "Disallow deletes with the access", nil,
clingy.Transform(strconv.ParseBool), clingy.Boolean, clingy.Optional).(*bool)
ap.disallowLists = params.Flag("disallow-lists", "Disallow lists with the access", nil,
clingy.Transform(strconv.ParseBool), clingy.Boolean, clingy.Optional).(*bool)
ap.disallowReads = params.Flag("disallow-reads", "Disallow reads with the access", nil,
clingy.Transform(strconv.ParseBool), clingy.Boolean, clingy.Optional).(*bool)
ap.disallowWrites = params.Flag("disallow-writes", "Disallow writes with the access", nil,
clingy.Transform(strconv.ParseBool), clingy.Boolean, clingy.Optional).(*bool)
params.Break()
ap.notBefore = params.Flag("not-before",
"Disallow access before this time (e.g. '+2h', 'now', '2020-01-02T15:04:05Z0700')",
time.Time{}, clingy.Transform(parseHumanDate), clingy.Type("relative_date")).(time.Time)
"Disallow access before this time (e.g. '+2h', 'now', '2020-01-02T15:04:05Z0700', 'none')",
nil, clingy.Transform(parseHumanDate), clingy.Type("relative_date"), clingy.Optional).(*time.Time)
ap.notAfter = params.Flag("not-after",
"Disallow access after this time (e.g. '+2h', 'now', '2020-01-02T15:04:05Z0700')", NoneDate{},
clingy.Transform(parseNoneDate)).(NoneDate)
"Disallow access after this time (e.g. '+2h', 'now', '2020-01-02T15:04:05Z0700', 'none')",
nil, clingy.Transform(parseHumanDate), clingy.Type("relative_date"), clingy.Optional).(*time.Time)
if !prefixFlags {
ap.prefixes = params.Arg("prefix", "Key prefix access will be restricted to",
@ -87,8 +91,8 @@ func (ap *accessPermissions) Apply(access *uplink.Access) (*uplink.Access, error
AllowList: ap.AllowList(),
AllowDownload: ap.AllowDownload(),
AllowUpload: ap.AllowUpload(),
NotBefore: ap.notBefore,
NotAfter: ap.notAfter.Date,
NotBefore: ap.NotBefore(),
NotAfter: ap.NotAfter(),
}
// if we aren't actually restricting anything, then we don't need to Share.
@ -109,18 +113,16 @@ func (ap *accessPermissions) Apply(access *uplink.Access) (*uplink.Access, error
return access, nil
}
func (ap *accessPermissions) AllowDelete() bool {
return !ap.disallowDeletes && !ap.readonly
func defaulted[T any](val *T, def T) T {
if val != nil {
return *val
}
return def
}
func (ap *accessPermissions) AllowList() bool {
return !ap.disallowLists && !ap.writeonly
}
func (ap *accessPermissions) AllowDownload() bool {
return !ap.disallowReads && !ap.writeonly
}
func (ap *accessPermissions) AllowUpload() bool {
return !ap.disallowWrites && !ap.readonly
}
func (ap *accessPermissions) NotBefore() time.Time { return defaulted(ap.notBefore, time.Time{}) }
func (ap *accessPermissions) NotAfter() time.Time { return defaulted(ap.notAfter, time.Time{}) }
func (ap *accessPermissions) AllowDelete() bool { return !defaulted(ap.disallowDeletes, ap.readonly) }
func (ap *accessPermissions) AllowList() bool { return !defaulted(ap.disallowLists, ap.writeonly) }
func (ap *accessPermissions) AllowDownload() bool { return !defaulted(ap.disallowReads, ap.writeonly) }
func (ap *accessPermissions) AllowUpload() bool { return !defaulted(ap.disallowWrites, ap.readonly) }

View File

@ -82,7 +82,7 @@ func (c *cmdShare) Execute(ctx context.Context) error {
if c.public {
c.register = true
if c.ap.notAfter.IsImplicitZero() {
if c.ap.notAfter == nil {
fmt.Fprintf(clingy.Stdout(ctx), "It's not recommended to create a shared Access without an expiration date.\n")
fmt.Fprintf(clingy.Stdout(ctx), "If you wish to do so anyway, please run this command with --not-after=none.\n")
return nil
@ -100,8 +100,8 @@ func (c *cmdShare) Execute(ctx context.Context) error {
fmt.Fprintf(clingy.Stdout(ctx), "Upload : %s\n", formatPermission(c.ap.AllowUpload()))
fmt.Fprintf(clingy.Stdout(ctx), "Lists : %s\n", formatPermission(c.ap.AllowList()))
fmt.Fprintf(clingy.Stdout(ctx), "Deletes : %s\n", formatPermission(c.ap.AllowDelete()))
fmt.Fprintf(clingy.Stdout(ctx), "NotBefore : %s\n", formatTimeRestriction(c.ap.notBefore))
fmt.Fprintf(clingy.Stdout(ctx), "NotAfter : %s\n", formatTimeRestriction(c.ap.notAfter.Date))
fmt.Fprintf(clingy.Stdout(ctx), "NotBefore : %s\n", formatTimeRestriction(c.ap.NotBefore()))
fmt.Fprintf(clingy.Stdout(ctx), "NotAfter : %s\n", formatTimeRestriction(c.ap.NotAfter()))
fmt.Fprintf(clingy.Stdout(ctx), "Paths : %s\n", formatPaths(c.ap.prefixes))
fmt.Fprintf(clingy.Stdout(ctx), "=========== SERIALIZED ACCESS WITH THE ABOVE RESTRICTIONS TO SHARE WITH OTHERS ===========\n")
fmt.Fprintf(clingy.Stdout(ctx), "Access : %s\n", newAccessData)
@ -115,7 +115,7 @@ func (c *cmdShare) Execute(ctx context.Context) error {
if err != nil {
return err
}
_, err = fmt.Fprintln(clingy.Stdout(ctx), "Public Access: ", c.public)
_, err = fmt.Fprintln(clingy.Stdout(ctx), "Public Access:", c.public)
if err != nil {
return err
}
@ -311,7 +311,7 @@ func DisplayGatewayCredentials(ctx context.Context, credentials edge.Credentials
return err
}
default: // plain text
_, err = fmt.Fprintf(clingy.Stdout(ctx), "========== CREDENTIALS ===================================================================\n"+
_, err = fmt.Fprintf(clingy.Stdout(ctx), "========== GATEWAY CREDENTIALS ===========================================================\n"+
"Access Key ID: %s\n"+
"Secret Key : %s\n"+
"Endpoint : %s\n",

View File

@ -53,31 +53,16 @@ func parseHumanDate(date string) (time.Time, error) {
return time.Now().Add(d), errs.Wrap(err)
default:
t, err := time.Parse(time.RFC3339, date)
if err != nil {
d, err := time.ParseDuration(date)
if err == nil {
return time.Now().Add(d), nil
}
}
return t, errs.Wrap(err)
}
}
// NoneDate is a date type which tracks if it was set to "none" explicitly.
type NoneDate struct {
isExplicitNone bool
Date time.Time
}
// IsImplicitZero indicates if the date has defaulted to empty becaues the argument was empty.
func (e NoneDate) IsImplicitZero() bool {
return e.Date.IsZero() && !e.isExplicitNone
}
func parseNoneDate(date string) (result NoneDate, err error) {
if date == "none" {
result.isExplicitNone = true
}
result.Date, err = parseHumanDate(date)
return result, err
}
// parseJSON parses command-line flags which accept JSON string.
// It can be passed to clingy.Transform to create a clingy.Option.
func parseJSON(jsonString string) (map[string]string, error) {

2
go.mod
View File

@ -1,6 +1,6 @@
module storj.io/storj
go 1.17
go 1.18
require (
github.com/alessio/shellescape v1.2.2

6
go.sum
View File

@ -62,7 +62,6 @@ github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7
github.com/calebcase/tmpfile v1.0.3 h1:BZrOWZ79gJqQ3XbAQlihYZf/YCV0H4KPIdM5K5oMpJo=
github.com/calebcase/tmpfile v1.0.3/go.mod h1:UAUc01aHeC+pudPagY/lWvt2qS9ZO5Zzof6/tIUzqeI=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@ -184,7 +183,6 @@ github.com/google/pprof v0.0.0-20211108044417-e9b028704de0/go.mod h1:KgnwoLYCZ8I
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go v2.0.0+incompatible h1:j0GKcs05QVmm7yesiZq2+9cxHkNK9YM6zKx4D2qucQU=
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
@ -233,7 +231,6 @@ github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
@ -256,7 +253,6 @@ github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5W
github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A=
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
@ -296,7 +292,6 @@ github.com/jtolds/monkit-hw/v2 v2.0.0-20191108235325-141a0da276b3 h1:dITCBge70U9
github.com/jtolds/monkit-hw/v2 v2.0.0-20191108235325-141a0da276b3/go.mod h1:eo5po8nCwRcvZIIR8eGi7PKthzXuunpXzUmXzxCBfBc=
github.com/jtolds/tracetagger/v2 v2.0.0-rc5 h1:SriMFVtftPsQmG+0xaABotz9HnoKoo1QM/oggqfpGh8=
github.com/jtolds/tracetagger/v2 v2.0.0-rc5/go.mod h1:61Fh+XhbBONy+RsqkA+xTtmaFbEVL040m9FAF/hTrjQ=
github.com/jtolio/eventkit v0.0.0-20221004135224-074cf276595b/go.mod h1:q7yMR8BavTz/gBNtIT/uF487LMgcuEpNGKISLAjNQes=
github.com/jtolio/eventkit v0.0.0-20221007130042-690145affff8 h1:Jm6SYrxKgQMKHUVLhV9qc2Y7PuSQRKUxxk/NSrtaxdQ=
github.com/jtolio/eventkit v0.0.0-20221007130042-690145affff8/go.mod h1:q7yMR8BavTz/gBNtIT/uF487LMgcuEpNGKISLAjNQes=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
@ -956,7 +951,6 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
storj.io/common v0.0.0-20220719163320-cd2ef8e1b9b0/go.mod h1:mCYV6Ud5+cdbuaxdPD5Zht/HYaIn0sffnnws9ErkrMQ=
storj.io/common v0.0.0-20220915180246-7826900e2b06/go.mod h1:+gF7jbVvpjVIVHhK+EJFhfPbudX395lnPq/dKkj/Qys=
storj.io/common v0.0.0-20221123115229-fed3e6651b63 h1:OuleF/3FvZe3Nnu6NdwVr+FvCXjfD4iNNdgfI2kcs3k=
storj.io/common v0.0.0-20221123115229-fed3e6651b63/go.mod h1:+gF7jbVvpjVIVHhK+EJFhfPbudX395lnPq/dKkj/Qys=
storj.io/drpc v0.0.32 h1:5p5ZwsK/VOgapaCu+oxaPVwO6UwIs+iwdMiD50+R4PI=