Skip to content

Java upload tab #2945

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 29 commits into from
May 12, 2024
Merged

Java upload tab #2945

merged 29 commits into from
May 12, 2024

Conversation

Chang-CH
Copy link
Contributor

@Chang-CH Chang-CH commented Apr 16, 2024

Description

Allows users to bypass compiler + type checker in local development by uploading class files to run directly.

Supports multiple file uploads.

image

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update
  • Code quality improvements

How to test

Compile java file(s) with javac *.java -target 8 -source 8 and upload

Checklist

  • I have tested this code
  • I have updated the documentation

@coveralls
Copy link

coveralls commented Apr 16, 2024

Pull Request Test Coverage Report for Build 9049753998

Details

  • 10 of 64 (15.63%) changed or added relevant lines in 8 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage decreased (-0.05%) to 32.062%

Changes Missing Coverage Covered Lines Changed/Added Lines %
src/pages/playground/Playground.tsx 1 2 50.0%
src/commons/workspace/WorkspaceActions.ts 2 4 50.0%
src/commons/sagas/PlaygroundSaga.ts 0 3 0.0%
src/commons/workspace/WorkspaceReducer.ts 0 6 0.0%
src/commons/sideContent/content/SideContentUpload.tsx 2 21 9.52%
src/commons/utils/JavaHelper.ts 0 23 0.0%
Totals Coverage Status
Change from base Build 8971907944: -0.05%
Covered Lines: 5021
Relevant Lines: 14700

💛 - Coveralls

Copy link
Member

@RichDom2185 RichDom2185 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this be safe (considering one can upload any file)? Any potential social engineering attack vector? Is it possible to access the JS environment from Java (and e.g. steal browser cookies)?

@Chang-CH
Copy link
Contributor Author

Will this be safe (considering one can upload any file)? Any potential social engineering attack vector? Is it possible to access the JS environment from Java (and e.g. steal browser cookies)?

At the moment most of the standard library is not yet implemented, there are no native functions that access network.

Ideally we only need the run tab, but due to the limitations of the type checker and compiler this was requested as a feature.

@martin-henz
Copy link
Member

Yes, maybe this feature should only be available in the command line tool and not in sourceacademy.org? I agree that for now it's ok. Maybe we include it for the project presentation next week and then remove it?

@Chang-CH
Copy link
Contributor Author

Yes, maybe this feature should only be available in the command line tool and not in sourceacademy.org? I agree that for now it's ok. Maybe we include it for the project presentation next week and then remove it?

I am planning to use localhost for presentation. I think mei tin is using the localhost approach as well. Is there a way we only enable it for dev and not production? do we have feature flags?

@RichDom2185
Copy link
Member

Is there a way we only enable it for dev and not production?

Not sure, does process.env.NODE_ENV work?

do we have feature flags?

No we don't (at least not yet for now…)

@Chang-CH
Copy link
Contributor Author

Is there a way we only enable it for dev and not production?

Not sure, does process.env.NODE_ENV work?

looks like it does, added the check.

@Chang-CH Chang-CH marked this pull request as ready for review April 18, 2024 14:18
Copy link
Member

@RichDom2185 RichDom2185 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, thanks for working on this! I have some comments below:

