Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into nft-transfer-criteria
Browse files Browse the repository at this point in the history
  • Loading branch information
samteb committed Jan 23, 2024
2 parents 925abaf + ee40039 commit 85e2f80
Show file tree
Hide file tree
Showing 43 changed files with 917 additions and 562 deletions.
25 changes: 0 additions & 25 deletions .github/workflows/authz_opa_ci.yml

This file was deleted.

9 changes: 5 additions & 4 deletions apps/authz/src/app/app.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ export class AppController {
@Post('/evaluation')
async evaluate(@Body() body: EvaluationRequestDto) {
this.logger.log({
message: 'Received evaluation'
message: 'Received evaluation',
body
})

// Map the DTO into the TS type because it's nicer to deal with.
Expand All @@ -44,11 +45,11 @@ export class AppController {

@Post('/evaluation-demo')
async evaluateDemo() {
const fakeRequest = await generateInboundRequest()
this.logger.log({
message: 'Received evaluation'
message: 'Received evaluation',
body: fakeRequest
})

const fakeRequest = await generateInboundRequest()
const result = await this.appService.runEvaluation(fakeRequest)
this.logger.log({
message: 'Evaluation Result',
Expand Down
12 changes: 10 additions & 2 deletions apps/authz/src/app/app.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,14 @@ export class AppService {
address,
signature: signature as Hex
})
if (!valid) throw new Error('Invalid Signature')
if (!valid) {
console.log('### invalid', {
pubKey,
sig
})

throw new Error('Invalid Signature')
}
}
// TODO: verify other alg types

Expand Down Expand Up @@ -134,8 +141,9 @@ export class AppService {
async runEvaluation({ request, authentication, approvals, transfers }: AuthorizationRequestPayload) {
// Pre-Process
// verify the signatures of the Principal and any Approvals
const decoder = new Decoder()
const decoder = new Decoder({})
const verificationMessage = hashRequest(request)

const principalCredential = await this.#verifySignature(authentication, verificationMessage)
if (!principalCredential) throw new Error(`Could not find principal`)
const populatedApprovals = await this.#populateApprovals(approvals, verificationMessage)
Expand Down
20 changes: 12 additions & 8 deletions apps/authz/src/app/opa/opa.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,25 @@ export class OpaService {

constructor(private persistenceRepository: PersistenceRepository) {}

async onApplicationBootstrap() {
async onApplicationBootstrap(): Promise<void> {
this.logger.log('OPA Service boot')
this.opaEngine = await this.getOpaEngine()
}

async evaluate(input: RegoInput): Promise<OpaResult[]> {
this.opaEngine = await this.getOpaEngine()
const evalResult: { result: OpaResult }[] = await this.opaEngine.evaluate(input, 'main/evaluate')
return evalResult.map(({ result }) => result)
}

private async getOpaEngine(): Promise<OpaEngine> {
const policyWasmPath = OPA_WASM_PATH
const policyWasm = readFileSync(policyWasmPath)
const opaEngine = await loadPolicy(policyWasm, undefined, {
'time.now_ns': () => new Date().getTime() * 1000000
})
const data = await this.persistenceRepository.getEntityData()
opaEngine.setData(data)
this.opaEngine = opaEngine
}

async evaluate(input: RegoInput): Promise<OpaResult[]> {
if (!this.opaEngine) throw new Error('OPA Engine not initialized')
const evalResult: { result: OpaResult }[] = await this.opaEngine.evaluate(input, 'main/evaluate')
return evalResult.map(({ result }) => result)
return opaEngine
}
}
2 changes: 2 additions & 0 deletions apps/authz/src/opa/rego/policies/e2e.rego
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ permit[{"policyId": "test-permit-policy-1"}] := reason {
checkTransferTokenType({"transferNative"})
checkTransferTokenAddress({"eip155:137/slip44/966"})
checkTransferTokenOperation({"operator": "gte", "value": "1000000000000000000"})

approvalsRequired = [{
"approvalCount": 2,
"countPrincipal": false,
"approvalEntityType": "Narval::User",
"entityIds": ["aa@narval.xyz", "bb@narval.xyz"],
}]

approvals := getApprovalsResult(approvalsRequired)
reason := {
"type": "permit",
Expand Down
9 changes: 9 additions & 0 deletions apps/orchestration/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,19 @@
"webpackConfig": "apps/orchestration/webpack.config.js"
},
"configurations": {
"repl": {
"main": "apps/orchestration/src/repl.ts"
},
"development": {},
"production": {}
}
},
"repl": {
"executor": "@nx/node:node",
"options": {
"buildTarget": "orchestration:build:repl"
}
},
"serve": {
"executor": "@nx/js:node",
"defaultConfiguration": "development",
Expand Down
111 changes: 57 additions & 54 deletions apps/orchestration/src/policy-engine/__test__/e2e/facade.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { PolicyEngineModule } from '@app/orchestration/policy-engine/policy-engi
import { PersistenceModule } from '@app/orchestration/shared/module/persistence/persistence.module'
import { TestPrismaService } from '@app/orchestration/shared/module/persistence/service/test-prisma.service'
import { QueueModule } from '@app/orchestration/shared/module/queue/queue.module'
import { TransactionType, hashRequest } from '@narval/authz-shared'
import { getQueueToken } from '@nestjs/bull'
import { HttpStatus, INestApplication } from '@nestjs/common'
import { ConfigModule } from '@nestjs/config'
Expand Down Expand Up @@ -96,58 +95,60 @@ describe('Policy Engine Cluster Facade', () => {

describe('POST /evaluations', () => {
it('evaluates a sign message authorization request', async () => {
const signMessageRequest = {
message: 'Sign me, please'
}
const payload = {
action: SupportedAction.SIGN_MESSAGE,
request: signMessageRequest,
hash: hashRequest(signMessageRequest),
authentication,
approvals
approvals,
request: {
action: SupportedAction.SIGN_MESSAGE,
nonce: '99',
resourceId: '5cfb8614-ddeb-4764-bf85-8d323f26d3b3',
message: 'Sign me, please'
}
}

const { status, body } = await request(app.getHttpServer())
.post(EVALUATIONS_ENDPOINT)
.set(REQUEST_HEADER_ORG_ID, org.id)
.send(payload)

expect(status).toEqual(HttpStatus.OK)
expect(body).toMatchObject({
approvals,
id: expect.any(String),
createdAt: expect.any(String),
updatedAt: expect.any(String),
status: AuthorizationRequestStatus.CREATED,
idempotencyKey: null,
action: payload.action,
hash: payload.hash,
request: payload.request,
createdAt: expect.any(String),
updatedAt: expect.any(String)
evaluations: []
})
expect(status).toEqual(HttpStatus.OK)
})

it('evaluates a sign transaction authorization request', async () => {
const signTransactionRequest = {
chainId: 1,
data: '0x',
from: '0xaaa8ee1cbaa1856f4550c6fc24abb16c5c9b2a43',
gas: '5000',
nonce: 0,
to: '0xbbb7be636c3ad8cf9d08ba8bdba4abd2ef29bd23',
type: TransactionType.EIP1559,
value: '0x',
accessList: [
{
address: '0xccc1472fce4ec74a1e3f9653776acfc790cd0743',
storageKeys: [stringToHex('storage-key-one'), stringToHex('storage-key-two')]
}
]
}
const payload = {
action: SupportedAction.SIGN_TRANSACTION,
hash: hashRequest(signTransactionRequest),
request: signTransactionRequest,
authentication,
approvals
approvals,
request: {
action: SupportedAction.SIGN_TRANSACTION,
nonce: '99',
resourceId: '68dc69bd-87d2-49d9-a5de-f482507b25c2',
transactionRequest: {
chainId: 1,
data: '0x',
from: '0xaaa8ee1cbaa1856f4550c6fc24abb16c5c9b2a43',
gas: '5000',
nonce: 0,
to: '0xbbb7be636c3ad8cf9d08ba8bdba4abd2ef29bd23',
type: '2',
value: '0x',
accessList: [
{
address: '0xccc1472fce4ec74a1e3f9653776acfc790cd0743',
storageKeys: [stringToHex('storage-key-one'), stringToHex('storage-key-two')]
}
]
}
}
}

const { status, body } = await request(app.getHttpServer())
Expand All @@ -156,27 +157,29 @@ describe('Policy Engine Cluster Facade', () => {
.send(payload)

expect(body).toMatchObject({
approvals,
id: expect.any(String),
createdAt: expect.any(String),
updatedAt: expect.any(String),
status: AuthorizationRequestStatus.CREATED,
idempotencyKey: null,
action: payload.action,
hash: payload.hash,
request: payload.request,
createdAt: expect.any(String),
updatedAt: expect.any(String)
evaluations: []
})
expect(status).toEqual(HttpStatus.OK)
})

it('evaluates a partial sign transaction authorization request', async () => {
const signTransactionRequest = {
from: '0xaaa8ee1cbaa1856f4550c6fc24abb16c5c9b2a43',
chainId: 1
}
const payload = {
action: SupportedAction.SIGN_TRANSACTION,
hash: hashRequest(signTransactionRequest),
request: signTransactionRequest,
request: {
action: SupportedAction.SIGN_TRANSACTION,
nonce: '99',
resourceId: '68dc69bd-87d2-49d9-a5de-f482507b25c2',
transactionRequest: {
from: '0xaaa8ee1cbaa1856f4550c6fc24abb16c5c9b2a43',
chainId: 1
}
},
authentication,
approvals
}
Expand All @@ -187,31 +190,31 @@ describe('Policy Engine Cluster Facade', () => {
.send(payload)

expect(body).toMatchObject({
approvals,
id: expect.any(String),
createdAt: expect.any(String),
updatedAt: expect.any(String),
status: AuthorizationRequestStatus.CREATED,
idempotencyKey: null,
action: payload.action,
hash: payload.hash,
request: payload.request,
createdAt: expect.any(String),
updatedAt: expect.any(String)
evaluations: []
})
expect(status).toEqual(HttpStatus.OK)
})
})

describe('GET /evaluations/:id', () => {
const signMessageRequest = {
message: 'Testing sign message request'
}
const authzRequest: AuthorizationRequest = {
authentication,
id: '986ae19d-c30c-40c6-b873-1fb6c49011de',
orgId: org.id,
status: AuthorizationRequestStatus.PERMITTED,
action: SupportedAction.SIGN_MESSAGE,
request: signMessageRequest,
hash: hashRequest(signMessageRequest),
request: {
action: SupportedAction.SIGN_MESSAGE,
nonce: '99',
resourceId: '5cfb8614-ddeb-4764-bf85-8d323f26d3b3',
message: 'Testing sign message request'
},
idempotencyKey: '8dcbb7ad-82a2-4eca-b2f0-b1415c1d4a17',
evaluations: [],
approvals: [],
Expand Down
Loading

0 comments on commit 85e2f80

Please sign in to comment.