Skip to content

Commit

Permalink
Merge branch 'main' into bc/ww-performance-jason
Browse files Browse the repository at this point in the history
  • Loading branch information
koekiebox committed Aug 28, 2024
2 parents a280ffc + 49310c7 commit 02bbc52
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 30 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/add_to_docs_board.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Add to documentation project board
on:
issues:
types:
- labeled

jobs:
add-to-project:
if: github.event.label.name == 'docs'
name: Add issue to project
runs-on: ubuntu-22.04
steps:
- uses: actions/[email protected]
with:
project-url: https://github.com/orgs/interledger/projects/24/
github-token: ${{ secrets.ADD_TO_PROJECT_TOKEN }}
102 changes: 102 additions & 0 deletions packages/auth/src/access/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,66 @@ describe('Access utilities', (): void => {
).toBe(true)
})

test('Can compare an access item on a grant and an access item from a request with different action ordering', async (): Promise<void> => {
const grantAccessItemSuperAction = await Access.query(trx).insertAndFetch({
grantId: grant.id,
type: AccessType.OutgoingPayment,
actions: [AccessAction.Create, AccessAction.ReadAll, AccessAction.List],
identifier,
limits: {
receiver,
debitAmount: {
value: '400',
assetCode: 'USD',
assetScale: 2
}
}
})

const requestAccessItem: AccessItem = {
type: 'outgoing-payment',
actions: ['read', 'list', 'create'],
identifier,
limits: {
receiver,
debitAmount: {
value: '400',
assetCode: 'USD',
assetScale: 2
}
}
}

expect(
compareRequestAndGrantAccessItems(
requestAccessItem,
toOpenPaymentsAccess(grantAccessItemSuperAction)
)
).toBe(true)
})

test('Can compare an access item on a grant without an identifier with a request with an identifier', async (): Promise<void> => {
const grantAccessItemSuperAction = await Access.query(trx).insertAndFetch({
grantId: grant.id,
type: AccessType.IncomingPayment,
actions: [AccessAction.ReadAll],
identifier: undefined
})

const requestAccessItem: AccessItem = {
type: 'incoming-payment',
actions: [AccessAction.ReadAll],
identifier
}

expect(
compareRequestAndGrantAccessItems(
requestAccessItem,
toOpenPaymentsAccess(grantAccessItemSuperAction)
)
).toBe(true)
})

test('access comparison fails if grant action items are insufficient', async (): Promise<void> => {
const identifier = `https://example.com/${v4()}`
const receiver =
Expand Down Expand Up @@ -206,4 +266,46 @@ describe('Access utilities', (): void => {
)
).toBe(false)
})

test('access comparison fails if identifier mismatch', async (): Promise<void> => {
const grantAccessItemSuperAction = await Access.query(trx).insertAndFetch({
grantId: grant.id,
type: AccessType.IncomingPayment,
actions: [AccessAction.ReadAll],
identifier
})

const requestAccessItem: AccessItem = {
type: 'incoming-payment',
actions: [AccessAction.ReadAll],
identifier: `https://example.com/${v4()}`
}

expect(
compareRequestAndGrantAccessItems(
requestAccessItem,
toOpenPaymentsAccess(grantAccessItemSuperAction)
)
).toBe(false)
})

test('access comparison fails if type mismatch', async (): Promise<void> => {
const grantAccessItemSuperAction = await Access.query(trx).insertAndFetch({
grantId: grant.id,
type: AccessType.Quote,
actions: [AccessAction.Read]
})

const requestAccessItem: AccessItem = {
type: 'incoming-payment',
actions: [AccessAction.Read]
}

expect(
compareRequestAndGrantAccessItems(
requestAccessItem,
toOpenPaymentsAccess(grantAccessItemSuperAction)
)
).toBe(false)
})
})
21 changes: 15 additions & 6 deletions packages/auth/src/access/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,22 @@ export function compareRequestAndGrantAccessItems(
return false
}

// Validate remaining keys
if (restOfRequestAccessItem.type !== restOfGrantAccessItem.type) {
return false
}

