Skip to content

Commit

Permalink
refactor: WorkController (#984)
Browse files Browse the repository at this point in the history
  • Loading branch information
lautarodragan authored Aug 15, 2019
1 parent f3c15d5 commit c8458aa
Show file tree
Hide file tree
Showing 10 changed files with 212 additions and 250 deletions.
16 changes: 9 additions & 7 deletions src/api/API.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { SendEmailConfiguration } from '../utils/SendEmail'

import { AccountController } from '../controllers/AccountController'
import { ArchiveController } from '../controllers/ArchiveController'
import { WorkController } from '../controllers/WorkController'
import { errorHandling } from '../middlewares/errorHandling'
import { logger } from '../middlewares/logger'

Expand Down Expand Up @@ -41,23 +42,23 @@ interface APIMethods {
stop(): Promise<APIMethods>
}

const init = (accountController: AccountController, archiveController: ArchiveController) => ({
const init = (
accountController: AccountController,
archiveController: ArchiveController,
workController: WorkController,
) => ({
maxApiRequestLimitForm,
maxApiRequestLimitJson,
passwordComplex,
sendEmail,
poetUrl,
testPoetUrl,
maxApiTokens,
loggingConfiguration,
}: APIConfiguration) => {
const app = new Koa()
const route = routes(accountController, archiveController)(
const route = routes(accountController, archiveController, workController)(
passwordComplex,
sendEmail,
poetUrl,
maxApiTokens,
testPoetUrl,
)

app
Expand Down Expand Up @@ -97,13 +98,14 @@ const stopAPI = async (server: any, logger: Pino.Logger) => {
export const API = (
accountController: AccountController,
archiveController: ArchiveController,
workController: WorkController,
) => (configuration: APIConfiguration): APIMethods => {
const { loggingConfiguration } = configuration
const logger = createModuleLogger(loggingConfiguration)(__dirname)

return {
async start(): Promise<APIMethods> {
const app = init(accountController, archiveController)(configuration)
const app = init(accountController, archiveController, workController)(configuration)
this.server = await startAPI(app, configuration, logger)
return this
},
Expand Down
15 changes: 9 additions & 6 deletions src/api/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as KoaRouter from 'koa-router'

import { AccountController } from '../controllers/AccountController'
import { ArchiveController } from '../controllers/ArchiveController'
import { WorkController } from '../controllers/WorkController'

import { Authentication } from '../middlewares/authentication'
import { Authorization } from '../middlewares/authorization'
Expand Down Expand Up @@ -41,12 +42,14 @@ import { GetWorks } from './works/GetWorks'

import { PostArchive } from './archives/PostArchive'

export const routes = (accountController: AccountController, archiveController: ArchiveController) => (
export const routes = (
accountController: AccountController,
archiveController: ArchiveController,
workController: WorkController,
) => (
passwordComplexConfiguration: PasswordComplexConfiguration,
sendEmailConfiguration: SendEmailConfiguration,
poetUrl: string,
maxApiTokens: number,
testPoetUrl: string,
) => {
const router = new KoaRouter()
const authentication = Authentication(accountController)
Expand Down Expand Up @@ -144,10 +147,10 @@ export const routes = (accountController: AccountController, archiveController:
router.post(
Path.WORKS,
validate({ body: CreateWorkSchema, options: { allowUnknown: true } }),
CreateWork(poetUrl, testPoetUrl),
CreateWork(workController),
)
router.get(Path.WORKS_WORKID, validate({ params: GetWorkSchema }), GetWork(poetUrl, testPoetUrl))
router.get(Path.WORKS, GetWorks(poetUrl, testPoetUrl))
router.get(Path.WORKS_WORKID, validate({ params: GetWorkSchema }), GetWork(workController))
router.get(Path.WORKS, GetWorks(workController))

router.post(
Path.ARCHIVES,
Expand Down
44 changes: 13 additions & 31 deletions src/api/works/CreateWork.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import * as Joi from 'joi'

import { errors } from '../../errors/errors'
import { isLiveNetwork } from '../../helpers/token'
import { WorksController } from '../../modules/Works/Works.controller'
import { WorkController } from '../../controllers/WorkController'
import { Vault } from '../../utils/Vault/Vault'

export const CreateWorkSchema = () => ({
Expand All @@ -26,35 +24,19 @@ export const CreateWorkSchema = () => ({
.optional(),
})

export const CreateWork = (poetUrl: string, testPoetUrl: string) => async (ctx: any, next: any): Promise<any> => {
const logger = ctx.logger(__dirname)
export const CreateWork = (workController: WorkController) => async (ctx: any, next: any): Promise<any> => {
const { user, tokenData } = ctx.state

try {
const { user, tokenData } = ctx.state
const { WorkError } = errors
const { '@context': context = {}, ...claim } = ctx.request.body

const { '@context': context = {}, ...newWork } = ctx.request.body
const signedVerifiableClaim = await workController.create(
claim,
context,
user.issuer,
user.privateKey,
tokenData.data.meta.network,
)

logger.info({ context, newWork }, 'Creating Work')

const privateKey = await Vault.decrypt(user.privateKey)
const nodeNetwork = isLiveNetwork(tokenData.data.meta.network) ? poetUrl : testPoetUrl

const work = new WorksController(ctx.logger, nodeNetwork)
const claim = await work.generateClaim(user.issuer, privateKey, newWork, context)

try {
await work.create(claim)
} catch (e) {
ctx.status = WorkError.code
ctx.body = WorkError.message
return
}

ctx.status = 200
ctx.body = { workId: claim.id }
} catch (exception) {
logger.error({ exception }, 'api.CreateWork')
ctx.status = 500
}
ctx.status = 200
ctx.body = { workId: signedVerifiableClaim.id }
}
32 changes: 6 additions & 26 deletions src/api/works/GetWork.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,14 @@
import * as Joi from 'joi'
import { errors } from '../../errors/errors'
import { isLiveNetwork } from '../../helpers/token'
import { WorksController } from '../../modules/Works/Works.controller'
import { WorkController } from '../../controllers/WorkController'

export const GetWorkSchema = () => ({
workId: Joi.string().required(),
})

export const GetWork = (poetUrl: string, testPoetUrl: string) => async (ctx: any, next: any): Promise<any> => {
const logger = ctx.logger(__dirname)
export const GetWork = (workController: WorkController) => async (ctx: any, next: any): Promise<any> => {
const { workId } = ctx.params
const { tokenData } = ctx.state

try {
const { workId } = ctx.params
const { tokenData } = ctx.state

const nodeNetwork = isLiveNetwork(tokenData.data.meta.network) ? poetUrl : testPoetUrl

const worksController = new WorksController(ctx.logger, nodeNetwork)

try {
const response = await worksController.get(workId)
ctx.body = response.claim
return
} catch (e) {
const { WorkNotFound } = errors
ctx.status = WorkNotFound.code
ctx.body = WorkNotFound.message
}
} catch (exception) {
logger.error({ exception }, 'api.GetWork')
ctx.status = 500
}
const response = await workController.getById(workId, tokenData.data.meta.network)
ctx.body = response.claim
}
33 changes: 6 additions & 27 deletions src/api/works/GetWorks.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,10 @@
import { SignedVerifiableClaim } from '@po.et/poet-js'
import { errors } from '../../errors/errors'
import { isLiveNetwork } from '../../helpers/token'
import { WorksController } from '../../modules/Works/Works.controller'
import { WorkController } from '../../controllers/WorkController'

export const GetWorks = (poetUrl: string, testPoetUrl: string) => async (ctx: any, next: any): Promise<any> => {
const logger = ctx.logger(__dirname)
export const GetWorks = (workController: WorkController) => async (ctx: any, next: any): Promise<any> => {
const { user, tokenData } = ctx.state
const { issuer } = user

try {
const { user, tokenData } = ctx.state
const { issuer } = user
const response = await workController.searchWorks({ issuer }, tokenData.data.meta.network)

const nodeNetwork = isLiveNetwork(tokenData.data.meta.network) ? poetUrl : testPoetUrl

const worksController = new WorksController(ctx.logger, nodeNetwork)

try {
const response = await worksController.getWorksByIssuer(issuer)

ctx.body = response.map((work: SignedVerifiableClaim) => work.claim)
return
} catch (e) {
const { WorkNotFound } = errors
ctx.status = WorkNotFound.code
ctx.body = WorkNotFound.message
}
} catch (exception) {
logger.error({ exception }, 'api.GetWorks')
ctx.status = 500
}
ctx.body = response.map(work => work.claim)
}
32 changes: 15 additions & 17 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { API } from './api/API'
import { Configuration } from './configuration'
import { AccountController } from './controllers/AccountController'
import { ArchiveController } from './controllers/ArchiveController'
import { WorkController } from './controllers/WorkController'
import { AccountDao } from './daos/AccountDao'
import { PoetNode } from './daos/PoetNodeDao'
import { initVault } from './initVault'
Expand Down Expand Up @@ -48,6 +49,9 @@ export async function app(localVars: any = {}) {

const sendEmail = SendEmail(configurationFrostAPI.sendEmail)

const mainnetNode = PoetNode(configuration.poetUrl)
const testnetNode = PoetNode(configuration.testPoetUrl)

const accountController = AccountController({
dependencies: {
logger: logger.child({ file: 'AccountController' }),
Expand All @@ -61,11 +65,19 @@ export async function app(localVars: any = {}) {
},
})

const workController = WorkController({
dependencies: {
logger: logger.child({ file: 'WorkController' }),
mainnetNode,
testnetNode,
},
})

const archiveController = ArchiveController({
dependencies: {
logger: logger.child({ file: 'ArchiveController' }),
mainnetNode: PoetNode(configuration.poetUrl),
testnetNode: PoetNode(configuration.testPoetUrl),
mainnetNode,
testnetNode,
},
configuration: {
ethereumUrl: configuration.ethereumUrl,
Expand All @@ -76,7 +88,7 @@ export async function app(localVars: any = {}) {
},
})

const frostAPI = await API(accountController, archiveController)(configurationFrostAPI).start()
const frostAPI = await API(accountController, archiveController, workController)(configurationFrostAPI).start()

await accountDao.createIndices()

Expand All @@ -89,20 +101,6 @@ export async function app(localVars: any = {}) {
}
}

const configurationToMongoDB = (configuration: Configuration) => ({
mongodbUrl: configuration.mongodbUrl,
options: {
socketTimeoutMS: configuration.mongodbSocketTimeoutMS,
keepAlive: configuration.mongodbKeepAlive,
reconnectTries: configuration.mongodbReconnectTries,
useNewUrlParser: configuration.mongodbUseNewUrlParser,
},
loggingConfiguration: {
loggingLevel: configuration.loggingLevel,
loggingPretty: configuration.loggingPretty,
},
})

const configurationToFrostAPI = (configuration: Configuration) => ({
host: configuration.frostHost,
port: configuration.frostPort,
Expand Down
89 changes: 89 additions & 0 deletions src/controllers/WorkController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { configureCreateVerifiableClaim, getVerifiableClaimSigner, SignedVerifiableClaim } from '@po.et/poet-js'
import * as Pino from 'pino'
import { pipeP } from 'ramda'

import { PoetNode, WorkSearchFilters } from '../daos/PoetNodeDao'
import { Network } from '../interfaces/Network'
import { Vault } from '../utils/Vault/Vault'

export interface WorkController {
readonly getById: (id: string, network: Network) => Promise<SignedVerifiableClaim>
readonly searchWorks: (filters: WorkSearchFilters, network: Network) => Promise<ReadonlyArray<SignedVerifiableClaim>>
readonly create: (
claim: any,
context: any,
issuer: string,
privateKey: string,
network: Network,
) => Promise<SignedVerifiableClaim>
}

interface Arguments {
readonly dependencies: Dependencies
}

interface Dependencies {
readonly logger: Pino.Logger
readonly mainnetNode: PoetNode
readonly testnetNode: PoetNode
}

export const WorkController = ({
dependencies: {
logger,
mainnetNode,
testnetNode,
},
}: Arguments): WorkController => {
const networkToNode = (network: Network) => network === Network.LIVE ? mainnetNode : testnetNode

const getById = async (id: string, network: Network) => {
const node = networkToNode(network)
return node.getWorkById(id)
}

const searchWorks = async (filters: WorkSearchFilters, network: Network) => {
const node = networkToNode(network)
return node.searchWorks(filters)
}

const create = async (claim: any, context: any, issuer: string, encryptedPrivateKey: string, network: Network) => {
const node = networkToNode(network)

const legacyContext = {
content: 'schema:text',
}

const aboutContext = {
about: {
'@id': 'schema:url',
'@container': '@list',
},
}

const privateKey = await Vault.decrypt(encryptedPrivateKey)

const createAndSignClaim = pipeP(
configureCreateVerifiableClaim({ issuer, context: { ...legacyContext, ...context, ...aboutContext} }),
getVerifiableClaimSigner().configureSignVerifiableClaim({ privateKey }),
)

const { content, ...newWork } = claim

const [{ archiveUrl = '', hash = '' } = {}] = content ? await node.postArchive(content) : []

const signedVerifiableClaim = await createAndSignClaim({ about: [ archiveUrl ], hash, ...newWork })

logger.info({ signedVerifiableClaim })

await node.postWork(signedVerifiableClaim)

return signedVerifiableClaim
}

return {
getById,
searchWorks,
create,
}
}
Loading

0 comments on commit c8458aa

Please sign in to comment.