Skip to content

Commit a209fef

Browse files
committed
fix(cmd-api-server): config-service example - authorization JSON
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 <[email protected]>
1 parent e43155f commit a209fef

File tree

2 files changed

+53
-27
lines changed

2 files changed

+53
-27
lines changed

packages/cactus-cmd-api-server/src/main/typescript/config/config-service.ts

+19-27
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import convict, { Schema, Config, SchemaObj } from "convict";
44
import { ipaddress } from "convict-format-with-validator";
55
import { v4 as uuidV4 } from "uuid";
66
import { JWK, JWS } from "jose";
7+
import type { Options as ExpressJwtOptions } from "express-jwt";
78
import {
89
LoggerProvider,
910
Logger,
1011
LogLevelDesc,
11-
Strings,
1212
} from "@hyperledger/cactus-common";
1313
import {
1414
ConsortiumDatabase,
@@ -108,19 +108,7 @@ export class ConfigService {
108108
authorizationConfigJson: {
109109
doc: "The JSON string to deserialize when configuring authorization.",
110110
default: null as IAuthorizationConfig | null,
111-
format: (json: string) => {
112-
if (Strings.isString(json)) {
113-
ConfigService.formatNonBlankString(json);
114-
try {
115-
const authzConf = JSON.parse(json) as IAuthorizationConfig;
116-
return authzConf;
117-
} catch (ex) {
118-
throw new Error(`AUTHORIZATION_CONFIG_JSON invalid JSON`);
119-
}
120-
} else {
121-
return json;
122-
}
123-
},
111+
format: Object,
124112
env: "AUTHORIZATION_CONFIG_JSON",
125113
arg: "authorization-config-json",
126114
},
@@ -513,21 +501,25 @@ export class ConfigService {
513501

514502
const jwtSecret = uuidV4();
515503

504+
const expressJwtOptions: ExpressJwtOptions = {
505+
secret: jwtSecret,
506+
algorithms: ["RS256"],
507+
audience: "org.hyperledger.cactus.jwt.audience",
508+
issuer: "org.hyperledger.cactus.jwt.issuer",
509+
};
510+
511+
const authorizationConfigJson: IAuthorizationConfig = {
512+
socketIoPath: Constants.SocketIoConnectionPathV1,
513+
unprotectedEndpointExemptions: [],
514+
socketIoJwtOptions: {
515+
secret: jwtSecret,
516+
},
517+
expressJwtOptions,
518+
};
519+
516520
return {
517521
authorizationProtocol: AuthorizationProtocol.JSON_WEB_TOKEN,
518-
authorizationConfigJson: {
519-
socketIoPath: Constants.SocketIoConnectionPathV1,
520-
unprotectedEndpointExemptions: [],
521-
socketIoJwtOptions: {
522-
secret: jwtSecret,
523-
},
524-
expressJwtOptions: {
525-
secret: jwtSecret,
526-
algorithms: ["RS256"],
527-
audience: "org.hyperledger.cactus.jwt.audience",
528-
issuer: "org.hyperledger.cactus.jwt.issuer",
529-
},
530-
},
522+
authorizationConfigJson,
531523
configFile: ".config.json",
532524
cactusNodeId: uuidV4(),
533525
consortiumId: uuidV4(),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { LoggerProvider } from "@hyperledger/cactus-common";
2+
import test, { Test } from "tape-promise/tape";
3+
4+
import { IAuthorizationConfig } from "../../../../main/typescript/public-api";
5+
import { ApiServer } from "../../../../main/typescript/public-api";
6+
import { ConfigService } from "../../../../main/typescript/public-api";
7+
8+
test("Generates valid example config for the API server", async (t: Test) => {
9+
const configService = new ConfigService();
10+
t.ok(configService, "Instantiated ConfigService truthy OK");
11+
12+
const exampleConfig = configService.newExampleConfig();
13+
t.ok(exampleConfig, "configService.newExampleConfig() truthy OK");
14+
15+
// FIXME - this hack should not be necessary, we need to re-think how we
16+
// do configuration parsing. The convict library may not be the path forward.
17+
exampleConfig.authorizationConfigJson = (JSON.stringify(
18+
exampleConfig.authorizationConfigJson,
19+
) as unknown) as IAuthorizationConfig;
20+
21+
exampleConfig.configFile = "";
22+
23+
const convictConfig = configService.newExampleConfigConvict(exampleConfig);
24+
t.ok(convictConfig, "configService.newExampleConfigConvict() truthy OK");
25+
26+
const config = convictConfig.getProperties();
27+
t.ok(config, "convictConfig.getProperties() truthy OK");
28+
29+
LoggerProvider.setLogLevel(config.logLevel);
30+
const apiServer = new ApiServer({ config });
31+
await apiServer.start();
32+
test.onFinish(() => apiServer.shutdown());
33+
t.end();
34+
});

0 commit comments

Comments
 (0)