Skip to content

Commit

Permalink
Merge pull request #1 from 0xShield3/feat/validation-json-interfaces
Browse files Browse the repository at this point in the history
Feat/validation json interfaces
  • Loading branch information
ipatka authored Oct 29, 2023
2 parents 5cd2297 + 92ed0d4 commit d1584eb
Show file tree
Hide file tree
Showing 8 changed files with 714 additions and 120 deletions.
153 changes: 94 additions & 59 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,95 +1,130 @@
import node_pre_gyp from '@mapbox/node-pre-gyp';
const { find } = node_pre_gyp;
import { resolve, join, dirname } from 'path';
import { fileURLToPath } from 'url';
import node_pre_gyp from '@mapbox/node-pre-gyp'
const { find } = node_pre_gyp
import { resolve, join, dirname } from 'path'
import { fileURLToPath } from 'url'
import Ajv from 'ajv'

import PolicyEngineResponse from './schemas/IPolicyEnginePolicyResponse.json'

// Native modules are not currently supported with ES module imports.
// https://nodejs.org/api/esm.html#esm_no_native_module_loading
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
import { createRequire } from 'module'
const require = createRequire(import.meta.url)

// __dirname is not defined in ES module scope, so get it manaully.
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

const {
hello,
authorize,
policy_to_json,
validate_policy,
// the file will be run in ./dist, so popd.
} = require(find(resolve(join(__dirname, process.env.dev ? '' : '..', './package.json'))));

} = require(find(resolve(join(__dirname, process.env.dev ? '' : '..', './package.json'))))

export interface IBanyan {}

export interface IPolicyEngineInvokePayload {
principal: string
action: string
resource: string
policy: string
entities: string
context: string
schema: string | undefined
principal: string
action: string
resource: string
policy: string
entities: string
context: string
schema: string | undefined
}

export interface IValidatePolicyPayload {
policy: string
additional_schema_fragments: string[]
}

export enum TriggeredPolicyAction {
BLOCK = 'Block',
MFA = 'MFA',
NOTIFY = 'Notify',
ALLOW = 'Allow'
MFA = 'MFA',
NOTIFY = 'Notify',
}

export enum PolicyDecision {
ALLOW = 'allow',
DENY = 'deny'
ALLOW = 'Allow',
DENY = 'Deny',
}

export interface IPolicyStatementResult {
name?: string
message?: string
action?: TriggeredPolicyAction
invoked: boolean
}

export interface IPolicyEnginePolicyResponse {
action?: TriggeredPolicyAction
name?: string
decision: PolicyDecision
reason: 'true' | 'false'
message?: string
reasons: IPolicyStatementResult[]
decision: PolicyDecision
errors: string[]
}

export interface IPolicyEngineInvokeResponse {
result: {
[key: string]: IPolicyEnginePolicyResponse
}
export interface IPolicyJSON {
effect: 'forbid' | 'permit'
principal: any
action: any
resource: any
conditions: any[]
annotations: {
[key: string]: string
}
}

export const Banyan = {
test: 'test'
};
export type PolicyToJSONResponse = IPolicyJSON[]

export const invoke = () => {
console.log('hello');
return hello();
console.log('hello')
return hello()
}

export const isAuthorized = (request: string) => {
console.log('authorize');
return authorize(request);
console.log('authorize')
return authorize(request)
}

export const parsePolicyEngineResponsePayload = (response: any): IPolicyEngineInvokeResponse | null => {
try {
const parsedResponse = JSON.parse(response)
export function validatePolicyEngineResponse(maybePolicyEngineResponse: any) {
const ajv = new Ajv()
const validate = ajv.compile(PolicyEngineResponse)
return validate(maybePolicyEngineResponse)
}

export const parsePolicyEngineResponsePayload = (response: any): IPolicyEnginePolicyResponse | null => {
try {
const parsedResponse = JSON.parse(response)
const validationResult = validatePolicyEngineResponse(parsedResponse)
console.log({ validationResult })
if (validationResult) return parsedResponse
else {
throw new Error('Failed to validate response')
}
} catch (error) {
// TODO handle parse error by raising an alert
console.error('Failed to parse response:', error)
return null
}
}

export const invokePolicyEngine = (request: IPolicyEngineInvokePayload): IPolicyEnginePolicyResponse => {
console.log('invokePolicyEngine')
const result = isAuthorized(JSON.stringify(request))
const parsed = parsePolicyEngineResponsePayload(result)
return parsed
}

export const policyToJson = (policy: string): PolicyToJSONResponse => {
console.log('policyToJson')
const result = policy_to_json(policy)
const parsedResponse: PolicyToJSONResponse = JSON.parse(result) // TODO validate
return parsedResponse
// const validationResult = validatePolicyEngineResponse(parsedResponse)
// console.log({ validationResult })
// if (validationResult) return parsedResponse
// else {
// throw new Error('Failed to validate response')
// }
} catch (error) {
// TODO handle parse error by raising an alert
console.error('Failed to parse response:', error)
return null
}
}

export const invokePolicyEngine = (request: IPolicyEngineInvokePayload): IPolicyEngineInvokeResponse => {
console.log('invokePolicyEngine');
const result = isAuthorized(JSON.stringify(request));
const parsed = parsePolicyEngineResponsePayload(result);
return parsed
}
export const validatePolicy = (request: IValidatePolicyPayload): any => {
console.log('validatePolicy')
const result = validate_policy(JSON.stringify(request))
const parsedResponse = JSON.parse(result) // TODO validate
return parsedResponse
}
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{
"name": "@shield3/banyan",
"version": "0.2.1",
"version": "0.3.0",
"description": "Banyan policy engine",
"main": "dist/index.js",
"scripts": {
"compileSchemas": "bob-tsm scripts/compileSchemas.ts",
"build-debug": "pnpm run build --",
"build": "cargo-cp-artifact -ac banyan_nodejs ./banyan.node -- cargo build --message-format=json-render-diagnostics",
"build-release": "cargo-cp-artifact -ac banyan_nodejs ./banyan.node -- cargo build --message-format=json-render-diagnostics --release",
Expand All @@ -23,6 +24,9 @@
"jest": "^29.7.0",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"typescript-json-schema": "^0.57.0",
"bob-ts": "^4.0.0",
"bob-tsm": "^1.1.1",
"typescript": "^5.2.2"
},
"os": [
Expand All @@ -35,7 +39,8 @@
"arm64"
],
"dependencies": {
"@mapbox/node-pre-gyp": "^1.0.11"
"@mapbox/node-pre-gyp": "^1.0.11",
"ajv": "^8.12.0"
},
"jest": {
"preset": "ts-jest/presets/default-esm",
Expand Down
Loading

0 comments on commit d1584eb

Please sign in to comment.