Skip to content
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

chore(backend): remove wallet address middleware #2708

Closed
wants to merge 15 commits into from

Conversation

mkurapov
Copy link
Contributor

@mkurapov mkurapov commented May 7, 2024

Changes proposed in this pull request

To finalize the standardization of Open Payments route errors in backend, this PR removes walletAddressMiddleware.
The benefits:

  • We now handle all possible errors properly in the openPaymentsServerErrorMiddleware (i.e. we don't use ctx.throw at all in other places)
  • walletAddressUrl is determined as an inline-middleware per route, meaning the complex logic walletAddressMiddleware can be removed
  • We don't need to fetch the walletAddress until each route needs it. This is nice for a few reasons:
    • we can control whether a route will poll (or not) the wallet address creation at the ASE (i.e. we can choose whether a route will call walletAddressService.getOrPollByUrl or just getByUrl)
    • we can eliminate a request to get the wallet address before other checks are ran (like token introspection, http signature middleware, Open Api validation, etc)

Context

Completion of backend changes for #1905

Checklist

  • Related issues linked using fixes #number
  • Tests added/updated
  • Documentation added
  • Make sure that all checks pass
  • Bruno collection updated

mkurapov added 7 commits May 6, 2024 17:45
…-middleware

# Conflicts:
#	packages/backend/src/open_payments/wallet_address/model.test.ts
#	packages/backend/src/payment-method/ilp/spsp/middleware.test.ts
#	packages/backend/src/payment-method/ilp/spsp/middleware.ts
…-middleware

# Conflicts:
#	packages/backend/src/open_payments/wallet_address/model.test.ts
#	packages/backend/src/payment-method/ilp/spsp/middleware.test.ts
#	packages/backend/src/payment-method/ilp/spsp/middleware.ts
@github-actions github-actions bot added type: tests Testing related pkg: backend Changes in the backend package. type: source Changes business logic labels May 7, 2024
@@ -181,12 +188,13 @@ async function getWalletAddress(

async function getOrPollByUrl(
deps: ServiceDependencies,
url: string
url: string,
options: GetOrPollByUrlOptions = { mustBeActive: true }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we primarily use this method when resolving the wallet address in Open Payments routes, we should expect it to always be active

@mkurapov mkurapov changed the title 1905/mk/remove wallet address middleware chore(backend): remove wallet address middleware May 7, 2024
@mkurapov mkurapov mentioned this pull request May 7, 2024
5 tasks
Comment on lines +558 to +572
const incomingPaymentService = await ctx.container.use(
'incomingPaymentService'
)
const incomingPayment = await incomingPaymentService.get({
id: ctx.params.id
})

if (!incomingPayment?.walletAddress) {
throw new OpenPaymentsServerRouteError(401, 'Unauthorized', {
description: 'Failed to get wallet address from incoming payment',
id: ctx.params.id
})
}

ctx.walletAddressUrl = incomingPayment.walletAddress.url
Copy link
Contributor Author

@mkurapov mkurapov May 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not get a specific wallet address in the following OP requests (either in the query params or request body):

GET /incoming-payments/:id
GET /outgoing-payments/:id
GET /quotes/:id
POST /incoming-payments/:id/complete

We need the walletAddressUrl in order to pass down into createTokenIntrospectionMiddleware, as the middleware needs to determine whether the possible identifier on the grant matches up to the resource for the particular wallet address.

This is why we still need to get the resource first, before we can proceed with handling the request. The status quo is returning a 401/Unauthorized response code (to not give away information about whether resource exists or not). Maybe this should be 400, but I don't have a strong opinion here.

Copy link
Contributor Author

@mkurapov mkurapov May 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to add tests for this, but I would need to do some work about splitting apart these in-line middlewares into separate functions. I can handle it in a separate PR where I do a little more refactoring, since I don't want to balloon this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the following:

GET /incoming-payments/:id
GET /outgoing-payments/:id
GET /quotes/:id

we could just store these on ctx.state and not have to call the <resource>Routes.get/fetch the resource from the DB again, but a) could be done in separate PR, or b) not worth doing at all for the consistency of having the routes as they are

@@ -100,9 +102,18 @@ async function createOutgoingPayment(
deps: ServiceDependencies,
ctx: CreateContext<CreateBody>
): Promise<void> {
const walletAddress = await deps.walletAddressService.getOrPollByUrl(
Copy link
Contributor Author

@mkurapov mkurapov May 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still want to poll here? Typically, the polling probably necessary only on the receiving side, i.e. incoming payment creation only. (since that is the most likely place where we would need to allow the ASE to make a request to their backend to create the corresponding wallet addresses)

Comment on lines -44 to -48
const walletAddress = await walletAddressService.getByUrl(
const walletAddress = await walletAddressService.getOrPollByUrl(
ctx.walletAddressUrl
)

if (!walletAddress?.isActive) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

already handled in getOrPollByUrl by default. However, this comment still stands: https://github.com/interledger/rafiki/pull/2708/files#r1592829255

@mkurapov mkurapov linked an issue May 8, 2024 that may be closed by this pull request
Base automatically changed from 1905/mk/spsp-errors to main May 10, 2024 17:12
# Conflicts:
#	packages/backend/src/open_payments/wallet_address/model.test.ts
#	packages/backend/src/payment-method/ilp/spsp/middleware.test.ts
#	packages/backend/src/payment-method/ilp/spsp/middleware.ts
Copy link

netlify bot commented May 10, 2024

Deploy Preview for brilliant-pasca-3e80ec canceled.

Name Link
🔨 Latest commit 2082015
🔍 Latest deploy log https://app.netlify.com/sites/brilliant-pasca-3e80ec/deploys/663e689bc9a532000837568f

@@ -107,27 +107,4 @@ describe('SPSP Middleware', (): void => {
expect(spspGetRouteSpy).not.toHaveBeenCalled()
}
})

test('throws error if inactive wallet address', async () => {
Copy link
Contributor Author

@mkurapov mkurapov May 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -20,14 +20,12 @@ export function parsePaginationQueryParameters({
type GetPageInfoArgs<T extends BaseModel> = {
getPage: (pagination: Pagination, sortOrder?: SortOrder) => Promise<T[]>
page: T[]
walletAddress?: string
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was unused

@mkurapov mkurapov marked this pull request as ready for review May 10, 2024 18:36
@mkurapov mkurapov marked this pull request as draft May 10, 2024 19:22
@mkurapov mkurapov closed this May 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg: backend Changes in the backend package. type: source Changes business logic type: tests Testing related
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant