Skip to content

Commit

Permalink
feat(cactus-plugin-ledger-connector-cdl-socketio): separate endpoint …
Browse files Browse the repository at this point in the history
…for subscription key

- Add separate configurations for endpoints supporting access token
    and subscription key separately.
- This is required by current public instance of CDL.

Signed-off-by: Michal Bajer <michal.bajer@fujitsu.com>
  • Loading branch information
outSH authored and petermetz committed Oct 19, 2023
1 parent 5c0578a commit b1048af
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ This plugin provides `Cacti` a way to interact with Fujitsu CDL networks. Using

#### Configuring CDL API Gateway Access

- Set the base URL of GW service in `cdlApiGateway.url` (example: `"http://localhost:3000"`).
- Set the base URL of GW service in `cdlApiGateway.url` (when using JWT access token - DEFAULT) and/or `cdlApiSubscriptionGateway.url` (when using subscription-key)
- Example: `"http://localhost:3000"`
- If the service certificate is signed with a known CA (node uses Mozilla DB), then you can skip the next steps.
- If the service is signed with unknown CA, you can specify the gateway certificate to trust manually:
- Set `cdlApiGateway.caPath` to path of API Gateway certificate (in PEM format). (example: `"/etc/cactus/connector-cdl-socketio/CA/cdl-api-gateway-ca.pem"`)
- (optional) If server name in cert doesn't match the one in `cdlApiGateway.url`, you can overwrite it in `cdlApiGateway.serverName`
- (not recommended - only for development): To ignore certificate rejection (e.g. use self-signed certificate) set `cdlApiGateway.skipCertCheck` to `true`.
- Set `cdlApiGateway.caPath`/`cdlApiSubscriptionGateway.caPath` to path of API Gateway certificate (in PEM format). (example: `"/etc/cactus/connector-cdl-socketio/CA/cdl-api-gateway-ca.pem"`)
- (optional) If server name in cert doesn't match the one in `url`, you can overwrite it in `cdlApiGateway.serverName`/`cdlApiSubscriptionGateway.serverName`
- (not recommended - only for development): To ignore certificate rejection (e.g. use self-signed certificate) set `cdlApiGateway.skipCertCheck`/`cdlApiSubscriptionGateway.skipCertCheck` to `true`.
### Docker
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,8 @@ cdlApiGateway:
#skipCertCheck: true # Set to true to ignore self-signed and other rejected certificates
#caPath: "/etc/cactus/connector-cdl-socketio/CA/cdl-api-gateway-ca.pem" # CA of CDL API gateway server in PEM format to use
#serverName: "cdl.fujitsu" # Overwrite server name from cdlApiGateway.url to match one specified in CA
cdlApiSubscriptionGateway:
url: "http://localhost:3000"
#skipCertCheck: true # Set to true to ignore self-signed and other rejected certificates
#caPath: "/etc/cactus/connector-cdl-socketio/CA/cdl-api-gateway-ca.pem" # CA of CDL API gateway server in PEM format to use
#serverName: "cdl.fujitsu" # Overwrite server name from cdlApiGateway.url to match one specified in CA
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import {
AuthInfoArgsType,
HTTP_HEADER_SUBSCRIPTION_KEY,
HTTP_HEADER_TRUST_USER_ID,
HTTP_HEADER_TRUST_USER_ROLE,
HTTP_HEADER_TRUST_AGENT_ID,
HTTP_HEADER_TRUST_AGENT_ROLE,
isAuthInfoAccessTokenArgsType,
isAuthInfoSubscriptionKeyArgsType,
} from "./type-defs";
Expand All @@ -13,11 +18,15 @@ import { readFileSync } from "fs";
const logger = getLogger("cdl-request[" + process.pid + "]");
logger.level = configRead("logLevel", "info");

