Skip to content

Commit

Permalink
Use signedBuild property in frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
Gregor Billing committed Oct 2, 2020
1 parent 4e1ed13 commit 712222f
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import org.worldcubeassociation.tnoodle.server.crypto.BuildVerification

@Serializable
data class VersionInfo(
val runningVersion: String,
val projectName: String,
val projectVersion: String,
val signedBuild: Boolean,
Expand All @@ -15,7 +14,6 @@ data class VersionInfo(
companion object {
fun fromEnvironmentConfig(config: ServerEnvironmentConfig): VersionInfo {
return VersionInfo(
config.title,
config.projectName,
config.projectVersion,
BuildVerification.BUILD_VERIFIED,
Expand Down
92 changes: 46 additions & 46 deletions tnoodle-ui/src/main/components/VersionInfo.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ const VersionInfo = connect(
currentTnoodle: null,
allowedTnoodleVersions: null,
runningVersion: null,
officialBuild: null,
signedBuild: null,
signatureKeyBytes: null,
wcaPublicKeyBytes: null,
wcaResponse: false,
tnoodleResponse: false,
};
Expand All @@ -31,46 +33,53 @@ const VersionInfo = connect(
if (!response) {
return;
}
let {current, allowed, publicKeyBytes} = response;
this.setState({
...this.state,
currentTnoodle: response.current,
allowedTnoodleVersions: response.allowed,
currentTnoodle: current,
allowedTnoodleVersions: allowed,
wcaPublicKeyBytes: publicKeyBytes,
wcaResponse: true,
});
this.analizeVersion();
this.analyzeVersion();
});

fetchRunningVersion().then((response) => {
if (!response) {
return;
}
let { projectName, projectVersion, signedBuild } = response;
let {projectName, projectVersion, signedBuild, signatureKeyBytes} = response;
this.setState({
...this.state,
// Running version is based on projectName and projectVersion
runningVersion:
projectVersion != null && projectVersion != null
projectName != null && projectVersion != null
? `${projectName}-${projectVersion}`
: "",
officialBuild: signedBuild,
signedBuild: signedBuild,
signatureKeyBytes: signatureKeyBytes,
tnoodleResponse: true,
});
this.analizeVersion();
this.analyzeVersion();
});
}

signatureValid() {
return this.state.signedBuild && this.state.signatureKeyBytes === this.state.wcaPublicKeyBytes;
}

// This method avoids global state update while rendering
analizeVersion() {
// We wait until both wca and tnoodle answes
analyzeVersion() {
// We wait until both wca and tnoodle answers
if (!this.state.tnoodleResponse || !this.state.wcaResponse) {
return;
}

let runningVersion = this.state.runningVersion;
let allowedVersions = this.state.allowedTnoodleVersions;
let officialBuild = this.state.officialBuild;
let signedBuild = this.signatureValid();

if (!officialBuild || !allowedVersions.includes(runningVersion)) {
if (!signedBuild || !allowedVersions.includes(runningVersion)) {
this.props.updateOfficialZipStatus(false);
}
}
Expand All @@ -79,54 +88,45 @@ const VersionInfo = connect(
let runningVersion = this.state.runningVersion;
let allowedVersions = this.state.allowedTnoodleVersions;
let currentTnoodle = this.state.currentTnoodle;
let officialBuild = this.state.officialBuild;
let signedBuild = this.signatureValid();

// We cannot analyze TNoodle version here. We do not bother the user.
if (!runningVersion || !allowedVersions) {
return null;
}

// Generated version is not an official jar
if (!officialBuild) {
return (
<div className="alert alert-danger m-0">
This TNoodle version is not official and scrambles
generated with this must not be used in competition. You
are on version {runningVersion}, you should use{" "}
{currentTnoodle.name} available{" "}
<a href={currentTnoodle.download}>here</a>
</div>
);
}

// Best case scenario. We place this after the officialBuild
// so we can avoid not official build from being accidentally used.
if (runningVersion === currentTnoodle.name) {
return null;
}
// Running version is not the most recent release
if (runningVersion !== currentTnoodle.name) {
// Running version is allowed, but not the latest.
if (allowedVersions.includes(runningVersion)) {
return (
<div className="alert alert-info m-0">
You are running {runningVersion}, which is still
allowed, but you should upgrade to {currentTnoodle.name}{" "}
available <a href={currentTnoodle.download}>here</a>{" "}
as soon as possible.
</div>
);
}

// Running version is not allowed anymore.
if (!allowedVersions.includes(runningVersion)) {
return (
<div className="alert alert-danger m-0">
This TNoodle version is not allowed. Do not use
scrambles generated in any official competition and
consider downloading the latest version{" "}
<a href={this.state.currentTnoodle.download}>here</a>.
You are running {runningVersion}, which is not allowed.
Do not use scrambles generated in any official competition
and consider downloading the latest version{" "}
<a href={currentTnoodle.download}>here</a>.
</div>
);
}

// Running version is allowed, but not the latest.
if (
allowedVersions.includes(runningVersion) &&
runningVersion !== currentTnoodle.name
) {
// Generated version is not an officially signed jar
if (!signedBuild) {
return (
<div className="alert alert-info m-0">
You are running {runningVersion}, which is still
allowed, but you should upgrade to {currentTnoodle.name}{" "}
available <a href={currentTnoodle.download}>here</a>.
<div className="alert alert-danger m-0">
You are running an unsigned TNoodle release.
Do not use scrambles generated in any official competition
and consider downloading the official program{" "}
<a href={currentTnoodle.download}>here</a>
</div>
);
}
Expand Down
68 changes: 59 additions & 9 deletions tnoodle-ui/src/test/VersionInfo.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import store from "../main/redux/Store";

import VersionInfo from "../main/components/VersionInfo";

import { scrambleProgram, version } from "./mock/wca.api.mock";

const tnoodleApi = require("../main/api/tnoodle.api");
const wcaApi = require("../main/api/wca.api");

Expand Down Expand Up @@ -45,6 +43,7 @@ it("Current version is the correct one", async () => {
"https://www.worldcubeassociation.org/regulations/scrambles/tnoodle/TNoodle-WCA-2.jar",
},
allowed: ["TNoodle-WCA-2"],
publicKeyBytes: "key",
history: ["TNoodle-WCA-0", "TNoodle-WCA-1", "TNoodle-WCA-2"],
};

Expand Down Expand Up @@ -93,6 +92,7 @@ it("Current version is allowed, but it's not the latest one", async () => {
"https://www.worldcubeassociation.org/regulations/scrambles/tnoodle/TNoodle-WCA-3.jar",
},
allowed: ["TNoodle-WCA-2", "TNoodle-WCA-3"],
publicKeyBytes: "key",
history: [
"TNoodle-WCA-0",
"TNoodle-WCA-1",
Expand Down Expand Up @@ -120,9 +120,7 @@ it("Current version is allowed, but it's not the latest one", async () => {

// The warning should be "your version is ok, but please upgrade"
const alert = container.querySelector(".alert-info");
expect(alert.textContent).toContain(
"which is still allowed, but you should upgrade to"
);
expect(alert.textContent).toContain("which is still allowed, but you should upgrade to");

const downloadLink = container.querySelector("a").href;
expect(downloadLink).toBe(scrambleProgram.current.download);
Expand All @@ -131,7 +129,7 @@ it("Current version is allowed, but it's not the latest one", async () => {
wcaApi.fetchVersionInfo.mockRestore();
});

it("Not official version alert", async () => {
it("Not signed version alert", async () => {
const version = {
projectName: "TNoodle-WCA",
projectVersion: "3",
Expand All @@ -148,6 +146,7 @@ it("Not official version alert", async () => {
"https://www.worldcubeassociation.org/regulations/scrambles/tnoodle/TNoodle-WCA-3.jar",
},
allowed: ["TNoodle-WCA-3"],
publicKeyBytes: "key",
history: [
"TNoodle-WCA-0",
"TNoodle-WCA-1",
Expand Down Expand Up @@ -175,10 +174,59 @@ it("Not official version alert", async () => {

// The warning should be "do not use this"
const alert = container.querySelector(".alert-danger");
expect(alert.textContent).toContain(
"This TNoodle version is not official and scrambles generated with this must not be used in competition."
expect(alert.textContent).toContain("You are running an unsigned TNoodle release.");

tnoodleApi.fetchRunningVersion.mockRestore();
wcaApi.fetchVersionInfo.mockRestore();
});

it("Signed with different key", async () => {
const version = {
projectName: "TNoodle-WCA",
projectVersion: "3",
signedBuild: true,
signatureKeyBytes: "fooBar", // This should trigger an alert, even with currentVersion == runningVersion
};

const scrambleProgram = {
current: {
name: "TNoodle-WCA-3",
information:
"https://www.worldcubeassociation.org/regulations/scrambles/",
download:
"https://www.worldcubeassociation.org/regulations/scrambles/tnoodle/TNoodle-WCA-3.jar",
},
allowed: ["TNoodle-WCA-3"],
publicKeyBytes: "key",
history: [
"TNoodle-WCA-0",
"TNoodle-WCA-1",
"TNoodle-WCA-2",
"TNoodle-WCA-3",
],
};

jest.spyOn(tnoodleApi, "fetchRunningVersion").mockImplementation(() =>
Promise.resolve(version)
);

jest.spyOn(wcaApi, "fetchVersionInfo").mockImplementation(() =>
Promise.resolve(scrambleProgram)
);

await act(async () => {
render(
<Provider store={store}>
<VersionInfo />
</Provider>,
container
);
});

// The warning should be "do not use this"
const alert = container.querySelector(".alert-danger");
expect(alert.textContent).toContain("You are running an unsigned TNoodle release.");

tnoodleApi.fetchRunningVersion.mockRestore();
wcaApi.fetchVersionInfo.mockRestore();
});
Expand All @@ -200,6 +248,7 @@ it("Not allowed TNoodle version, despite it's official", async () => {
"https://www.worldcubeassociation.org/regulations/scrambles/tnoodle/TNoodle-WCA-3.jar",
},
allowed: ["TNoodle-WCA-2", "TNoodle-WCA-3"],
publicKeyBytes: "key",
history: [
"TNoodle-WCA-0",
"TNoodle-WCA-1",
Expand Down Expand Up @@ -227,7 +276,7 @@ it("Not allowed TNoodle version, despite it's official", async () => {

// The warning should be "do not use this"
const alert = container.querySelector(".alert-danger");
expect(alert.textContent).toContain("This TNoodle version is not allowed.");
expect(alert.textContent).toContain("which is not allowed.");

tnoodleApi.fetchRunningVersion.mockRestore();
wcaApi.fetchVersionInfo.mockRestore();
Expand All @@ -245,6 +294,7 @@ it("Do not bother the user if we can't be sure", async () => {
"https://www.worldcubeassociation.org/regulations/scrambles/tnoodle/TNoodle-WCA-3.jar",
},
allowed: ["TNoodle-WCA-2", "TNoodle-WCA-3"],
publicKeyBytes: "key",
history: [
"TNoodle-WCA-0",
"TNoodle-WCA-1",
Expand Down
1 change: 1 addition & 0 deletions tnoodle-ui/src/test/mock/wca.api.mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const scrambleProgram = {
"https://www.worldcubeassociation.org/regulations/scrambles/tnoodle/TNoodle-WCA-2.jar",
},
allowed: ["TNoodle-WCA-2"],
publicKeyBytes: "key",
history: ["TNoodle-WCA-0", "TNoodle-WCA-1", "TNoodle-WCA-2"],
};

Expand Down

0 comments on commit 712222f

Please sign in to comment.