Skip to content

Commit

Permalink
[DOVU Alpha V2] Guardian Middleware API rewrite (#20)
Browse files Browse the repository at this point in the history
* Hide tsc scan errror

* deprecating currents into into tests for alpha version of v2

* update an API endpoints for guardian v2 re-write

* update in tags with reference to query routes and state queries

* Update roles.ts

* Update index.ts

* Add password confirmation for guardian auth register

* Update tsc interfaces

* Update acc register for DTO for guardian

* Alpha V2: scan JSON (500) error response for unprocessible entities 422

* Updated openAPI spec for valid endpoints

* Rewrite/re-arch of API usage against policies.

* Format been able to return valid values based off of enum for validation (used in ensure query role)

* Dynamic ability for particular roles to reference block data for particular stages of a workflow

* Query handler for role based data view -- allow for filtering for any downstream credential subject value

* standalone utility to enable the ingestion of a credential, subject and filterable values to enable filtering

* Chore prettier
  • Loading branch information
mattsmithies committed Dec 8, 2023
1 parent 7b81880 commit 43fb482
Show file tree
Hide file tree
Showing 34 changed files with 1,216 additions and 285 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import StatusCode from 'src/constants/status'
import hmacAxios from 'src/apiClient/hmacApiClient'
import config from 'src/config'
import StatusCode from '../../../src/constants/status'
import hmacAxios from '../../../src/apiClient/hmacApiClient'
import config from '../../../src/config'

const SECONDS = 1000
const TEN_SECONDS = 10 * SECONDS
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import StatusCode from 'src/constants/status'
import hmacAxios from 'src/apiClient/hmacApiClient'
import config from 'src/config'
import StatusCode from '../../../src/constants/status'
import hmacAxios from '../../../src/apiClient/hmacApiClient'
import config from '../../../src/config'

const SECONDS = 1000
const TEN_SECONDS = 10 * SECONDS
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import StatusCode from 'src/constants/status'
import hmacAxios from 'src/apiClient/hmacApiClient'
import config from 'src/config'
import StatusCode from '../../../src/constants/status'
import hmacAxios from '../../../src/apiClient/hmacApiClient'
import config from '../../../src/config'

const SECONDS = 1000
const TEN_SECONDS = 10 * SECONDS
Expand Down Expand Up @@ -116,7 +116,7 @@ describe('Test General Supply Documentation policy flow', () => {
ONE_MINUTE
)
it(
'submits a new application',
'submits a new project',
async () => {
const { accessToken } = await loginResponseData(
registrant,
Expand Down Expand Up @@ -149,7 +149,7 @@ describe('Test General Supply Documentation policy flow', () => {
ONE_MINUTE
)
it(
'approves the application',
'approves the project',
async () => {
await new Promise((r) => setTimeout(r, TEN_SECONDS))
const { did } = await loginResponseData(registrant, password)
Expand All @@ -172,7 +172,7 @@ describe('Test General Supply Documentation policy flow', () => {
ONE_MINUTE
)
it(
'submits an ecological project',
'submits a site',
async () => {
await new Promise((r) => setTimeout(r, TEN_SECONDS))
const { accessToken } = await loginResponseData(
Expand Down Expand Up @@ -210,7 +210,7 @@ describe('Test General Supply Documentation policy flow', () => {
ONE_MINUTE
)
it(
'approves the ecological project',
'approves the site',
async () => {
await new Promise((r) => setTimeout(r, TEN_SECONDS))
const { did } = await loginResponseData(registrant, password)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import onlyPut from 'src/middleware/onlyPut'
import prepare from 'src/utils/prepare'
import useGuardianContext from 'src/context/useGuardianContext'
import approveMrvRequestHandler from 'src/handler/policies/approveMrvRequestHandler'
import approveClaimHandler from 'src/handler/policies/claims/approveClaimHandler'
import withAuthentication from 'src/middleware/withAuthentication'
import withHmac from 'src/middleware/withHmac'
import ensureRole from 'src/middleware/ensureRole'
Expand All @@ -13,4 +13,4 @@ export default prepare(
useGuardianContext,
withAuthentication,
ensureRole(Role.VERIFIER)
)(approveMrvRequestHandler)
)(approveClaimHandler)
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import onlyPut from 'src/middleware/onlyPut'
import prepare from 'src/utils/prepare'
import useGuardianContext from 'src/context/useGuardianContext'
import approveApplicationHandler from 'src/handler/policies/approveApplicationHandler'
import approveProjectHandler from 'src/handler/policies/projects/approveProjectHandler'
import withAuthentication from 'src/middleware/withAuthentication'
import withHmac from 'src/middleware/withHmac'
import ensureRole from 'src/middleware/ensureRole'
Expand All @@ -13,4 +13,4 @@ export default prepare(
useGuardianContext,
withAuthentication,
ensureRole(Role.STANDARD_REGISTRY)
)(approveApplicationHandler)
)(approveProjectHandler)
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import onlyPut from 'src/middleware/onlyPut'
import prepare from 'src/utils/prepare'
import useGuardianContext from 'src/context/useGuardianContext'
import approveEcologicalProjectHandler from 'src/handler/policies/approveEcologicalProjectHandler'
import approveSiteHandler from 'src/handler/policies/sites/approveSiteHandler'
import withAuthentication from 'src/middleware/withAuthentication'
import withHmac from 'src/middleware/withHmac'
import ensureRole from 'src/middleware/ensureRole'
Expand All @@ -13,4 +13,4 @@ export default prepare(
useGuardianContext,
withAuthentication,
ensureRole(Role.STANDARD_REGISTRY)
)(approveEcologicalProjectHandler)
)(approveSiteHandler)
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import onlyPost from 'src/middleware/onlyPost'
import prepare from 'src/utils/prepare'
import useGuardianContext from 'src/context/useGuardianContext'
import mrvSubmissionHandler from 'src/handler/policies/mrvSubmissionHandler'
import createSiteHandler from 'src/handler/policies/sites/createSiteHandler'
import withAuthentication from 'src/middleware/withAuthentication'
import withHmac from 'src/middleware/withHmac'
import ensureRole from 'src/middleware/ensureRole'
Expand All @@ -12,5 +12,5 @@ export default prepare(
withHmac,
useGuardianContext,
withAuthentication,
ensureRole(Role.REGISTRANT)
)(mrvSubmissionHandler)
ensureRole(Role.SUPPLIER)
)(createSiteHandler)
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import onlyPost from 'src/middleware/onlyPost'
import prepare from 'src/utils/prepare'
import useGuardianContext from 'src/context/useGuardianContext'
import registerProjectHandler from 'src/handler/policies/registerProjectHandler'
import createProjectHandler from 'src/handler/policies/projects/createProjectHandler'
import withAuthentication from 'src/middleware/withAuthentication'
import withHmac from 'src/middleware/withHmac'
import ensureRole from 'src/middleware/ensureRole'
Expand All @@ -12,5 +12,5 @@ export default prepare(
withHmac,
useGuardianContext,
withAuthentication,
ensureRole(Role.REGISTRANT)
)(registerProjectHandler)
ensureRole(Role.SUPPLIER)
)(createProjectHandler)
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import onlyPost from 'src/middleware/onlyPost'
import prepare from 'src/utils/prepare'
import useGuardianContext from 'src/context/useGuardianContext'
import ecologicalProjectHandler from 'src/handler/policies/ecologicalProjectHandler'
import createClaimHandler from 'src/handler/policies/claims/createClaimHandler'
import withAuthentication from 'src/middleware/withAuthentication'
import withHmac from 'src/middleware/withHmac'
import ensureRole from 'src/middleware/ensureRole'
import { Role } from 'src/config/guardianTags'

/**
* 6 Month Deprecation notice: December 2023 - May 2024
*/
export default prepare(
onlyPost,
withHmac,
useGuardianContext,
withAuthentication,
ensureRole(Role.REGISTRANT)
)(ecologicalProjectHandler)
ensureRole(Role.SUPPLIER)
)(createClaimHandler)
13 changes: 13 additions & 0 deletions pages/api/policies/[policyId]/state/[entity].ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import onlyGet from 'src/middleware/onlyGet'
import prepare from 'src/utils/prepare'
import useGuardianContext from 'src/context/useGuardianContext'
import queryEntityHandler from 'src/handler/state/queryEntityHandler'
import withAuthentication from 'src/middleware/withAuthentication'
import ensureQueryDataRole from 'src/middleware/ensureQueryDataRole'

export default prepare(
onlyGet,
useGuardianContext,
withAuthentication,
ensureQueryDataRole
)(queryEntityHandler)
66 changes: 53 additions & 13 deletions src/config/guardianTags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,32 @@

export enum Tag {
chooseRole = 'choose_role',
initialApplicationSubmission = 'create_application',
initialProjectSubmission = 'create_ecological_project',

// Approve an application
approveApplicationBlocks = 'registrants_grid',
approveApplicationBtn = 'approve_registrant_btn',
supplierGrid = 'supplier_grid',
// supplierGrid = 'save_copy_ecological_project',
approveProjectBtn = 'approve_supplier_btn',

// Submit document to make an ecological project
createEcologicalProject = 'create_farm_form',
// Submit document to make site
createSite = 'create_site_form',

sitesForClaim = 'sites_grid',

// Submit an MRV for an ecological project as an issue request
mrvSubmission = 'create_issue_request_form',
mrvSubmission = 'create_claim_request_form',

// Submit document to make a claim
createClaim = 'create_claim_request_form',

// Approve an ecological project
approveEcologicalProject = 'approve_farms_grid',
approveEcologicalProjectBtn = 'approve_farm_button',
approveSite = 'approve_sites_grid',
approveSiteBtn = 'approve_site_button',

// Approve an MRV request
approveMrvRequest = 'issue_requests_grid(evident)',
approveMrvRequestBtn = 'approve_issue_requests_btn',
// approveMrvRequest = 'claim_requests_grid(evident)',
approveClaimRequest = 'claim_requests_grid(verifier)',
approveClaimRequestBtn = 'approve_claim_requests_btn',

// Weirdness needed for all document approval
approveBtn = 'Option_0',
Expand All @@ -40,18 +47,51 @@ export enum Tag {

// Path to mint token
verifierWorkflow = 'verifier_workflow',
approveIssueRequestsPage = 'approve_issue_requests_page',
mintTokenParent = 'mit_token',
approveIssueRequestsPage = 'approve_claim_requests_page',
mintTokenParent = 'mint_token',
}

export enum Role {
STANDARD_REGISTRY = 'ADMINISTRATOR',
VERIFIER = 'VERIFIER',
REGISTRANT = 'REGISTRANT',
SUPPLIER = 'SUPPLIER',
}

export enum MRV {
AGRECALC = 'agrecalc',
COOL_FARM_TOOL = 'cool-farm-tool',
GENERAL_SUPPLY_DOCUMENTATION = 'general-supply-documentation',
}

export enum EntityState {
APPROVED = 'Approved',
WAITING = 'Waiting for approval',
}

/**
* This enables the (API) client to query the entity at a particular state of the workflow,
* guardian expects different users to query to submit documents.
*/
export enum QueryRoute {
PROJECTS = 'projects', // registry only
APPROVE_SITE = 'approve-site', // registry only
CREATE_SITE = 'create-site', // supplier only
CREATE_CLAIM = 'create-claim', // supplier only
APPROVE_CLAIM = 'approve-claim', // verifier only
}

export const QueryBlockTag = {
[QueryRoute.PROJECTS]: Tag.supplierGrid,
[QueryRoute.CREATE_SITE]: Tag.createSite,
[QueryRoute.CREATE_CLAIM]: Tag.sitesForClaim,
[QueryRoute.APPROVE_SITE]: Tag.approveSite,
[QueryRoute.APPROVE_CLAIM]: Tag.approveClaimRequest,
}

export const QueryRole = {
[QueryRoute.PROJECTS]: Role.STANDARD_REGISTRY,
[QueryRoute.CREATE_SITE]: Role.SUPPLIER,
[QueryRoute.CREATE_CLAIM]: Role.SUPPLIER,
[QueryRoute.APPROVE_SITE]: Role.STANDARD_REGISTRY,
[QueryRoute.APPROVE_CLAIM]: Role.VERIFIER,
}
2 changes: 1 addition & 1 deletion src/config/roles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
export default {
user: 'USER',
standardRegistry: 'STANDARD_REGISTRY',
registrant: 'REGISTRANT',
supplier: 'SUPPLIER',
verifier: 'VERIFIER',
}
15 changes: 9 additions & 6 deletions src/constants/language/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ const language = {
'A role can only be enforced when connected to a policy',
policyDoesNotExist: 'A policy cannot be found with that id',
[Role.STANDARD_REGISTRY]:
'Only a "STANDARD_REGISTRY" policy owner may approve an application',
'Only a "STANDARD_REGISTRY" policy owner may approve a project, site or query related block data',
[Role.VERIFIER]:
'Only a user with the role "VERIFIER" make approve an MRV block',
[Role.REGISTRANT]:
'Only a user with the role "REGISTRANT" may submit this document',
'Only a user with the role "VERIFIER" make approve an claim (MRV) block or query related block data',
[Role.SUPPLIER]:
'Only a user with the role "SUPPLIER" may submit this document or query related block data',
},
withAuthenticationResponse: {
noAccessToken:
Expand All @@ -24,13 +24,16 @@ const language = {
notAllowed: (method: string) =>
`Method ${method} is not allowed on this route`,
},
queryResponse: {
invalidType: (validValues: string) =>
`The policy can only query types of ${validValues}. Please update your request.`,
},
ensureMrv: {
unknownMrv: 'No MRV found with that id',
},
validate: {
message: 'Validation errors',
invalidRole:
"Invalid role type. Must be 'registrant' or 'verifier'",
invalidRole: "Invalid role type. Must be 'supplier' or 'verifier'",
},
guardian: {
serverError:
Expand Down
1 change: 1 addition & 0 deletions src/guardian/account/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ interface LoginCredentialsDto {
export interface CreateAccountDto {
username: string
password: string
password_confirmation: string
role: 'USER'
}
export interface Accounts {
Expand Down
5 changes: 4 additions & 1 deletion src/guardian/policies/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { AxiosInstance, AxiosResponse } from 'axios'

export interface BlockData {
data?: BlockData[] // Feels naughty 👹
find?: Function
reduce?: Function
push?: Function
data?: BlockData[] | BlockData // Feels naughty 👹
hash?: string
id: string
uiMetaData: { title: string; description: string }
Expand Down
3 changes: 2 additions & 1 deletion src/handler/accounts/createAccountHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ async function CreateAccountHandler(

const userData: CreateAccountDto = {
...userCredentials,
// This doesn't need to be a registrant (the API handles the registration)
// This doesn't need to be a supplier (the API handles the registration)
role: 'USER',
password_confirmation: userCredentials.password,
}

await guardian.account.register(userData)
Expand Down
45 changes: 0 additions & 45 deletions src/handler/policies/approveEcologicalProjectHandler.ts

This file was deleted.

Loading

0 comments on commit 43fb482

Please sign in to comment.