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

feat(backend): add clientId to OP resources #535

Merged
merged 35 commits into from
Sep 20, 2022
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
04f9d1b
feat(backend): add clientId to incoming payments
sabineschaller Aug 24, 2022
f8d7db4
fix(backend): route tests
sabineschaller Aug 25, 2022
46db826
fix(backend): build
sabineschaller Aug 25, 2022
7ceda6e
Merge branch 'main' into s2-add-clientId-to-resources
sabineschaller Aug 25, 2022
c70f4dd
fix(backend): quote and outgoing payment tests
sabineschaller Aug 25, 2022
0902c53
Merge branch 'main' into s2-add-clientId-to-resources
sabineschaller Sep 7, 2022
036798f
fix(backend): incoming payment list route tests
sabineschaller Sep 7, 2022
b9e1bad
feat(backend): add grant model that holds clientId
sabineschaller Sep 9, 2022
d0e3fd7
fix(backend): outgoing payment resolver
sabineschaller Sep 9, 2022
fe913c5
Merge branch 'main' into s2-add-clientId-to-resources
sabineschaller Sep 9, 2022
fdc73a0
style(backend): remove unnecessary styling
sabineschaller Sep 9, 2022
04f436c
feat(backend): make grant optional on resource creation
sabineschaller Sep 12, 2022
eb75faf
feat(backend): use withgraphjoined on pagination
sabineschaller Sep 12, 2022
6f2bda9
fix(backend): lock grant
sabineschaller Sep 12, 2022
612115a
fix(backend): grant access can hold multiple items again
sabineschaller Sep 12, 2022
1d4e5a2
fix(backend): incoming payment glitches
sabineschaller Sep 13, 2022
3776626
feat(backend): add clientId to outgoing payments
sabineschaller Sep 13, 2022
06bb2ae
test(backend): add additional payments before running pagination tests
sabineschaller Sep 14, 2022
3a5bc3f
fix(backend): remove unnecessary query parameter from setup function
sabineschaller Sep 14, 2022
5661171
refactor(backend): setup function uses options instead of arg list
sabineschaller Sep 14, 2022
abd1360
feat(backend): `xAll` actions include `x` action
sabineschaller Sep 14, 2022
2cc0a05
refactor(backend): outgoing payment creation only takes Grant, not gr…
sabineschaller Sep 15, 2022
9fc9a71
feat(backend): return error if client id doesn't match known grant
sabineschaller Sep 15, 2022
72ae24d
refactor(backend): `referenceGrant` --> `grantRef`
sabineschaller Sep 15, 2022
50defc3
refactor(backend): rename model `Grant` --> `GrantReference`, move to…
sabineschaller Sep 15, 2022
3173839
feat(backend): add GrantReferenceService
sabineschaller Sep 15, 2022
1c55cc7
refactor(backend): add Brandon's suggestions
sabineschaller Sep 16, 2022
12a4c15
feat(backend): allow to pass transaction to GrantReferenceService met…
sabineschaller Sep 16, 2022
ed8dcca
test(backend): add GrantReference tests
sabineschaller Sep 16, 2022
10551e9
Merge branch 'main' into s2-add-clientId-to-resources
sabineschaller Sep 16, 2022
ee46354
fix(backend): throw 500 if clientId mismatch
sabineschaller Sep 19, 2022
15a315e
fix(backend): make transaction required in lock
sabineschaller Sep 19, 2022
0e34b6c
test(backend): fix create and get GrantReference tests
sabineschaller Sep 19, 2022
010a7e3
feat(backend): get and create GrantReference within the same transaction
sabineschaller Sep 19, 2022
8de25af
feat(backend): remove GrantReferenceService dependencies
sabineschaller Sep 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
exports.up = function (knex) {
return knex.schema.createTable('grants', function (table) {
table.string('id').notNullable().primary()
table.string('clientId').notNullable()
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ exports.up = function (knex) {
table.string('externalRef').nullable()
table.uuid('connectionId').notNullable()

table.string('grantId').nullable()
table.foreign('grantId').references('grants.id')

table.uuid('assetId').notNullable()
table.foreign('assetId').references('assets.id')
table.timestamp('processAt').nullable()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ exports.up = function (knex) {
table.string('description').nullable()
table.string('externalRef').nullable()

table.string('grantId').nullable().index()
table.string('grantId').nullable()
table.foreign('grantId').references('grants.id')

// Open payments payment pointer corresponding to wallet account
// from which to request funds for payment
Expand Down
4 changes: 3 additions & 1 deletion packages/backend/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,10 @@ export class App {
} = {
[AccessAction.Create]: 'create',
[AccessAction.Read]: 'get',
[AccessAction.ReadAll]: 'get',
[AccessAction.Complete]: 'complete',
[AccessAction.List]: 'list'
[AccessAction.List]: 'list',
[AccessAction.ListAll]: 'list'
}

for (const path in openApi.paths) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@ import { randomAsset } from '../../tests/asset'
import { createIncomingPayment } from '../../tests/incomingPayment'
import { createPaymentPointer } from '../../tests/paymentPointer'
import { truncateTables } from '../../tests/tableManager'
import { v4 as uuid } from 'uuid'
import { Grant } from '../../open_payments/auth/grantModel'

describe('Incoming Payment Resolver', (): void => {
let deps: IocContract<AppServices>
let appContainer: TestContainer
let knex: Knex
let paymentPointerId: string
let grant: Grant

const asset = randomAsset()

Expand All @@ -34,13 +37,18 @@ describe('Incoming Payment Resolver', (): void => {
describe('Payment pointer incoming payments', (): void => {
beforeEach(async (): Promise<void> => {
paymentPointerId = (await createPaymentPointer(deps, { asset })).id
grant = await Grant.query().insert({
id: uuid(),
clientId: uuid()
})
})

getPageTests({
getClient: () => appContainer.apolloClient,
createModel: () =>
createIncomingPayment(deps, {
paymentPointerId,
grantId: grant.id,
incomingAmount: {
value: BigInt(123),
assetCode: asset.code,
Expand Down
3 changes: 3 additions & 0 deletions packages/backend/src/open_payments/auth/grant.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { Grant, AccessType, AccessAction, getInterval } from './grant'
import { Interval } from 'luxon'
import { v4 as uuid } from 'uuid'

describe('Grant', (): void => {
describe('includesAccess', (): void => {
let grant: Grant
const type = AccessType.IncomingPayment
const action = AccessAction.Create
const clientId = uuid()

describe.each`
identifier | description
Expand All @@ -16,6 +18,7 @@ describe('Grant', (): void => {
grant = new Grant({
active: true,
grant: 'PRY5NM33OM4TB8N6BW7',
clientId,
access: [
{
type: AccessType.OutgoingPayment,
Expand Down
8 changes: 7 additions & 1 deletion packages/backend/src/open_payments/auth/grant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ export enum AccessType {
export enum AccessAction {
Create = 'create',
Read = 'read',
ReadAll = 'read-all',
Complete = 'complete',
List = 'list'
List = 'list',
ListAll = 'list-all'
}

export interface AccessLimits {
Expand Down Expand Up @@ -53,6 +55,7 @@ export type GrantAccessJSON = Omit<GrantAccess, 'limits'> & {
export interface GrantOptions {
active: boolean
grant: string
clientId: string
access?: GrantAccess[]
}

Expand All @@ -66,11 +69,13 @@ export class Grant {
this.active = options.active
this.grant = options.grant
this.access = options.access || []
this.clientId = options.clientId
}

public readonly active: boolean
public readonly grant: string
public readonly access: GrantAccess[]
public readonly clientId: string

public includesAccess({
sabineschaller marked this conversation as resolved.
Show resolved Hide resolved
type,
Expand All @@ -93,6 +98,7 @@ export class Grant {
return {
active: this.active,
grant: this.grant,
clientId: this.clientId,
access: this.access?.map((access) => {
return {
...access,
Expand Down
11 changes: 11 additions & 0 deletions packages/backend/src/open_payments/auth/grantModel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Model } from 'objection'
import { DbErrors } from 'objection-db-errors'

export class Grant extends DbErrors(Model) {
sabineschaller marked this conversation as resolved.
Show resolved Hide resolved
public static get modelPaths(): string[] {
return [__dirname]
}
public static readonly tableName = 'grants'
public id!: string
public clientId!: string
}
3 changes: 3 additions & 0 deletions packages/backend/src/open_payments/auth/middleware.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import assert from 'assert'
import nock, { Definition } from 'nock'
import { URL } from 'url'
import { v4 as uuid } from 'uuid'

import { createAuthMiddleware } from './middleware'
import { Grant, GrantJSON, AccessType, AccessAction } from './grant'
Expand Down Expand Up @@ -131,6 +132,7 @@ describe('Auth Middleware', (): void => {
test('returns 403 for unauthorized request', async (): Promise<void> => {
const scope = mockAuthServer({
active: true,
clientId: uuid(),
grant: 'PRY5NM33OM4TB8N6BW7',
access: [
{
Expand All @@ -156,6 +158,7 @@ describe('Auth Middleware', (): void => {
async ({ limitAccount }): Promise<void> => {
const grant = new Grant({
active: true,
clientId: uuid(),
sabineschaller marked this conversation as resolved.
Show resolved Hide resolved
grant: 'PRY5NM33OM4TB8N6BW7',
access: [
{
Expand Down
8 changes: 8 additions & 0 deletions packages/backend/src/open_payments/auth/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AccessType, AccessAction } from './grant'
import { AppContext } from '../../app'
import { Grant } from './grantModel'

export function createAuthMiddleware({
type,
Expand Down Expand Up @@ -33,6 +34,13 @@ export function createAuthMiddleware({
) {
ctx.throw(403, 'Insufficient Grant')
}
await Grant.query()
.insert({
id: grant.grant,
clientId: grant.clientId
})
.onConflict('id')
.ignore()
sabineschaller marked this conversation as resolved.
Show resolved Hide resolved
ctx.grant = grant
await next()
} catch (err) {
Expand Down
1 change: 1 addition & 0 deletions packages/backend/src/open_payments/auth/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ async function introspectToken(
)
const options: GrantOptions = {
active: data.active,
clientId: data.clientId,
grant: data.grant
}
if (data.access) {
Expand Down
7 changes: 7 additions & 0 deletions packages/backend/src/open_payments/connection/routes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ import { IncomingPayment } from '../payment/incoming/model'
import { createIncomingPayment } from '../../tests/incomingPayment'
import { createPaymentPointer } from '../../tests/paymentPointer'
import base64url from 'base64url'
import { Grant } from '../auth/grantModel'

describe('Connection Routes', (): void => {
let deps: IocContract<AppServices>
let appContainer: TestContainer
let knex: Knex
let config: IAppConfig
let connectionRoutes: ConnectionRoutes
let grant: Grant

beforeAll(async (): Promise<void> => {
config = Config
Expand All @@ -44,8 +46,13 @@ describe('Connection Routes', (): void => {
config = await deps.use('config')

paymentPointer = await createPaymentPointer(deps, { asset })
grant = await Grant.query().insert({
id: uuid(),
clientId: uuid()
})
incomingPayment = await createIncomingPayment(deps, {
paymentPointerId: paymentPointer.id,
grantId: grant.id,
description: 'hello world',
expiresAt: new Date(Date.now() + 30_000),
incomingAmount: {
Expand Down
12 changes: 12 additions & 0 deletions packages/backend/src/open_payments/payment/incoming/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { LiquidityAccount, OnCreditOptions } from '../../../accounting/service'
import { ConnectorAccount } from '../../../connector/core/rafiki'
import { BaseModel } from '../../../shared/baseModel'
import { WebhookEvent } from '../../../webhook/model'
import { Grant } from '../../auth/grantModel'

export enum IncomingPaymentEventType {
IncomingPaymentExpired = 'incoming_payment.expired',
Expand Down Expand Up @@ -79,6 +80,14 @@ export class IncomingPayment
from: 'incomingPayments.paymentPointerId',
to: 'paymentPointers.id'
}
},
grant: {
relation: Model.HasOneRelation,
modelClass: Grant,
join: {
from: 'incomingPayments.grantId',
to: 'grants.id'
}
}
}

Expand All @@ -91,6 +100,9 @@ export class IncomingPayment
public externalRef?: string
public connectionId!: string

public grantId?: string
public grant?: Grant

public processAt!: Date | null

public readonly assetId!: string
Expand Down
Loading