-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor and document eacl
package
#526
Conversation
5641760
to
b22e4f6
Compare
List of changes: * SYSTEM role is deprecated. * encoding/decoding/copying methods are provided by the `Table` type only. * `ToV2` method and `NewFromV2` function are replaced by `WriteToV2` and `ReadFromV2` respectively. `ReadFromV2` now check protocol requirements and returns an error. * `Operation` enum is replaced with the `acl.Op` one * Keys to the object filters are exported now. * Protocol string encoding methods of the enums are purged since NeoFS API protocol doesn't define this format (these values are transmitted binary only). * `Validator` type is purged because it is only related to the system nodes' implementation and makes no sense in the SDK. * constructors for the structured types are provided to simplify understanding of required/optional fields. * Documentation is extended/improved. * Code examples are added. Signed-off-by: Leonard Lyubich <leonard@morphbits.io>
Previously, test code was needed to randomize `neofscrypto.Signer` via randomizer or manually in order to get random `neofscrypto.PublicKey`. This could increase misunderstanding code (especially examples) that user needs to have signer instance to work with public keys. Add `RandomPublicKey` function returning random public key instances. Signed-off-by: Leonard Lyubich <leonard@morphbits.io>
b22e4f6
to
c2f3f5e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my opinion, there are too many panics in code. Part of them can be replaced with regular errors.
// See also [NewFilter]. | ||
func NewFilterObjectAttribute(key string, matcher Matcher, value string) Filter { | ||
if strings.HasPrefix(key, acl.ObjectFilterPrefix) { | ||
panic(fmt.Sprintf("reserved prefix in '%s'", key)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'%s'
-> %q
?
// resulting Table. All records MUST be correctly constructed. | ||
// | ||
// See also [NewForContainer]. | ||
func New(records []Record) Table { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this function make sense? Anyway, the table must be linked to the container. NewForContainer
is a perfect candidate for a single constructor because it covers this requirement. And rename NewForContainer to New
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree. not sure a table without a container could be used, so LimitByContainer
is useless also to me
func (t Table) Container() (cid.ID, bool) { | ||
if t.cid == nil { | ||
var zero cid.ID | ||
return zero, false | ||
} | ||
|
||
// SetVersion sets version of eACL format. | ||
func (t *Table) SetVersion(version version.Version) { | ||
t.version = version | ||
return *t.cid, true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
t.cid
is a pointer here, we may use this fact to remove the second bool returning value. And check the result, it is nil or not. Pros and cons?
// The argument MUST be non-empty. | ||
func (t *Target) readFromV2(ms []v2acl.Target) error { | ||
if len(ms) == 0 { | ||
panic("empty slice of targets") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Panic? may be just an error like here? We already have error
returning value
func (u u64Stringer) EncodeToString() string { | ||
return strconv.FormatUint(uint64(u), 10) | ||
// returns message about docs violation or zero if everything is OK. | ||
func (f Filter) validate() string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest to replace string
with error
// returns message about docs violation or zero if everything is OK. | ||
func (t Target) validate() string { | ||
if len(t.roles)+len(t.keys) == 0 { | ||
return "neither roles nor keys are presented" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest here and below in the function to replace the string with an error
for i := range t.roles { | ||
switch t.roles[i] { | ||
default: | ||
panic(fmt.Sprintf("invalid role #%d: forbidden value %v of enum %T", i, t.roles[i], t.roles[i])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And here we may return the error instead of panic
return false | ||
} | ||
if withKeys { | ||
ms[len(ms)-1].SetKeys(t.keys) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now, we have all the checks to be sure this row works appropriately. But one may change some of these checks, and in one moment ms
can't be zero length => we have runtime panic.
Could we add a simple check ms > 0
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- A single patch changing whole
eacl
is bad. It shouldn't be this way, it should be a series of patches. - Many of the conceptual fixes are nice (validators/system/multi role)
- But renamings are better be avoided at this stage. We're at RC, there has to be a reason to change something.
- New* constructors are nice and look fine in related PRs (less code bloat).
// | ||
// Note that type conversion from- and to numerical types is not recommended: | ||
// use enum names only. | ||
type Action v2acl.Action |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So it doesn't need to tov2/fromv2, it's v2 already?
MatchStringNotEqual | ||
_ Action = iota | ||
ActionAllow // allows something | ||
ActionDeny // denies something |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But these are new enums that are not synchronized with v2 in any way.
// payload's homomorphic checksum of the objects. | ||
// | ||
// See also [NewFilter]. | ||
func NewFilterObjectPayloadHomomorphicChecksum(matcher Matcher, cs [tz.Size]byte) Filter { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suppose I have a MatchIntegerLessThan
matcher, will it work here (and in other cases)?
// implementation only and is not expected to be directly used by applications. | ||
// | ||
// See also [Table.ReadFromV2]. | ||
func (t Table) WriteToV2(m *acl.Table) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On one hand, it's unification. On the other, we still have ToV2()
for other structures. So I'm not sure it's an improvement at all.
} | ||
|
||
// SetCID sets identifier of the container that should use given access control rules. | ||
func (t *Table) SetCID(cid cid.ID) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't add a lot of value at RC11 stage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw, i do not agree that Container
is somehow better than CID
. less explicit, more things to keep in mind, struct context is required for code reading, and so on
} | ||
|
||
// EqualTables compares Table with each other. | ||
func EqualTables(t1, t2 Table) bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No replacement for it?
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func baseBenchmarkTableBinaryComparison(b *testing.B, factor int) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We no longer care?
// eACL provides ability to determine target subjects of access rules, in | ||
// particular, distribute/restrict access on an exclusive basis. | ||
func ExampleTable_exclusiveRights() { | ||
friendPubKey := randomPublicKey() | ||
friendPubKey := test.RandomPublicKey() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NACK. It's an example. It must not import any test packages, it should be something people can copy/paste. Sure, randomPublicKey()
will need to be replaced, but at least one can see what's in there, unlike when it's an imported package.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Linter died.
@@ -1,116 +0,0 @@ | |||
package eacltest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why drop?
@@ -1,50 +1,44 @@ | |||
package eacltest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is literally not the eacl
package that is mentioned as being changed in the commit and no words about this change in the body. a separate commit?
// Key MUST be non-empty. | ||
// | ||
// See also other helper constructors. | ||
func NewFilter(typ HeaderType, key string, matcher Matcher, value string) Filter { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why so generic name for a header-typed filter?
value: value, | ||
} | ||
if msg := f.validate(); msg != "" { | ||
panic(msg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
panic? i think we are getting rid of them in sdk (and least in constructors)
// Return value MUST NOT be mutated, make a copy first if needed. | ||
// | ||
// See also [Record.IsForKey]. | ||
func (r Record) TargetBinaryKeys() [][]byte { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it ok to have bytes here but neofscrypto.PublicKey
in the func a few lines below?
cid *cid.ID | ||
records []Record | ||
} | ||
|
||
// New constructs eACL from the given list of access rules. Being applied as | ||
// part of access control to the NeoFS resources, the rules are matched | ||
// according to the first hit: if a rule with a certain index is applicable, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we want this behavior? i would say that looking for every applicable rule and choosing the most restrictive looks better
// resulting Table. All records MUST be correctly constructed. | ||
// | ||
// See also [NewForContainer]. | ||
func New(records []Record) Table { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree. not sure a table without a container could be used, so LimitByContainer
is useless also to me
} | ||
|
||
// SetCID sets identifier of the container that should use given access control rules. | ||
func (t *Table) SetCID(cid cid.ID) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw, i do not agree that Container
is somehow better than CID
. less explicit, more things to keep in mind, struct context is required for code reading, and so on
return t.keys | ||
} | ||
// See also other helper constructors. | ||
func NewTarget(roles []Role, publicKeys []neofscrypto.PublicKey) Target { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
again, why some version of a generic struct is more default than others? why keys are more default New
than roles?
// | ||
// If no matching table entry is found or some filters are missing, | ||
// ActionAllow is returned and the second return value is false. | ||
func (v *Validator) CalculateAction(unit *ValidationUnit) (Action, bool) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we are so get used to moving code from one repo to another and many other types of useless work. i am not a conservative but can we at least explain why we moving smth in and out again?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feedback must be addressed.
overlapped by #605 |
No description provided.