From e271d1682d0a519cc07940ba3a811a827488d552 Mon Sep 17 00:00:00 2001 From: Tian Na Date: Fri, 10 Nov 2023 15:09:15 +0800 Subject: [PATCH 1/3] Add checking the uss file path when upload file or stdin to uss file. Signed-off-by: Tian Na --- CHANGELOG.md | 4 +++ .../FileToUssFile.Handler.test.ts | 21 ++++++++++++ .../StdinToUssFile.Handler.test.ts | 20 ++++++++++++ .../file-to-uss-file/FileToUssFile.Handler.ts | 24 ++++++++------ .../StdinToUssFile.Handler.ts | 32 +++++++++++-------- 5 files changed, 79 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afd655ac..1fa6c3ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to the z/OS FTP Plug-in for Zowe CLI will be documented in this file. +## Recent Changes + +- Add checking the uss file path when upload file or stdin to uss file. + ## `2.1.4` - BugFix: Provide new utility function that checks file names for valid characters [143](https://github.com/zowe/zowe-cli-ftp-plugin/issues/143). diff --git a/__tests__/__unit__/cli/upload/file-to-uss-file/FileToUssFile.Handler.test.ts b/__tests__/__unit__/cli/upload/file-to-uss-file/FileToUssFile.Handler.test.ts index 547b17b7..be0a70f7 100644 --- a/__tests__/__unit__/cli/upload/file-to-uss-file/FileToUssFile.Handler.test.ts +++ b/__tests__/__unit__/cli/upload/file-to-uss-file/FileToUssFile.Handler.test.ts @@ -39,4 +39,25 @@ describe("Upload file to data set handler", () => { expect(mockResponse.console.log.mock.calls[0][2]).toBe("/u/user/ussfile1"); }); + it("should return error if the uss file path is not a full path.", async () => { + const handler = new UploadFileToUssFileHandler(); + + IO.readFileSync = jest.fn().mockReturnValue(Promise.resolve(Buffer.from("sss"))); + // UssUtils.normalizeUnixPath = + CoreUtils.addCarriageReturns = jest.fn().mockReturnValue(("sss")); + const mockResponse = TestUtils.getMockResponse(); + const mockParams: any = { + arguments: { + file: "/u/user/file1", + ussFile: "ussfile1" + }, + connection: { + uploadDataset: jest.fn().mockReturnValue(Promise.resolve("")) + }, + response: mockResponse + }; + await handler.processFTP(mockParams); + expect(mockResponse.console.log.mock.calls[0][0]).toBe("Please check the uss file path. The full file path is required."); + }); + }); diff --git a/__tests__/__unit__/cli/upload/stdin-to-uss-file/StdinToUssFile.Handler.test.ts b/__tests__/__unit__/cli/upload/stdin-to-uss-file/StdinToUssFile.Handler.test.ts index 09a87630..82d15ea1 100644 --- a/__tests__/__unit__/cli/upload/stdin-to-uss-file/StdinToUssFile.Handler.test.ts +++ b/__tests__/__unit__/cli/upload/stdin-to-uss-file/StdinToUssFile.Handler.test.ts @@ -37,4 +37,24 @@ describe("Upload file to data set handler", () => { expect(mockResponse.console.log.mock.calls[0][2]).toBe("/u/user/ussfile1"); }); + it("should return error if the uss file path is not a full path.", async () => { + const handler = new UploadStdinToUssFileHandler(); + + CoreUtils.readStdin = jest.fn().mockReturnValue(Promise.resolve(Buffer.from("sss"))); + CoreUtils.addCarriageReturns = jest.fn().mockReturnValue(("sss")); + const mockResponse = TestUtils.getMockResponse(); + const mockParams: any = { + arguments: { + file: "/u/user/file1", + ussFile: "ussfile1" + }, + connection: { + uploadDataset: jest.fn().mockReturnValue(Promise.resolve("")) + }, + response: mockResponse + }; + await handler.processFTP(mockParams); + expect(mockResponse.console.log.mock.calls[0][0]).toBe("Please check the uss file path. The full file path is required."); + }); + }); diff --git a/src/cli/upload/file-to-uss-file/FileToUssFile.Handler.ts b/src/cli/upload/file-to-uss-file/FileToUssFile.Handler.ts index 2f83650f..1483ff72 100644 --- a/src/cli/upload/file-to-uss-file/FileToUssFile.Handler.ts +++ b/src/cli/upload/file-to-uss-file/FileToUssFile.Handler.ts @@ -17,16 +17,22 @@ export default class UploadFileToUssFileHandler extends FTPBaseHandler { public async processFTP(params: IFTPHandlerParams): Promise { const ussFile = UssUtils.normalizeUnixPath(params.arguments.ussFile); - const options = { - localFile: params.arguments.file, - transferType: params.arguments.binary ? TRANSFER_TYPE_BINARY : TRANSFER_TYPE_ASCII, - }; - await UssUtils.uploadFile(params.connection, ussFile, options); + if (!ussFile.startsWith('/')) { + const errMsg = params.response.console.log("Please check the uss file path. The full file path is required."); + params.response.data.setMessage(errMsg); + this.log.info(errMsg); + } else { + const options = { + localFile: params.arguments.file, + transferType: params.arguments.binary ? TRANSFER_TYPE_BINARY : TRANSFER_TYPE_ASCII, + }; + await UssUtils.uploadFile(params.connection, ussFile, options); - const uploadSource: string = "local file '" + params.arguments.file + "'"; - const successMsg = params.response.console.log("Uploaded from %s to %s ", uploadSource, ussFile); - params.response.data.setMessage(successMsg); - this.log.info(successMsg); + const uploadSource: string = "local file '" + params.arguments.file + "'"; + const successMsg = params.response.console.log("Uploaded from %s to %s ", uploadSource, ussFile); + params.response.data.setMessage(successMsg); + this.log.info(successMsg); + } } } diff --git a/src/cli/upload/stdin-to-uss-file/StdinToUssFile.Handler.ts b/src/cli/upload/stdin-to-uss-file/StdinToUssFile.Handler.ts index 942cd23e..eb63ea48 100644 --- a/src/cli/upload/stdin-to-uss-file/StdinToUssFile.Handler.ts +++ b/src/cli/upload/stdin-to-uss-file/StdinToUssFile.Handler.ts @@ -18,19 +18,25 @@ export default class UploadStdinToUssFileHandler extends FTPBaseHandler { public async processFTP(params: IFTPHandlerParams): Promise { const ussFile = UssUtils.normalizeUnixPath(params.arguments.ussFile); - const content: Buffer | string = await CoreUtils.readStdin(params.stdin); - - const options = { - content, - transferType: params.arguments.binary ? TRANSFER_TYPE_BINARY : TRANSFER_TYPE_ASCII, - }; - await UssUtils.uploadFile(params.connection, ussFile, options); - - const uploadSource: string = "stdin"; - const successMsg = params.response.console.log("Uploaded from %s to %s ", uploadSource, ussFile); - params.response.data.setMessage(successMsg); - this.log.info(successMsg); - + if (!ussFile.startsWith('/')) { + const errMsg = params.response.console.log("Please check the uss file path. The full file path is required."); + params.response.data.setMessage(errMsg); + this.log.info(errMsg); + } else { + const content: Buffer | string = await CoreUtils.readStdin(params.stdin); + + const options = { + content, + transferType: params.arguments.binary ? TRANSFER_TYPE_BINARY : TRANSFER_TYPE_ASCII, + }; + await UssUtils.uploadFile(params.connection, ussFile, options); + + const uploadSource: string = "stdin"; + const successMsg = params.response.console.log("Uploaded from %s to %s ", uploadSource, ussFile); + params.response.data.setMessage(successMsg); + this.log.info(successMsg); + + } } } From 10bf0ac01d43d4775cb1a3d23556a5a7698114f8 Mon Sep 17 00:00:00 2001 From: Tian Na Date: Fri, 10 Nov 2023 16:54:16 +0800 Subject: [PATCH 2/3] add checkAbsoluteFilePath in UssUtils Signed-off-by: Tian Na --- __tests__/__unit__/api/UssUtils.test.ts | 9 +++++ .../FileToUssFile.Handler.test.ts | 22 ------------- .../StdinToUssFile.Handler.test.ts | 21 ------------ src/api/UssUtils.ts | 10 +++++- .../file-to-uss-file/FileToUssFile.Handler.ts | 25 ++++++-------- .../StdinToUssFile.Handler.ts | 33 ++++++++----------- 6 files changed, 42 insertions(+), 78 deletions(-) diff --git a/__tests__/__unit__/api/UssUtils.test.ts b/__tests__/__unit__/api/UssUtils.test.ts index b607067d..3d378003 100644 --- a/__tests__/__unit__/api/UssUtils.test.ts +++ b/__tests__/__unit__/api/UssUtils.test.ts @@ -9,6 +9,7 @@ * */ +import { ImperativeError } from "@zowe/imperative"; import { UssUtils } from "../../../src/api/UssUtils"; describe("UssUtils", () => { @@ -28,4 +29,12 @@ describe("UssUtils", () => { path = UssUtils.normalizeUnixPath("//home/user1/hello.text"); expect(path).toBe("/home/user1/hello.text"); }); + + it("should throw error when the uss file path is not absolute file Path", () => { + const path = "test.txt"; + const result = () => { + UssUtils.checkAbsoluteFilePath(path); + }; + expect(result).toThrow(ImperativeError); + }); }); diff --git a/__tests__/__unit__/cli/upload/file-to-uss-file/FileToUssFile.Handler.test.ts b/__tests__/__unit__/cli/upload/file-to-uss-file/FileToUssFile.Handler.test.ts index be0a70f7..e745c75a 100644 --- a/__tests__/__unit__/cli/upload/file-to-uss-file/FileToUssFile.Handler.test.ts +++ b/__tests__/__unit__/cli/upload/file-to-uss-file/FileToUssFile.Handler.test.ts @@ -38,26 +38,4 @@ describe("Upload file to data set handler", () => { expect(mockResponse.console.log.mock.calls[0][1]).toBe("local file '/u/user/file1'"); expect(mockResponse.console.log.mock.calls[0][2]).toBe("/u/user/ussfile1"); }); - - it("should return error if the uss file path is not a full path.", async () => { - const handler = new UploadFileToUssFileHandler(); - - IO.readFileSync = jest.fn().mockReturnValue(Promise.resolve(Buffer.from("sss"))); - // UssUtils.normalizeUnixPath = - CoreUtils.addCarriageReturns = jest.fn().mockReturnValue(("sss")); - const mockResponse = TestUtils.getMockResponse(); - const mockParams: any = { - arguments: { - file: "/u/user/file1", - ussFile: "ussfile1" - }, - connection: { - uploadDataset: jest.fn().mockReturnValue(Promise.resolve("")) - }, - response: mockResponse - }; - await handler.processFTP(mockParams); - expect(mockResponse.console.log.mock.calls[0][0]).toBe("Please check the uss file path. The full file path is required."); - }); - }); diff --git a/__tests__/__unit__/cli/upload/stdin-to-uss-file/StdinToUssFile.Handler.test.ts b/__tests__/__unit__/cli/upload/stdin-to-uss-file/StdinToUssFile.Handler.test.ts index 82d15ea1..bb39b238 100644 --- a/__tests__/__unit__/cli/upload/stdin-to-uss-file/StdinToUssFile.Handler.test.ts +++ b/__tests__/__unit__/cli/upload/stdin-to-uss-file/StdinToUssFile.Handler.test.ts @@ -36,25 +36,4 @@ describe("Upload file to data set handler", () => { expect(mockResponse.console.log.mock.calls[0][1]).toBe("stdin"); expect(mockResponse.console.log.mock.calls[0][2]).toBe("/u/user/ussfile1"); }); - - it("should return error if the uss file path is not a full path.", async () => { - const handler = new UploadStdinToUssFileHandler(); - - CoreUtils.readStdin = jest.fn().mockReturnValue(Promise.resolve(Buffer.from("sss"))); - CoreUtils.addCarriageReturns = jest.fn().mockReturnValue(("sss")); - const mockResponse = TestUtils.getMockResponse(); - const mockParams: any = { - arguments: { - file: "/u/user/file1", - ussFile: "ussfile1" - }, - connection: { - uploadDataset: jest.fn().mockReturnValue(Promise.resolve("")) - }, - response: mockResponse - }; - await handler.processFTP(mockParams); - expect(mockResponse.console.log.mock.calls[0][0]).toBe("Please check the uss file path. The full file path is required."); - }); - }); diff --git a/src/api/UssUtils.ts b/src/api/UssUtils.ts index a56552a3..4a70ffb5 100644 --- a/src/api/UssUtils.ts +++ b/src/api/UssUtils.ts @@ -12,7 +12,7 @@ import * as PATH from "path"; import * as fs from "fs"; -import { IHandlerResponseConsoleApi, IO, Logger } from "@zowe/imperative"; +import { IHandlerResponseConsoleApi, IO, ImperativeError, Logger } from "@zowe/imperative"; import { CoreUtils, TRANSFER_TYPE_ASCII } from "./CoreUtils"; import { StreamUtils } from "./StreamUtils"; import { IDeleteFileOption, IDownloadFileOption, IUploadFileOption } from "./UssInterface"; @@ -201,6 +201,14 @@ export class UssUtils { } } + public static checkAbsoluteFilePath(filePath: string) { + if (!filePath.startsWith('/')) { + throw new ImperativeError({ msg: "Please check the uss file path. The full file path is required."}); + } else { + return filePath; + } + } + private static get log(): Logger { return Logger.getAppLogger(); } diff --git a/src/cli/upload/file-to-uss-file/FileToUssFile.Handler.ts b/src/cli/upload/file-to-uss-file/FileToUssFile.Handler.ts index 1483ff72..b263532c 100644 --- a/src/cli/upload/file-to-uss-file/FileToUssFile.Handler.ts +++ b/src/cli/upload/file-to-uss-file/FileToUssFile.Handler.ts @@ -17,22 +17,17 @@ export default class UploadFileToUssFileHandler extends FTPBaseHandler { public async processFTP(params: IFTPHandlerParams): Promise { const ussFile = UssUtils.normalizeUnixPath(params.arguments.ussFile); - if (!ussFile.startsWith('/')) { - const errMsg = params.response.console.log("Please check the uss file path. The full file path is required."); - params.response.data.setMessage(errMsg); - this.log.info(errMsg); - } else { - const options = { - localFile: params.arguments.file, - transferType: params.arguments.binary ? TRANSFER_TYPE_BINARY : TRANSFER_TYPE_ASCII, - }; - await UssUtils.uploadFile(params.connection, ussFile, options); + UssUtils.checkAbsoluteFilePath(ussFile); + const options = { + localFile: params.arguments.file, + transferType: params.arguments.binary ? TRANSFER_TYPE_BINARY : TRANSFER_TYPE_ASCII, + }; + await UssUtils.uploadFile(params.connection, ussFile, options); - const uploadSource: string = "local file '" + params.arguments.file + "'"; - const successMsg = params.response.console.log("Uploaded from %s to %s ", uploadSource, ussFile); - params.response.data.setMessage(successMsg); - this.log.info(successMsg); - } + const uploadSource: string = "local file '" + params.arguments.file + "'"; + const successMsg = params.response.console.log("Uploaded from %s to %s ", uploadSource, ussFile); + params.response.data.setMessage(successMsg); + this.log.info(successMsg); } } diff --git a/src/cli/upload/stdin-to-uss-file/StdinToUssFile.Handler.ts b/src/cli/upload/stdin-to-uss-file/StdinToUssFile.Handler.ts index eb63ea48..11c4c522 100644 --- a/src/cli/upload/stdin-to-uss-file/StdinToUssFile.Handler.ts +++ b/src/cli/upload/stdin-to-uss-file/StdinToUssFile.Handler.ts @@ -18,25 +18,20 @@ export default class UploadStdinToUssFileHandler extends FTPBaseHandler { public async processFTP(params: IFTPHandlerParams): Promise { const ussFile = UssUtils.normalizeUnixPath(params.arguments.ussFile); - if (!ussFile.startsWith('/')) { - const errMsg = params.response.console.log("Please check the uss file path. The full file path is required."); - params.response.data.setMessage(errMsg); - this.log.info(errMsg); - } else { - const content: Buffer | string = await CoreUtils.readStdin(params.stdin); - - const options = { - content, - transferType: params.arguments.binary ? TRANSFER_TYPE_BINARY : TRANSFER_TYPE_ASCII, - }; - await UssUtils.uploadFile(params.connection, ussFile, options); - - const uploadSource: string = "stdin"; - const successMsg = params.response.console.log("Uploaded from %s to %s ", uploadSource, ussFile); - params.response.data.setMessage(successMsg); - this.log.info(successMsg); - - } + UssUtils.checkAbsoluteFilePath(ussFile); + const content: Buffer | string = await CoreUtils.readStdin(params.stdin); + + const options = { + content, + transferType: params.arguments.binary ? TRANSFER_TYPE_BINARY : TRANSFER_TYPE_ASCII, + }; + await UssUtils.uploadFile(params.connection, ussFile, options); + + const uploadSource: string = "stdin"; + const successMsg = params.response.console.log("Uploaded from %s to %s ", uploadSource, ussFile); + params.response.data.setMessage(successMsg); + this.log.info(successMsg); } + } From c230fe24cae1025a72f8ad57dde76a647a03e4e8 Mon Sep 17 00:00:00 2001 From: Tian Na Date: Tue, 14 Nov 2023 14:13:36 +0800 Subject: [PATCH 3/3] update @zowe/cli-test-utils to 7.18.11 Signed-off-by: Tian Na --- npm-shrinkwrap.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index eabed1f2..69fa478f 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -20,7 +20,7 @@ "@typescript-eslint/eslint-plugin": "^5.33.0", "@typescript-eslint/parser": "^5.33.0", "@zowe/cli": "^7.18.8", - "@zowe/cli-test-utils": "^7.18.7", + "@zowe/cli-test-utils": "^7.18.11", "@zowe/imperative": "^5.18.3", "chalk": "^2.3.0", "env-cmd": "^10.1.0", @@ -2469,9 +2469,9 @@ } }, "node_modules/@zowe/cli-test-utils": { - "version": "7.18.7", - "resolved": "https://zowe.jfrog.io/zowe/api/npm/npm-release/@zowe/cli-test-utils/-/@zowe/cli-test-utils-7.18.7.tgz", - "integrity": "sha512-1o4nNi7r/rrGngEomGdEVfMRDKdVzEki4M4wEgJCfraCeIG8vr/3INaWUHJX5vjpEIp+yvHH4NN+wSkNzQ7OQw==", + "version": "7.18.11", + "resolved": "https://zowe.jfrog.io/zowe/api/npm/npm-release/@zowe/cli-test-utils/-/@zowe/cli-test-utils-7.18.11.tgz", + "integrity": "sha512-uaCd+u2vYKonN47wRNseX8YQypjfaCO1+q3DXPkatXPWuAPuUOxpDKmPWq42fXdzKJoBdycmarKe4SwkbjEsvw==", "dev": true, "dependencies": { "find-up": "^5.0.0", @@ -15351,9 +15351,9 @@ } }, "@zowe/cli-test-utils": { - "version": "7.18.7", - "resolved": "https://zowe.jfrog.io/zowe/api/npm/npm-release/@zowe/cli-test-utils/-/@zowe/cli-test-utils-7.18.7.tgz", - "integrity": "sha512-1o4nNi7r/rrGngEomGdEVfMRDKdVzEki4M4wEgJCfraCeIG8vr/3INaWUHJX5vjpEIp+yvHH4NN+wSkNzQ7OQw==", + "version": "7.18.11", + "resolved": "https://zowe.jfrog.io/zowe/api/npm/npm-release/@zowe/cli-test-utils/-/@zowe/cli-test-utils-7.18.11.tgz", + "integrity": "sha512-uaCd+u2vYKonN47wRNseX8YQypjfaCO1+q3DXPkatXPWuAPuUOxpDKmPWq42fXdzKJoBdycmarKe4SwkbjEsvw==", "dev": true, "requires": { "find-up": "^5.0.0", diff --git a/package.json b/package.json index cf330a57..97ccd94d 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "@typescript-eslint/eslint-plugin": "^5.33.0", "@typescript-eslint/parser": "^5.33.0", "@zowe/cli": "^7.18.8", - "@zowe/cli-test-utils": "^7.18.7", + "@zowe/cli-test-utils": "^7.18.11", "@zowe/imperative": "^5.18.3", "chalk": "^2.3.0", "env-cmd": "^10.1.0",