Skip to content

Commit

Permalink
Adding SQLite db to authz, updating persitence directory structure, s…
Browse files Browse the repository at this point in the history
…tarting to wire up crud for entities
  • Loading branch information
mattschoch committed Jan 29, 2024
1 parent ca16216 commit 8fe45dc
Show file tree
Hide file tree
Showing 22 changed files with 480 additions and 50 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,7 @@ Thumbs.db
.env.production
.env.test

/rego-build
/rego-build

*.sqlite
*.sqlite-journal
4 changes: 4 additions & 0 deletions apps/authz/.env.default
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
NODE_ENV=development

PORT=3010

ENGINE_DATABASE_URL="file:./engine-core.sqlite"
3 changes: 3 additions & 0 deletions apps/authz/.env.test.default
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# IMPORTANT: The variables defined here will override other variables.
# See `./apps/authz/jest.setup.ts`.
NODE_ENV=test

ENGINE_DATABASE_URL="file:./engine-core-test.sqlite"
46 changes: 43 additions & 3 deletions apps/authz/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
AUTHZ_PROJECT_NAME := authz
AUTHZ_PROJECT_DIR := ./apps/authz
AUTHZ_DATABASE_SCHEMA := ${AUTHZ_PROJECT_DIR}/src/shared/module/persistence/schema/schema.prisma

# === Start ===

Expand Down Expand Up @@ -30,21 +31,60 @@ authz/format/check:
authz/lint/check:
npx nx lint ${AUTHZ_PROJECT_NAME}

# === Database ===

authz/db/generate-types:
npx prisma generate \
--schema ${AUTHZ_DATABASE_SCHEMA}

authz/db/migrate:
npx dotenv -e ${AUTHZ_PROJECT_DIR}/.env -- \
prisma migrate dev \
--schema ${AUTHZ_DATABASE_SCHEMA}

authz/db/setup:
@echo ""
@echo "${TERM_GREEN}🛠️ Setting up Authz development database${TERM_NO_COLOR}"
@echo ""
npx dotenv -e ${AUTHZ_PROJECT_DIR}/.env -- \
prisma migrate reset \
--schema ${AUTHZ_DATABASE_SCHEMA} \
--force
make authz/db/seed

@echo ""
@echo "${TERM_GREEN}🛠️ Setting up Authz test database${TERM_NO_COLOR}"
@echo ""
make authz/test/db/setup

authz/db/create-migration:
npx dotenv -e ${AUTHZ_PROJECT_DIR}/.env -- \
prisma migrate dev \
--schema ${AUTHZ_DATABASE_SCHEMA} \
--name ${NAME}

# === Testing ===

authz/test/db/setup:
npx dotenv -e ${AUTHZ_PROJECT_DIR}/.env.test --override -- \
prisma migrate reset \
--schema ${AUTHZ_DATABASE_SCHEMA} \
--skip-seed \
--force

authz/test/type:
npx tsc \
--project ${AUTHZ_PROJECT_DIR}/tsconfig.app.json \
--noEmit

authz/test/unit:
npx nx test:unit ${AUTHZ_PROJECT_NAME}
npx nx test:unit ${AUTHZ_PROJECT_NAME} -- ${ARGS}

authz/test/integration:
npx nx test:integration ${AUTHZ_PROJECT_NAME}
npx nx test:integration ${AUTHZ_PROJECT_NAME} -- ${ARGS}

authz/test/e2e:
npx nx test:e2e ${AUTHZ_PROJECT_NAME}
npx nx test:e2e ${AUTHZ_PROJECT_NAME} -- ${ARGS}

# === Open Policy Agent & Rego ===

Expand Down
18 changes: 16 additions & 2 deletions apps/authz/src/app/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
import { z } from 'zod'

export enum Env {
DEVELOPMENT = 'development',
TEST = 'test',
PRODUCTION = 'production'
}

const ConfigSchema = z.object({
port: z.coerce.number()
env: z.nativeEnum(Env),
port: z.coerce.number(),
database: z.object({
url: z.string().startsWith('file:')
})
})

export type Config = z.infer<typeof ConfigSchema>

