-
Notifications
You must be signed in to change notification settings - Fork 90
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(backend): add getOrCreate
method for grantReferenceService
#787
Conversation
method getOrCreate was added for `grantReferenceService`
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 solid, just a few small comments. Would test this by
await grantReferenceService.create({ | ||
id: grant.grant, | ||
clientId: uuid() | ||
}) |
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 don't think you need this create
@@ -79,4 +80,60 @@ describe('Grant Reference Service', (): void => { | |||
) | |||
}) | |||
}) | |||
|
|||
describe('Get or Create Grant Reference', (): void => { | |||
test('cannot fetch a non-existing grant reference', async (): Promise<void> => { |
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.
test('cannot fetch a non-existing grant reference', async (): Promise<void> => { | |
test('returns undefined for a non-existing grant reference', async (): Promise<void> => { |
expect(retrievedRef).toEqual(existingRef) | ||
}) | ||
|
||
test('create a grant reference', async (): Promise<void> => { |
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.
test('create a grant reference', async (): Promise<void> => { | |
test('creates a grant reference', async (): Promise<void> => { |
nitpick, generally naming the test as though it's doing the action: the test creates, returns, throws etc
@@ -263,6 +263,42 @@ describe('Auth Middleware', (): void => { | |||
scope.done() | |||
}) | |||
|
|||
test('if getOrCreateGrantReference throws, return 500', async (): Promise<void> => { |
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.
test('if getOrCreateGrantReference throws, return 500', async (): Promise<void> => { | |
test('returns 500 if getOrCreateGrantReference throws', async (): Promise<void> => { |
the same as comments below
} catch (e) { | ||
const errInfo = e && typeof e === 'object' && e.stack ? e.stack : e | ||
logger.debug(errInfo) |
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.
} catch (e) { | |
const errInfo = e && typeof e === 'object' && e.stack ? e.stack : e | |
logger.debug(errInfo) | |
} catch (error) { | |
const errorMessage = error?.message ?? 'Failed to get or create grant reference' | |
logger.error({ error }, errorMessage) |
would prefer something like this, without needing to check the type etc
{ id, clientId: uuid() }, | ||
AccessAction.List | ||
) | ||
).rejects.toThrowError('does not match internal reference clientId') |
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 thought we would have needed a RegEx here, but it seems to work?
).rejects.toThrowError('does not match internal reference clientId') | |
).rejects.toThrowError(/does not match internal reference clientId/) |
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 was thinking the same, but based on Jest docs, RegEx and strings are equivalent in this case.
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 great!
In order to properly test this we need to:
- Create or seed an initial grant in the auth server
- Make a request (e.g. get incoming payment) with the token related to the created grant, and verify that the grant reference was created in backend's database during token introspection
- Make another request (e.g. duplicate get incoming payment) with the token related to the created grant, and this time verify the grant reference was fetched correctly from backend's database.
Easiest way would be to test this with the Create Incoming Payment request in the Postman P2P payment transfer example collection, after my PR is merged in. Once that is merged, I can walk you through the flow
} | ||
|
||
return grantRef | ||
} else if (action === AccessAction.Create) { |
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 this check should be moved out to the caller.
await grantReferenceService.getOrCreate( | ||
{ id: grant.grant, clientId: grant.clientId }, | ||
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.
await grantReferenceService.getOrCreate( | |
{ id: grant.grant, clientId: grant.clientId }, | |
action | |
) | |
if (action === AccessAction.Create) { | |
await grantReferenceService.getOrCreate({ | |
id: grant.grant, | |
clientId: grant.clientId | |
}) | |
} else { | |
await grantReferenceService.get(grant.grant) | |
} |
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.
By moving the action check to the caller, the clientId
check
rafiki/packages/backend/src/open_payments/grantReference/service.ts
Lines 58 to 63 in c6eaaa9
if (grantRef) { | |
if (grantRef.clientId !== options.clientId) { | |
throw new Error( | |
`clientID ${options.clientId} for grant ${options.id} does not match internal reference clientId ${grantRef.clientId}.` | |
) | |
} |
will probably need to be moved to the
getGrantRerefence
methodrafiki/packages/backend/src/open_payments/grantReference/service.ts
Lines 27 to 29 in c6eaaa9
async function getGrantReference(grantId: string, trx: Transaction) { | |
return await GrantReference.query(trx).findById(grantId) | |
} |
and will have to take both arguments (
id
and clientId
)
async function getGrantReference(
options: CreateGrantReferenceOptions,
trx: Transaction
) {
// ...
}
otherwise there will be no validation for the clientId
when calling grantReferenceService.get
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'm leaning towards not passing clientId
to grantReferenceService.get
(even though this is currently the only place calling it).
What if we moved the clientId
check out here?
await grantReferenceService.getOrCreate( | |
{ id: grant.grant, clientId: grant.clientId }, | |
action | |
) | |
if (action === AccessAction.Create) { | |
await grantReferenceService.getOrCreate({ | |
id: grant.grant, | |
clientId: grant.clientId | |
}) | |
} else { | |
const grantRef = await grantReferenceService.get(grant.grant) | |
if (grantRef && grantRef.clientId !== grant.clientId) { | |
throw new Error( | |
`clientID ${grant.clientId} for grant ${grant.id} does not match internal reference clientId ${grantRef.clientId}.` | |
} | |
} | |
} |
🤔 that looks a lot like how it was before...
Is there an argument for not actually using getOrCreate
?
It looks like the AccessAction.Create
check was added after this issue was opened:
This will completely remove |
Closing this PR since #800 got merged in. |
Changes proposed in this pull request
getOrCreate
method forgrantReferenceService
Context
grantReferenceService.getOrCreate
#703Checklist
fixes #number