Skip to content

Commit

Permalink
fix(cmd-api-server): config-service example - authorization JSON
Browse files Browse the repository at this point in the history
The custom formatter that was introduced the parse the JSON
config for the authorizer was causing problems.
This was overlooked at the time of the implementation of the authz
feature because Peter (yours truly) is an idiot but also to a smaller
extent because there was no automated test coverage for this specific
issue which this commit is now rectifying by adding a new test case.

Longer term we should look into using a different configuration
parsing library that has more flexibility on how to handle JSON
and validations around it.

There was a second bug masked by the first which is that the
"algorithms" array property of the express-jwt middleware
options was also not being used correctly, but to get to that
first the initial bug with the parsing had to be fixed.

Signed-off-by: Peter Somogyvari <peter.somogyvari@accenture.com>
  • Loading branch information
petermetz committed Jun 1, 2021
1 parent e43155f commit a209fef
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import convict, { Schema, Config, SchemaObj } from "convict";
import { ipaddress } from "convict-format-with-validator";
import { v4 as uuidV4 } from "uuid";
import { JWK, JWS } from "jose";
import type { Options as ExpressJwtOptions } from "express-jwt";
import {
LoggerProvider,
Logger,
LogLevelDesc,
Strings,
} from "@hyperledger/cactus-common";
import {
ConsortiumDatabase,
Expand Down Expand Up @@ -108,19 +108,7 @@ export class ConfigService {
authorizationConfigJson: {
doc: "The JSON string to deserialize when configuring authorization.",
default: null as IAuthorizationConfig | null,
format: (json: string) => {
if (Strings.isString(json)) {
ConfigService.formatNonBlankString(json);
try {
const authzConf = JSON.parse(json) as IAuthorizationConfig;
return authzConf;
} catch (ex) {
throw new Error(`AUTHORIZATION_CONFIG_JSON invalid JSON`);
}
} else {
return json;
}
},
format: Object,
env: "AUTHORIZATION_CONFIG_JSON",
arg: "authorization-config-json",
},
Expand Down Expand Up @@ -513,21 +501,25 @@ export class ConfigService {

const jwtSecret = uuidV4();

const expressJwtOptions: ExpressJwtOptions = {
secret: jwtSecret,
algorithms: ["RS256"],
audience: "org.hyperledger.cactus.jwt.audience",
issuer: "org.hyperledger.cactus.jwt.issuer",
};

const authorizationConfigJson: IAuthorizationConfig = {
socketIoPath: Constants.SocketIoConnectionPathV1,
unprotectedEndpointExemptions: [],
socketIoJwtOptions: {
secret: jwtSecret,
},
expressJwtOptions,
};

return {
authorizationProtocol: AuthorizationProtocol.JSON_WEB_TOKEN,
authorizationConfigJson: {
socketIoPath: Constants.SocketIoConnectionPathV1,
unprotectedEndpointExemptions: [],
socketIoJwtOptions: {
secret: jwtSecret,
},
expressJwtOptions: {
secret: jwtSecret,
algorithms: ["RS256"],
audience: "org.hyperledger.cactus.jwt.audience",
issuer: "org.hyperledger.cactus.jwt.issuer",
},
},
authorizationConfigJson,
configFile: ".config.json",
cactusNodeId: uuidV4(),
consortiumId: uuidV4(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { LoggerProvider } from "@hyperledger/cactus-common";
import test, { Test } from "tape-promise/tape";

import { IAuthorizationConfig } from "../../../../main/typescript/public-api";
import { ApiServer } from "../../../../main/typescript/public-api";
import { ConfigService } from "../../../../main/typescript/public-api";

test("Generates valid example config for the API server", async (t: Test) => {
const configService = new ConfigService();
t.ok(configService, "Instantiated ConfigService truthy OK");

const exampleConfig = configService.newExampleConfig();
t.ok(exampleConfig, "configService.newExampleConfig() truthy OK");

// FIXME - this hack should not be necessary, we need to re-think how we
// do configuration parsing. The convict library may not be the path forward.
exampleConfig.authorizationConfigJson = (JSON.stringify(
exampleConfig.authorizationConfigJson,
) as unknown) as IAuthorizationConfig;

exampleConfig.configFile = "";

const convictConfig = configService.newExampleConfigConvict(exampleConfig);
t.ok(convictConfig, "configService.newExampleConfigConvict() truthy OK");

const config = convictConfig.getProperties();
t.ok(config, "convictConfig.getProperties() truthy OK");

LoggerProvider.setLogLevel(config.logLevel);
const apiServer = new ApiServer({ config });
await apiServer.start();
test.onFinish(() => apiServer.shutdown());
t.end();
});

0 comments on commit a209fef

Please sign in to comment.