-
Notifications
You must be signed in to change notification settings - Fork 286
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(core-manager): implement basic authentication (#3687)
- Loading branch information
1 parent
9894e9a
commit c304257
Showing
18 changed files
with
556 additions
and
47 deletions.
There are no files selected for viewing
211 changes: 211 additions & 0 deletions
211
__tests__/unit/core-manager/server/plugins/rpc-response-handler.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
import "jest-extended"; | ||
|
||
import { Server as HapiServer } from "@hapi/hapi"; | ||
import * as Boom from "@hapi/boom"; | ||
import * as rpc from "@hapist/json-rpc"; | ||
|
||
import { Container } from "@packages/core-kernel"; | ||
import { Validation } from "@packages/crypto"; | ||
import { Sandbox } from "@packages/core-test-framework"; | ||
import { Identifiers } from "@packages/core-manager/src/ioc"; | ||
import { Server } from "@packages/core-manager/src/server/server"; | ||
import { ActionReader } from "@packages/core-manager/src/action-reader"; | ||
import { Actions, Plugins } from "@packages/core-manager/src/contracts"; | ||
import { rpcResponseHandler } from "@packages/core-manager/src/server/plugins/rpc-response-handler"; | ||
import { Assets } from "../../__fixtures__"; | ||
|
||
let sandbox: Sandbox; | ||
let server: Server; | ||
|
||
let mockOnRequest = jest.fn(); | ||
|
||
// @ts-ignore | ||
let dummyPlugin = { | ||
name: "dummy", | ||
version: "0.0.1", | ||
register: (server: HapiServer) => { | ||
server.ext({ | ||
type: "onRequest", | ||
method: mockOnRequest | ||
}) | ||
} | ||
} | ||
|
||
let mockPluginFactory: Plugins.PluginFactory = { | ||
preparePlugins() { | ||
return [ | ||
{ | ||
plugin: rpcResponseHandler | ||
}, | ||
{ | ||
plugin: rpc, | ||
options: { | ||
methods: [ | ||
new Assets.DummyAction() | ||
], | ||
processor: { | ||
schema: { | ||
properties: { | ||
id: { | ||
type: ["number", "string"], | ||
}, | ||
jsonrpc: { | ||
pattern: "2.0", | ||
type: "string", | ||
}, | ||
method: { | ||
type: "string", | ||
}, | ||
params: { | ||
type: "object", | ||
}, | ||
}, | ||
required: ["jsonrpc", "method", "id"], | ||
type: "object", | ||
}, | ||
validate(data: object, schema: object) { | ||
try { | ||
const { error } = Validation.validator.validate(schema, data); | ||
return { value: data, error: error ? error : null }; | ||
} catch (error) { | ||
return { value: null, error: error.stack }; | ||
} | ||
}, | ||
}, | ||
} | ||
}, | ||
{ | ||
plugin: dummyPlugin | ||
}, | ||
] | ||
} | ||
} | ||
|
||
let logger = { | ||
info: jest.fn(), | ||
notice: jest.fn(), | ||
error: jest.fn(), | ||
} | ||
|
||
beforeEach(() => { | ||
|
||
let dummyAction = new Assets.DummyAction(); | ||
|
||
let actionReader: Partial<ActionReader> = { | ||
discoverActions(): Actions.Action[] { | ||
return [dummyAction]; | ||
} | ||
} | ||
|
||
sandbox = new Sandbox(); | ||
|
||
sandbox.app.bind(Identifiers.HTTP).to(Server).inSingletonScope(); | ||
sandbox.app.bind(Identifiers.ActionReader).toConstantValue(actionReader); | ||
sandbox.app.bind(Identifiers.PluginFactory).toConstantValue(mockPluginFactory); | ||
|
||
sandbox.app.bind(Container.Identifiers.LogService).toConstantValue(logger); | ||
|
||
server = sandbox.app.get<Server>(Identifiers.HTTP); | ||
}); | ||
|
||
afterEach(async () => { | ||
await server.dispose(); | ||
jest.clearAllMocks(); | ||
}) | ||
|
||
describe("RPC Response Handler", () => { | ||
let injectOptions; | ||
|
||
beforeEach(() => { | ||
injectOptions = { | ||
method: "POST", | ||
url: "/", | ||
payload: { | ||
jsonrpc: "2.0", | ||
id: "1", | ||
method: "dummy", | ||
params: { id: 123 }, | ||
}, | ||
headers: { | ||
"content-type": "application/vnd.api+json", | ||
}, | ||
}; | ||
}) | ||
|
||
it("should return result", async () => { | ||
await server.initialize("serverName", {}) | ||
await server.boot() | ||
|
||
mockOnRequest.mockImplementation((request, h) => { | ||
return h.continue; | ||
}) | ||
|
||
const response = await server.inject(injectOptions); | ||
const parsedResponse: Record<string, any> = { body: response.result, statusCode: response.statusCode }; | ||
|
||
expect(parsedResponse).toEqual({ body: { id: '1', jsonrpc: '2.0', result: {} }, statusCode: 200 }) | ||
}); | ||
|
||
it("should return status -32001 if 401 response code", async () => { | ||
await server.initialize("serverName", {}) | ||
await server.boot() | ||
|
||
mockOnRequest.mockImplementation((request, h) => { | ||
return Boom.unauthorized(); | ||
}) | ||
|
||
const response = await server.inject(injectOptions); | ||
const parsedResponse: Record<string, any> = { body: response.result, statusCode: response.statusCode }; | ||
|
||
expect(parsedResponse).toEqual({ | ||
body: { | ||
jsonrpc: '2.0', | ||
error: { code: -32001, message: 'These credentials do not match our records' }, | ||
id: null | ||
}, | ||
statusCode: 200 | ||
}) | ||
}); | ||
|
||
it("should return status -32003 if 403 response code", async () => { | ||
await server.initialize("serverName", {}) | ||
await server.boot() | ||
|
||
mockOnRequest.mockImplementation((request, h) => { | ||
return Boom.forbidden(); | ||
}) | ||
|
||
const response = await server.inject(injectOptions); | ||
const parsedResponse: Record<string, any> = { body: response.result, statusCode: response.statusCode }; | ||
|
||
expect(parsedResponse).toEqual({ | ||
body: { | ||
jsonrpc: '2.0', | ||
error: { code: -32003, message: 'Forbidden' }, | ||
id: null | ||
}, | ||
statusCode: 200 | ||
}) | ||
}); | ||
|
||
it("should return status -32603 if unhandled response code", async () => { | ||
await server.initialize("serverName", {}) | ||
await server.boot() | ||
|
||
mockOnRequest.mockImplementation((request, h) => { | ||
return Boom.notImplemented(); | ||
}) | ||
|
||
const response = await server.inject(injectOptions); | ||
const parsedResponse: Record<string, any> = { body: response.result, statusCode: response.statusCode }; | ||
|
||
expect(parsedResponse).toEqual({ | ||
body: { | ||
jsonrpc: '2.0', | ||
error: { code: -32603, message: 'Internal server error' }, | ||
id: null | ||
}, | ||
statusCode: 200 | ||
}) | ||
}); | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.