Comment on lines 26 to 71
class SideContentUpload extends React.Component<OwnProps> {
public render() {
return (
<div>
<p>
Bypass the compiler and type checker by uploading class files to run in the JVM.
<br />
<br />
Only .class files are accepted. Code in the editor will be ignored when running while this
tab is active.
<br />
<br />
Compile the files with the following command:
<code>javac *.java -target 8 -source 8</code>
<br />
<br />
Avoid running class files downloaded from unknown sources.
<br />
<br />
<strong>Main class must be named Main and uploaded as Main.class.</strong>
</p>
<input
type="file"
multiple
accept=".class"
onChange={e => {
const ret: { [key: string]: string } = {};
const promises = [];
for (const file of e.target.files ?? []) {
if (file.name.endsWith('.class')) {
promises.push(
getBase64(file, (b64: string) => {
ret[file.name] = b64;
})
);
}
}
Promise.all(promises).then(() => {
this.props.onUpload(ret);
});
}}
/>
</div>
);
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are trying to move away from React component classes into functional components instead. Could you refactor this?

Comment on lines 30 to 46
<p>
Bypass the compiler and type checker by uploading class files to run in the JVM.
<br />
<br />
Only .class files are accepted. Code in the editor will be ignored when running while this
tab is active.
<br />
<br />
Compile the files with the following command:
<code>javac *.java -target 8 -source 8</code>
<br />
<br />
Avoid running class files downloaded from unknown sources.
<br />
<br />
<strong>Main class must be named Main and uploaded as Main.class.</strong>
</p>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Semantically, does it make sense to have everything in a single paragraph with so many line breaks, instead of multiple p/pre tags?

multiple
accept=".class"
onChange={e => {
const ret: { [key: string]: string } = {};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type to represent a file is used a lot. Can we move this to a type alias to ensure single source of truth?


const makeUploadTabFrom = (
location: SideContentLocation,
onUpload: (files: { [key: string]: any }) => void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or perhaps this type could be aliased instead (or both).

@@ -106,7 +91,34 @@ export async function javaRun(
}
};

if (isUsingCse) return await runJavaCseMachine(javaCode, targetStep, context);
// #endregion
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove this comment?

Comment on lines 848 to 854
const { workspaceLocation } = action.payload;
if (workspaceLocation === 'playground' || workspaceLocation === 'sicp') {
state[workspaceLocation].usingUpload = action.payload.usingUpload;
}
})
.addCase(uploadFiles, (state, action) => {
const { workspaceLocation } = action.payload;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

workspaceLocation should not be accessed via destructuring of action.payload. Refer to the other functions for how (i.e. getWorkspaceLocation).

@Chang-CH Chang-CH requested a review from RichDom2185 April 21, 2024 01:53
* Memoize change handler
* Fix layout and UI bugs
* Use Blueprint file input instead of HTML input component
Copy link
Member

@RichDom2185 RichDom2185 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I've fixed some of the bugs and typings as per my above comments but I still have some comments below:

Also, could you resolve the merge conflicts?

Thanks!

/**
* This component is responsible for uploading Java class files to bypass the compiler.
*/
const SideContentUpload: React.FC<Props> = ({ onUpload, workspaceLocation }) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workspaceLocation prop is not used. Is this intentional?

Comment on lines 67 to 70
<FileInput
inputProps={{ multiple: true, accept: '.class' }}
onInputChange={handleFileUpload}
/>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we keep track of the state by updating the text prop? See https://blueprintjs.com/docs/#core/components/file-input

Copy link
Contributor Author

@Chang-CH Chang-CH Apr 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not quite sure what you mean by this. Do we want to show some kind of text to indicate what files are uploaded like "4 files uploaded"?

Added this change, if that is what you meant.

Copy link
Member

@RichDom2185 RichDom2185 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks and sorry for the delayed review!

@RichDom2185 RichDom2185 enabled auto-merge (squash) May 12, 2024 07:25
@RichDom2185 RichDom2185 disabled auto-merge May 12, 2024 07:27
@RichDom2185 RichDom2185 enabled auto-merge (squash) May 12, 2024 07:28
@RichDom2185 RichDom2185 merged commit bbe8abe into master May 12, 2024
8 checks passed
@RichDom2185 RichDom2185 deleted the java-jvm-tab branch May 12, 2024 07:34
chownces pushed a commit that referenced this pull request May 12, 2024
* add class file upload tab

* unused code param

* fix imports

* update reducer pattern

* update upload text

* fix: tsc missing properties

* disable upload tab on prod

* fix comments

* Fix component typing

* Fix incorrect workspace location in reducer

* Refactor SideContentUpload component

* Memoize change handler
* Fix layout and UI bugs
* Use Blueprint file input instead of HTML input component

* Fix typing

* remove location prop

* Show upload count

* Fix format

* Improve typing

* Update typing

---------

Co-authored-by: Richard Dominick <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants