-
Notifications
You must be signed in to change notification settings - Fork 0
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
[ID-1117] Add fence_account_key and distributed_lock tables to db #174
Conversation
This will be used for Bond providers
264ec0a
to
73d5f55
Compare
73d5f55
to
6c996e9
Compare
import org.immutables.value.Value; | ||
|
||
@Value.Immutable | ||
public interface DistributedLock { |
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.
public interface DistributedLock { | |
public interface DistributedLock extends WithDistributedLock { |
This, along with ./gradlew assemble
, will let you uncomment the builder.
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 had to add extends WithDistributedLock
first and then run ./gradlew assemble
in order to generate that interface
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.
Hmm I'm still getting an error about the builder being final 🤔
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 ./gradlew assemble
fixed the error!
import org.immutables.value.Value; | ||
|
||
@Value.Immutable | ||
public interface FenceAccountKey { |
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.
Same as above
8ee3aac
to
5b99a70
Compare
author: sehsan | ||
changes: | ||
- createTable: | ||
tableName: fence_account_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.
I think we also need a foreign key to the user's linked_account
record, so that we can retrieve a user's fence account key by user_id and provider (similar to ga4gh_passport). Does that make sense @tlangs?
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.
That does make sense!
4a0cebf
to
d1bef70
Compare
Needed to locate a key based on the user and provider name.
d1bef70
to
09c2d11
Compare
Also fix encoding/decoding key JSON
|
||
@Value.Immutable | ||
public interface FenceAccountKey extends WithFenceAccountKey { | ||
Optional<Integer> getId(); |
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.
FYI this is optional because when we pass a FenceAccountKey
object to insertFenceAccountKey
, it won't have an id at that point.
references: linked_account(id) | ||
foreignKeyName: fk_linked_account_id | ||
- column: | ||
name: key_json |
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.
nit: maybe this should be called key_json_base64?
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.
Looks good overall, just some small changes requested
service/src/main/java/bio/terra/externalcreds/dataAccess/DistributedLockDAO.java
Show resolved
Hide resolved
public Optional<DistributedLock> getDistributedLock(String lockName, String userId) { | ||
var namedParameters = | ||
new MapSqlParameterSource().addValue("lockName", lockName).addValue("userId", userId); | ||
var query = "SELECT * FROM distributed_lock WHERE lock_name = :lockName AND user_id = :userId"; |
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 nitpicky but I think it is best to name each column in a DAO query.
var namedParameters = | ||
new MapSqlParameterSource("userId", userId).addValue("providerName", providerName); | ||
var query = | ||
"SELECT p.* FROM fence_account_key p" |
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.
Same comment as above I would name each column instead of using *.
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.
also nitpicky but I would use something more descriptive than 'p' for fence_account_key's alias, maybe 'fence' or 'fak'. Just to make the query easier to read.
var generatedKeyHolder = new GeneratedKeyHolder(); | ||
jdbcTemplate.update(query, namedParameters, generatedKeyHolder); | ||
|
||
return fenceAccountKey.withId(Objects.requireNonNull(generatedKeyHolder.getKey()).intValue()); |
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 love that you can get the id back from the insert query, there are limitations on this in scala libs that I have used.
@@ -29,3 +29,6 @@ databaseChangeLog: | |||
- include: | |||
file: changesets/20220412_add_last_encrypt_timestamp_to_ssh_key_pair_table.yaml | |||
relativeToChangelogFile: true | |||
- include: |
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.
There's a merge conflict here. Make sure this changeset comes after the just-merged changeset.
new FenceAccountKey.Builder() | ||
.id(rs.getInt("id")) | ||
.linkedAccountId(rs.getInt("linked_account_id")) | ||
.keyJson(base64Decode(rs.getString("key_json"))) |
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, I looked at the Bond code, and its storing the keys as raw json instead of base64. I thought it about it a little bit more, and storing the keys as JSON or JSONB might actually be better, since we could then query into the keys to find info. That may be useful for debugging or analysis.
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.
Apologies for the whiplash...
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 worries! That's a good point about search-ability
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.
im confused i thought it was storing the keys as b64?
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.
Bond stores them as plain text.
primaryKey: true | ||
nullable: false | ||
- column: | ||
name: linked_account_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.
Oh! Can we make this cascade on delete? That way, if someone deletes their linked account, the key will automatically get deleted too.
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 assumed that was the default behavior 😅 I'll double check!
…ials-manager into se/ID-1117-add-fence-account-key-table
} | ||
|
||
@WithSpan | ||
public FenceAccountKey insertFenceAccountKey(FenceAccountKey fenceAccountKey) { |
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.
Can we rename this upsertFenceAccountKey
and do the same ON CONFLICT
logic?
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 just when there is a conflict on the id
and linked_account_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.
Ah I had to add a unique constraint on the linked_account_id
in order to use is as the conflict criteria
|
||
String getUserId(); | ||
|
||
Timestamp getExpiresAt(); |
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 should probably use java.time.Instant
here instead of the SQL Timestamp.
|
Jira: https://broadworkbench.atlassian.net/browse/ID-1117
What:
fence_account_key
table that is equivalent to the one in Bond and adistributed_lock
table to store the lock information about fence tokens (or eventually passports).Why:
The Identiteam is moving Bond's functionality to authenticate with fence account providers into ECM, so ECM needs to store information about fence account keys.
How:
Testing:
I ran the ECM server locally and confirmed that the new table was created.