// Validate identifier, if present on the grant
const grantAccessIdentifier = (
restOfGrantAccessItem as OutgoingPaymentOrIncomingPaymentAccess
).identifier

const requestAccessIdentifier = (
restOfRequestAccessItem as OutgoingPaymentOrIncomingPaymentAccess
).identifier

if (
restOfRequestAccessItem.type !== restOfGrantAccessItem.type ||
(restOfRequestAccessItem as OutgoingPaymentOrIncomingPaymentAccess)
.identifier !==
(restOfGrantAccessItem as OutgoingPaymentOrIncomingPaymentAccess)
.identifier
grantAccessIdentifier &&
requestAccessIdentifier !== grantAccessIdentifier
) {
return false
}
Expand Down
33 changes: 17 additions & 16 deletions packages/backend/src/open_payments/auth/middleware.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ type IntrospectionCallObject = {
access: {
type: AccessType
actions: AccessAction[]
identifier?: string
identifier: string
}[]
}

Expand Down Expand Up @@ -193,7 +193,8 @@ describe('Auth Middleware', (): void => {
access: [
{
type: type,
actions: [action]
actions: [action],
identifier: ctx.walletAddressUrl
}
]
})
Expand All @@ -217,7 +218,8 @@ describe('Auth Middleware', (): void => {
access: [
{
type: type,
actions: [action]
actions: [action],
identifier: ctx.walletAddressUrl
}
]
})
Expand Down Expand Up @@ -286,15 +288,12 @@ describe('Auth Middleware', (): void => {
access: [
{
type,
actions: [action]
actions: [action],
identifier: ctx.walletAddressUrl
}
]
}

if (type === AccessType.OutgoingPayment) {
expectedCallObject.access[0].identifier = ctx.walletAddressUrl
}

expect(introspectSpy).toHaveBeenCalledWith(expectedCallObject)
expect(next).not.toHaveBeenCalled()
}
Expand All @@ -313,7 +312,8 @@ describe('Auth Middleware', (): void => {
access: [
{
type,
actions: [action]
actions: [action],
identifier: ctx.walletAddressUrl
}
]
})
Expand Down Expand Up @@ -349,7 +349,8 @@ describe('Auth Middleware', (): void => {
access: [
{
type,
actions: [subAction]
actions: [subAction],
identifier: ctx.walletAddressUrl
}
]
})
Expand All @@ -376,7 +377,8 @@ describe('Auth Middleware', (): void => {
access: [
{
type,
actions: [superAction]
actions: [superAction],
identifier: ctx.walletAddressUrl
}
]
})
Expand Down Expand Up @@ -436,13 +438,11 @@ describe('Auth Middleware', (): void => {
access: [
{
type,
actions: [action]
actions: [action],
identifier: ctx.walletAddressUrl
}
]
}
if (type === AccessType.OutgoingPayment) {
expectedCallObject.access[0].identifier = ctx.walletAddressUrl
}

expect(introspectSpy).toHaveBeenCalledWith(expectedCallObject)
expect(next).toHaveBeenCalled()
Expand Down Expand Up @@ -473,7 +473,8 @@ describe('Auth Middleware', (): void => {
access: [
{
type,
actions: [action]
actions: [action],
identifier: ctx.walletAddressUrl
}
]
})
Expand Down
14 changes: 6 additions & 8 deletions packages/backend/src/open_payments/auth/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export interface Grant {
export interface Access {
type: string
actions: AccessAction[]
identifier?: string
identifier: string
}

function contextToRequestLike(ctx: HttpSigContext): RequestLike {
Expand Down Expand Up @@ -95,13 +95,11 @@ export function createTokenIntrospectionMiddleware({
tokenInfo = await tokenIntrospectionClient.introspect({
access_token: token,
access: [
requestType === AccessType.OutgoingPayment
? toOpenPaymentsAccess(
requestType,
requestAction,
ctx.walletAddressUrl
)
: toOpenPaymentsAccess(requestType, requestAction)
toOpenPaymentsAccess(
requestType,
requestAction,
ctx.walletAddressUrl
)
]
})
} catch (err) {
Expand Down

0 comments on commit 02bbc52

Please sign in to comment.