-
Notifications
You must be signed in to change notification settings - Fork 200
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
feat(sql/auth): base authentication storage implementation #1095
Conversation
Codecov Report
@@ Coverage Diff @@
## authentication #1095 +/- ##
==================================================
+ Coverage 80.52% 80.94% +0.42%
==================================================
Files 26 29 +3
Lines 1884 2125 +241
==================================================
+ Hits 1517 1720 +203
- Misses 287 318 +31
- Partials 80 87 +7
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
b9d2341
to
5ebcb8a
Compare
8fe812d
to
ade17a7
Compare
5ebcb8a
to
c62399b
Compare
builder: builder, | ||
now: timestamppb.Now, | ||
generateID: func() string { | ||
return uuid.Must(uuid.NewV4()).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.
are we worried about (highly unlikely) potential for panic here?
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 think the only case uuid
panics occur is when your system runs out of entropy (I could be mistaken).
I believe the advice in this situation is to panic for reals. So, I wouldn't be too worried about not capturing this.
internal/storage/sql/auth/store.go
Outdated
&authentication.Id, | ||
&hashedToken, | ||
ptr(method(authentication.Method)), | ||
&jsonField[map[string]string]{authentication.Metadata}, |
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.
for variant.attachment
I think we just represented it as a string
and compacted it before saving, ie:
flipt/internal/storage/sql/common/flag.go
Line 265 in 28ed354
if attachment != nil { |
is there a reason to do it this way instead?
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.
The jsonField
container just marshals which type it contains to and from a string to make that operations a one-liner. I could definitely use json.Compact
in the Driver
implementation too. But this is the same thing.
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.
cool, i wonder if we should move to be consistent everywhere
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.
Let me see if I can drop Attachment in, and it just works...
I just moved JSONField
to the sql
package, so it is reachable now.
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.
Ahh I see, Attachment moves around as a string in the protobuf itself. My mistake.
Whereas, Metadata is actually a map<string, string>
in protobuf:
flipt/rpc/flipt/auth/auth.proto
Line 45 in 35eec68
map<string, string> metadata = 6; |
Here, JSONField
allows for the one-lining of (un)marshalling to and from arbitrary Go types like this to string for persistence.
Whereas, Attachment
using json.Compact
to first unmarshal a string which assumed to contain JSON and back into a compact JSON form.
Seems these are two relatively different concepts, and I see why they're both different.
With Attachments, the data's schema is controlled by the end user.
We don't need to know the structure of the JSON document.
It is compacted to keep storage cost minimized.
With Metadata, the data's schema is strictly map<string, string>
.
We use that structure internally to allow each auth method to populate the map in their respective ways (e.g. static tokens store their name and description under controlled keys).
JSON is merely a convenient serialization form to stash the structured object in a TEXT
field.
) | ||
|
||
// AdaptError converts specific known-driver errors into wrapped storage errors. | ||
func (d Driver) AdaptError(err error) error { |
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.
oh i like this. is the idea to replace the specific sql/x
subpackages that override the common
implementation with this for existing flag/segment/etc CRUD operations?
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.
Yeah, 💯 I think we might be able to do away with having to add adaptors for each driver.
I can port the rest of Flipt to it in a later PR too if we like how it works.
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.
heyooooo 🚀
} | ||
} | ||
|
||
func FuzzHashClientToken(f *testing.F) { |
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.
ooo love the fuzz
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.
Honestly, first time I have given it a proper go. It is really neat.
I ran a long fuzz of this function. Roughly ~7M calls.
It is mostly just base64 and sha256, so not testing much.
However, it was nice to get some confidence it was producing base64 encoded non-zero length tokens.
fix(sql/auth): use crypto/rand.Reader in place of math/rand.New fix(sql/auth): capture test parameters in loop-body variables chore(migrations): drop index before dropping authentications table fix(import): run down migrations on --drop fix(migrations/sqlite3): syntax error in uniqueness constraint on temp table in down test(sql/auth): fuzz hashClientToken chore(sql/auth): more fuzzing seeds fix(sql/auth): map driver constraint errors to internal error representation chore(sql/auth): remove underscore from Fuzz test name chore(storage/sql): remove dead code refactor(migrations): change authentications method from string to integer refactor(storage/sql): move common field utilities into sql package chore(storage/sql): use keyed field in struct literals
Fixes: FLI-36
Initial implementation for storing
Authentication
instances into the backing relational DBs.This PR:
internal/storage/sql/auth
.*auth.Store
implementation specifically forAuthentication
associated state.CreateAuthentication
.GetAuthenticationByClientToken
.SHA256
.Authentication
instances.