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
#73)

* Adding SQLite db to authz, updating persitence directory structure, starting to wire up crud for entities
  • Loading branch information
mattschoch authored Jan 30, 2024
1 parent c16acdc commit e93bc30
Show file tree
Hide file tree
Showing 24 changed files with 494 additions and 84 deletions.
35 changes: 3 additions & 32 deletions .github/workflows/authz_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,6 @@ jobs:
name: Build and test

runs-on: ubuntu-latest

services:
postgres:
image: postgres:14
ports:
- '5432:5432'
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis
ports:
- '6379:6379'
env:
REDIS_PORT: 6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Checkout
uses: actions/checkout@master
Expand All @@ -62,16 +36,12 @@ jobs:
make authz/format/check
make authz/lint/check
# TODO: Finish once the authz-node has a database.
- name: Setup database and Prisma types
shell: bash
run: |
make authz/copy-default-env
# make orchestration/test/db/setup
# Generate the orchestration Prisma client types to prevent the type
# tests to fail.
# make orchestration/db/generate-types
make authz/test/db/setup
make authz/db/generate-types
- name: Test types
shell: bash
Expand All @@ -86,6 +56,7 @@ jobs:
- name: Test integration
shell: bash
run: |
make authz/test/db/setup
make authz/test/integration
# - name: Test E2E
Expand Down
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"
52 changes: 47 additions & 5 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 All @@ -11,6 +12,8 @@ authz/start/dev:
authz/setup:
make authz/copy-default-env
make authz/rego/compile
make authz/db/setup
make authz/test/db/setup

authz/copy-default-env:
cp ${AUTHZ_PROJECT_DIR}/.env.default ${AUTHZ_PROJECT_DIR}/.env
Expand All @@ -19,32 +22,71 @@ authz/copy-default-env:
# == Code format ==

authz/format:
npx nx format:write --projects ${AUTHZ_PROJECT_NAME}
npx nx format:write --projects ${AUTHZ_PROJECT_NAME}

authz/lint:
npx nx lint ${AUTHZ_PROJECT_NAME} -- --fix

authz/format/check:
npx nx format:check --projects ${AUTHZ_PROJECT_NAME}
npx nx format:check --projects ${AUTHZ_PROJECT_NAME}

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

@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:
make authz/db/generate-types
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
1 change: 1 addition & 0 deletions apps/authz/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const config: Config = {
displayName: 'authz',
moduleFileExtensions: ['ts', 'js', 'html'],
preset: '../../jest.preset.js',
setupFiles: ['<rootDir>/jest.setup.ts'],
testEnvironment: 'node',
transform: {
'^.+\\.[tj]s$': [
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,56 @@
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, ConfigService } 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('should have test db url', () => {
// Just leaving this to ensure the jest.setup.ts file is configured correctly to set the env variable.
const configService = module.get<ConfigService>(ConfigService)
expect(configService.get('database.url', { infer: true })).toBe('file:./engine-core-test.sqlite')
})

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 e93bc30

Please sign in to comment.