Skip to content

Commit

Permalink
Remove mac-ca usage since it was only in tests (#6043) (#6321)
Browse files Browse the repository at this point in the history
* Remove mac-ca usage since it was only in tests (#6043)

* Make injecting CAs injectable, remove mac-ca as dependency
* Fix win-ca failing on electron renderer on windows
* Fix the matcher under features/ for main

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix type errors from new types

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Temp change to see windows errors on CI

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix temp change

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Change error message for windows

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Increase maxBuffer size when reading windows CAs

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Switch back to running integration tests on windows

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix usage after rebase

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Update lock file

Signed-off-by: Sebastian Malton <sebastian@malton.name>

Signed-off-by: Sebastian Malton <sebastian@malton.name>
  • Loading branch information
Nokel81 authored Nov 22, 2022
1 parent 6d7090f commit 0eee5a0
Show file tree
Hide file tree
Showing 24 changed files with 293 additions and 271 deletions.
7 changes: 4 additions & 3 deletions integration/__tests__/app-preferences.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ describe("preferences page tests", () => {

await app.evaluate(async ({ app }) => {
await app.applicationMenu
.getMenuItemById(process.platform === "darwin" ? "mac" : "file")
.submenu.getMenuItemById("navigate-to-preferences")
.click();
?.getMenuItemById(process.platform === "darwin" ? "mac" : "file")
?.submenu
?.getMenuItemById("navigate-to-preferences")
?.click();
});
}, 10*60*1000);

Expand Down
3 changes: 2 additions & 1 deletion integration/__tests__/cluster-pages.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ import { minikubeReady } from "../helpers/minikube";
import type { Frame, Page } from "playwright";
import { groupBy, toPairs } from "lodash/fp";
import { pipeline } from "@ogre-tools/fp";
import { describeIf } from "../../src/test-utils/skippers";

const TEST_NAMESPACE = "integration-tests";

utils.describeIf(minikubeReady(TEST_NAMESPACE))("Minikube based tests", () => {
describeIf(minikubeReady(TEST_NAMESPACE))("Minikube based tests", () => {
let window: Page;
let cleanup: undefined | (() => Promise<void>);
let frame: Frame;
Expand Down
8 changes: 0 additions & 8 deletions integration/helpers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,6 @@ export const appPaths: Partial<Record<NodeJS.Platform, string>> = {
"darwin": "./dist/mac/OpenLens.app/Contents/MacOS/OpenLens",
};

export function itIf(condition: boolean) {
return condition ? it : it.skip;
}

export function describeIf(condition: boolean) {
return condition ? describe : describe.skip;
}

async function getMainWindow(app: ElectronApplication, timeout = 50_000): Promise<Page> {
return new Promise((resolve, reject) => {
const cleanup = disposer();
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,6 @@
"js-yaml": "^4.1.0",
"jsdom": "^16.7.0",
"lodash": "^4.17.15",
"mac-ca": "^1.0.6",
"marked": "^4.2.3",
"md5-file": "^5.0.0",
"mobx": "^6.7.0",
Expand Down
99 changes: 0 additions & 99 deletions src/common/__tests__/system-ca.test.ts

This file was deleted.

39 changes: 39 additions & 0 deletions src/common/certificate-authorities/inject-system-cas.injectable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/

import { getInjectable } from "@ogre-tools/injectable";
import { globalAgent } from "https";
import { requestSystemCAsInjectionToken } from "./request-system-cas-token";

// DST Root CA X3, which was expired on 9.30.2021
const DSTRootCAX3 = "-----BEGIN CERTIFICATE-----\nMIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/\nMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\nDkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow\nPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD\nEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\nAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O\nrz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq\nOLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b\nxiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw\n7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD\naeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV\nHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG\nSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69\nikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr\nAvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz\nR8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5\nJDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo\nOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ\n-----END CERTIFICATE-----\n";

function isCertActive(cert: string) {
const isExpired = typeof cert !== "string" || cert.includes(DSTRootCAX3);

return !isExpired;
}

const injectSystemCAsInjectable = getInjectable({
id: "inject-system-cas",
instantiate: (di) => {
const requestSystemCAs = di.inject(requestSystemCAsInjectionToken);

return async () => {
for (const cert of await requestSystemCAs()) {
if (isCertActive(cert)) {
if (Array.isArray(globalAgent.options.ca) && !globalAgent.options.ca.includes(cert)) {
globalAgent.options.ca.push(cert);
} else {
globalAgent.options.ca = [cert];
}
}
}
};
},
});

export default injectSystemCAsInjectable;

10 changes: 10 additions & 0 deletions src/common/certificate-authorities/request-system-cas-token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/

import { getInjectionToken } from "@ogre-tools/injectable";

export const requestSystemCAsInjectionToken = getInjectionToken<() => Promise<string[]>>({
id: "request-system-cas-token",
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import execFileInjectable from "../fs/exec-file.injectable";
import loggerInjectable from "../logger.injectable";
import type { AsyncResult } from "../utils/async-result";
import { requestSystemCAsInjectionToken } from "./request-system-cas-token";

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Cheatsheet#other_assertions
const certSplitPattern = /(?=-----BEGIN\sCERTIFICATE-----)/g;

const requestSystemCAsInjectable = getInjectable({
id: "request-system-cas",
instantiate: (di) => {
const execFile = di.inject(execFileInjectable);
const logger = di.inject(loggerInjectable);

const execSecurity = async (...args: string[]): Promise<AsyncResult<string[]>> => {
const result = await execFile("/usr/bin/security", args);

if (!result.callWasSuccessful) {
return {
callWasSuccessful: false,
error: result.error.stderr || result.error.message,
};
}

return {
callWasSuccessful: true,
response: result.response.split(certSplitPattern),
};
};

return async () => {
const [trustedResult, rootCAResult] = await Promise.all([
execSecurity("find-certificate", "-a", "-p"),
execSecurity("find-certificate", "-a", "-p", "/System/Library/Keychains/SystemRootCertificates.keychain"),
]);

if (!trustedResult.callWasSuccessful) {
logger.warn(`[INJECT-CAS]: Error retreiving trusted CAs: ${trustedResult.error}`);
} else if (!rootCAResult.callWasSuccessful) {
logger.warn(`[INJECT-CAS]: Error retreiving root CAs: ${rootCAResult.error}`);
} else {
return [...new Set([...trustedResult.response, ...rootCAResult.response])];
}

return [];
};
},
causesSideEffects: true,
injectionToken: requestSystemCAsInjectionToken,
});

export default requestSystemCAsInjectable;
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { requestSystemCAsInjectionToken } from "./request-system-cas-token";

const requestSystemCAsInjectable = getInjectable({
id: "request-system-cas",
instantiate: () => async () => [],
injectionToken: requestSystemCAsInjectionToken,
});

export default requestSystemCAsInjectable;
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { requestSystemCAsInjectionToken } from "./request-system-cas-token";

const requestSystemCAsInjectable = getInjectable({
id: "request-system-cas",
instantiate: () => async () => [],
injectionToken: requestSystemCAsInjectionToken,
});

export default requestSystemCAsInjectable;
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import execFileInjectable from "../fs/exec-file.injectable";
import loggerInjectable from "../logger.injectable";
import { requestSystemCAsInjectionToken } from "./request-system-cas-token";

const pemEncoding = (hexEncodedCert: String) => {
const certData = Buffer.from(hexEncodedCert, "hex").toString("base64");
const lines = ["-----BEGIN CERTIFICATE-----"];

for (let i = 0; i < certData.length; i += 64) {
lines.push(certData.substring(i, i + 64));
}

lines.push("-----END CERTIFICATE-----", "");

return lines.join("\r\n");
};

const requestSystemCAsInjectable = getInjectable({
id: "request-system-cas",
instantiate: (di) => {
const wincaRootsExePath: string = __non_webpack_require__.resolve("win-ca/lib/roots.exe");
const execFile = di.inject(execFileInjectable);
const logger = di.inject(loggerInjectable);

return async () => {
/**
* This needs to be done manually because for some reason calling the api from "win-ca"
* directly fails to load "child_process" correctly on renderer
*/
const result = await execFile(wincaRootsExePath, {
maxBuffer: 128 * 1024 * 1024, // 128 MiB
});

if (!result.callWasSuccessful) {
logger.warn(`[INJECT-CAS]: Error retreiving CAs`, result.error);

return [];
}

return result
.response
.split("\r\n")
.filter(Boolean)
.map(pemEncoding);
};
},
causesSideEffects: true,
injectionToken: requestSystemCAsInjectionToken,
});

export default requestSystemCAsInjectable;
Loading

0 comments on commit 0eee5a0

Please sign in to comment.