export const load = (): Config => {
const result = ConfigSchema.safeParse({
port: process.env.PORT
env: process.env.NODE_ENV,
port: process.env.PORT,
database: {
url: process.env.ENGINE_DATABASE_URL
}
})

if (result.success) {
Expand Down
2 changes: 1 addition & 1 deletion apps/authz/src/app/app.controller.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { EvaluationRequestDto } from '@app/authz/app/evaluation-request.dto'
import { generateInboundRequest } from '@app/authz/shared/module/persistence/mock_data'
import { generateInboundRequest } from '@app/authz/app/persistence/repository/mock_data'
import { AuthorizationRequest } from '@narval/authz-shared'
import { Body, Controller, Get, Logger, Post } from '@nestjs/common'
import { AppService } from './app.service'
Expand Down
5 changes: 4 additions & 1 deletion apps/authz/src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { OrganizationRepository } from '@app/authz/app/persistence/repository/organization.repository'
import { PersistenceModule } from '@app/authz/shared/module/persistence/persistence.module'
import { Logger, Module, OnApplicationBootstrap, ValidationPipe } from '@nestjs/common'
import { ConfigModule } from '@nestjs/config'
Expand All @@ -10,13 +11,15 @@ import { OpaService } from './opa/opa.service'
@Module({
imports: [
ConfigModule.forRoot({
load: [load]
load: [load],
isGlobal: true
}),
PersistenceModule
],
controllers: [AppController],
providers: [
AppService,
OrganizationRepository,
OpaService,
{
provide: APP_PIPE,
Expand Down
6 changes: 3 additions & 3 deletions apps/authz/src/app/app.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PersistenceRepository } from '@app/authz/shared/module/persistence/persistence.repository'
import { OrganizationRepository } from '@app/authz/app/persistence/repository/organization.repository'
import { AuthCredential, OpaResult, RegoInput } from '@app/authz/shared/types/domain.type'
import {
Action,
Expand Down Expand Up @@ -61,11 +61,11 @@ export const finalizeDecision = (response: OpaResult[]) => {

@Injectable()
export class AppService {
constructor(private persistenceRepository: PersistenceRepository, private opaService: OpaService) {}
constructor(private OrganizationRepository: OrganizationRepository, private opaService: OpaService) {}

async #verifySignature(requestSignature: Signature, verificationMessage: string): Promise<AuthCredential> {
const { pubKey, alg, sig } = requestSignature
const credential = await this.persistenceRepository.getCredentialForPubKey(pubKey)
const credential = await this.OrganizationRepository.getCredentialForPubKey(pubKey)
if (alg === Alg.ES256K) {
// TODO: ensure sig & pubkey begins with 0x
const signature = sig.startsWith('0x') ? sig : `0x${sig}`
Expand Down
6 changes: 3 additions & 3 deletions apps/authz/src/app/opa/opa.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PersistenceRepository } from '@app/authz/shared/module/persistence/persistence.repository'
import { OrganizationRepository } from '@app/authz/app/persistence/repository/organization.repository'
import { OpaResult, RegoInput } from '@app/authz/shared/types/rego'
import { Injectable, Logger } from '@nestjs/common'
import { loadPolicy } from '@open-policy-agent/opa-wasm'
Expand All @@ -15,7 +15,7 @@ export class OpaService {
private logger = new Logger(OpaService.name)
private opaEngine: OpaEngine | undefined

constructor(private persistenceRepository: PersistenceRepository) {}
constructor(private organizationRepository: OrganizationRepository) {}

async onApplicationBootstrap(): Promise<void> {
this.logger.log('OPA Service boot')
Expand All @@ -34,7 +34,7 @@ export class OpaService {
const opaEngine = await loadPolicy(policyWasm, undefined, {
'time.now_ns': () => new Date().getTime() * 1000000
})
const data = await this.persistenceRepository.getEntityData()
const data = await this.organizationRepository.getEntityData()
opaEngine.setData(data)
return opaEngine
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { load } from '@app/authz/app/app.config'
import { OrganizationRepository } from '@app/authz/app/persistence/repository/organization.repository'
import { PersistenceModule } from '@app/authz/shared/module/persistence/persistence.module'
import { TestPrismaService } from '@app/authz/shared/module/persistence/service/test-prisma.service'
import { Alg } from '@narval/authz-shared'
import { ConfigModule } from '@nestjs/config'
import { Test, TestingModule } from '@nestjs/testing'

describe(OrganizationRepository.name, () => {
let module: TestingModule
let repository: OrganizationRepository
let testPrismaService: TestPrismaService

beforeEach(async () => {
module = await Test.createTestingModule({
imports: [
ConfigModule.forRoot({
load: [load],
isGlobal: true
}),
PersistenceModule
],
providers: [OrganizationRepository]
}).compile()

testPrismaService = module.get<TestPrismaService>(TestPrismaService)
repository = module.get<OrganizationRepository>(OrganizationRepository)
})

afterEach(async () => {
await testPrismaService.truncateAll()
await module.close()
})

describe('create', () => {
it('creates a new organization', async () => {
await repository.createOrganization('test-org-uid', 'test-user-uid', {
alg: Alg.ES256K,
pubKey: 'test-public-key'
})

const org = await testPrismaService.getClient().organization.findFirst({
where: {
uid: 'test-org-uid'
}
})
expect(org).toEqual({ uid: 'test-org-uid' })
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ export const MATT: User = {
}

export const MATT_CREDENTIAL_1: AuthCredential = {
id: 'credentialId1',
alg: Alg.ES256K,
userId: MATT.uid,
pubKey: '0xd75D626a116D4a1959fE3bB938B2e7c116A05890'
Expand All @@ -60,7 +59,6 @@ export const AAUser: User = {

export const AAUser_Credential_1: AuthCredential = {
userId: AAUser.uid,
id: 'credentialId2',
alg: Alg.ES256K,
pubKey: '0x501D5c2Ce1EF208aadf9131a98BAa593258CfA06'
}
Expand All @@ -72,7 +70,6 @@ export const BBUser: User = {

export const BBUser_Credential_1: AuthCredential = {
userId: BBUser.uid,
id: 'credentialId3',
alg: Alg.ES256K,
pubKey: '0xab88c8785D0C00082dE75D801Fcb1d5066a6311e'
}
Expand Down
Loading

0 comments on commit 8fe45dc

Please sign in to comment.