function getHttpsAgent() {
type HTTPAuthHeadersType = Record<string, string | number | boolean>;

function createHttpsGatewayConfig(
gatewayKey: "cdlApiGateway" | "cdlApiSubscriptionGateway",
) {
const agentOptions: https.AgentOptions = {};

const skipCertCheck = configRead<boolean>(
"cdlApiGateway.skipCertCheck",
`${gatewayKey}.skipCertCheck`,
false,
);
if (skipCertCheck) {
Expand All @@ -27,24 +36,40 @@ function getHttpsAgent() {
agentOptions.rejectUnauthorized = !skipCertCheck;
}

const caPath = configRead<string>("cdlApiGateway.caPath", "");
const caPath = configRead<string>(`${gatewayKey}.caPath`, "");
if (caPath) {
logger.info(`Using CDL API GW CA ${caPath}`);
const gatewayCAString = readFileSync(caPath, "ascii");
logger.debug("CDL Gateway certificate read:", gatewayCAString);
agentOptions.ca = gatewayCAString;
}

const serverName = configRead<string>("cdlApiGateway.serverName", "");
const serverName = configRead<string>(`${gatewayKey}.serverName`, "");
if (serverName) {
logger.info(`Overwrite CDL API GW server name with '${serverName}'`);
agentOptions.servername = serverName;
}

return new https.Agent(agentOptions);
return {
baseURL: configRead<string>(`${gatewayKey}.url`),
httpsAgent: new https.Agent(agentOptions),
};
}

const COMMON_HTTPS_AGENT = getHttpsAgent();
const API_GATEWAY_CONFIG = createHttpsGatewayConfig("cdlApiGateway");
const API_SUBSCRIPTION_GATEWAY_CONFIG = createHttpsGatewayConfig(
"cdlApiSubscriptionGateway",
);

function getHttpsGatewayConfigForHeaders(headers: HTTPAuthHeadersType) {
if (HTTP_HEADER_SUBSCRIPTION_KEY in headers) {
logger.debug("Using subscription key gateway for this request");
return API_SUBSCRIPTION_GATEWAY_CONFIG;
}

logger.debug("Using access token gateway for this request");
return API_GATEWAY_CONFIG;
}

export async function cdlRequest(
url: string,
Expand All @@ -59,17 +84,20 @@ export async function cdlRequest(

logger.debug(`cdlRequest ${httpMethod} ${url} executed`);

const authHeaders = getAuthorizationHeaders(authInfo);
const { httpsAgent, baseURL } = getHttpsGatewayConfigForHeaders(authHeaders);

try {
const requestResponse = await axios({
httpsAgent: COMMON_HTTPS_AGENT,
httpsAgent,
method: httpMethod,
baseURL: configRead<string>("cdlApiGateway.url"),
baseURL,
url,
responseType: "json",
headers: {
"User-Agent": configRead<string>("userAgent", "CactiCDLConnector"),
"Content-Type": "application/json;charset=UTF-8",
...getAuthorizationHeaders(authInfo),
...authHeaders,
},
params: queryParams,
data: dataPayload,
Expand All @@ -87,7 +115,7 @@ export async function cdlRequest(

function getAuthorizationHeaders(
authInfo: AuthInfoArgsType,
): Record<string, string | number | boolean> {
): HTTPAuthHeadersType {
if (
isAuthInfoAccessTokenArgsType(authInfo) &&
isAuthInfoSubscriptionKeyArgsType(authInfo)
Expand All @@ -100,15 +128,15 @@ function getAuthorizationHeaders(
if (isAuthInfoAccessTokenArgsType(authInfo)) {
return {
Authorization: `Bearer ${authInfo.accessToken}`,
"Trust-Agent-Id": authInfo.trustAgentId,
[HTTP_HEADER_TRUST_AGENT_ID]: authInfo.trustAgentId,
};
} else if (isAuthInfoSubscriptionKeyArgsType(authInfo)) {
return {
"Ocp-Apim-Subscription-Key": authInfo.subscriptionKey,
"Trust-User-Id": authInfo.trustUserId,
"Trust-User-Role": authInfo.trustUserRole,
"Trust-Agent-Id": authInfo.trustAgentId,
"Trust-Agent-Role": authInfo.trustAgentRole,
[HTTP_HEADER_SUBSCRIPTION_KEY]: authInfo.subscriptionKey,
[HTTP_HEADER_TRUST_USER_ID]: authInfo.trustUserId,
[HTTP_HEADER_TRUST_USER_ROLE]: authInfo.trustUserRole,
[HTTP_HEADER_TRUST_AGENT_ID]: authInfo.trustAgentId,
[HTTP_HEADER_TRUST_AGENT_ROLE]: authInfo.trustAgentRole,
};
} else {
throw new Error(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { type } from "os";

export type SupportedFunctions =
| "registerHistoryData"
| "getLineage"
Expand Down Expand Up @@ -57,3 +55,9 @@ export type FunctionArgsType = {
args: any;
reqID?: string;
};

export const HTTP_HEADER_SUBSCRIPTION_KEY = "Ocp-Apim-Subscription-Key";
export const HTTP_HEADER_TRUST_USER_ID = "Trust-User-Id";
export const HTTP_HEADER_TRUST_USER_ROLE = "Trust-User-Role";
export const HTTP_HEADER_TRUST_AGENT_ID = "Trust-Agent-Id";
export const HTTP_HEADER_TRUST_AGENT_ROLE = "Trust-Agent-Role";

0 comments on commit b1048af

Please sign in to comment.