-
Notifications
You must be signed in to change notification settings - Fork 3
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
Limiting file size #105
Merged
Merged
Limiting file size #105
Changes from 7 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
3264397
Making the inital commit
SoujitD-SAP f342e8f
Added handler for validating size and unit test file.
SoujitD-SAP 7402a98
Update plugin.js
SoujitD-SAP dad007d
Merge branch 'main' into LimitFileSize
SoujitD-SAP c02e2dd
Updated CHANGELOG.md and plugin.js
SoujitD-SAP c14f396
Update package.json, changelog, and plugin.js
SoujitD-SAP bd33a5b
Merge branch 'main' into LimitFileSize
SoujitD-SAP 44f91a3
Update CHANGELOG.md with UI5 version update
SoujitD-SAP 6dfe6ce
Update CHANGELOG.md with UI5 version update
SoujitD-SAP e5545dc
Merge branch 'main' into LimitFileSize
jeevitha011 3655497
Formatted plugin.js
SoujitD-SAP e8a2c33
Formatted plugin.js
SoujitD-SAP File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,7 @@ const attachmentIDRegex = /\/\w+\(.*ID=([0-9a-fA-F-]{36})/; | |
|
||
cds.on("loaded", function unfoldModel(csn) { | ||
if (!("Attachments" in csn.definitions)) return; | ||
const csnCopy = structuredClone(csn) | ||
const csnCopy = structuredClone(csn); | ||
cds.linked(csnCopy).forall("Composition", (comp) => { | ||
if (comp._target && comp._target["@_is_media_data"] && comp.parent && comp.is2many) { | ||
const parentDefinition = comp.parent.name | ||
|
@@ -31,24 +31,28 @@ cds.once("served", async function registerPluginHandlers() { | |
for (let srv of cds.services) { | ||
if (srv instanceof cds.ApplicationService) { | ||
Object.values(srv.entities).forEach((entity) => { | ||
|
||
for (let elementName in entity.elements) { | ||
if (elementName === "SiblingEntity") continue; // REVISIT: Why do we have this? | ||
const element = entity.elements[elementName], target = element._target; | ||
const element = entity.elements[elementName], | ||
target = element._target; | ||
if (target?.["@_is_media_data"] && target?.drafts) { | ||
DEBUG?.("serving attachments for:", target.name); | ||
|
||
srv.before("READ", [target, target.drafts], validateAttachment); | ||
|
||
srv.after("READ", [target, target.drafts], readAttachment); | ||
|
||
srv.before("PUT", target.drafts, (req) => validateAttachmentSize(req) ); | ||
|
||
|
||
AttachmentsSrv.registerUpdateHandlers(srv, entity, target); | ||
srv.before('NEW', target.drafts, req => { | ||
|
||
srv.before("NEW", target.drafts, (req) => { | ||
req.data.url = cds.utils.uuid(); | ||
req.data.ID = cds.utils.uuid(); | ||
let ext = extname(req.data.filename).toLowerCase().slice(1); | ||
req.data.mimeType = Ext2MimeTyes[ext] || "application/octet-stream"; | ||
req.data.mimeType = | ||
Ext2MimeTyes[ext] || "application/octet-stream"; | ||
}); | ||
} | ||
} | ||
|
@@ -57,34 +61,53 @@ cds.once("served", async function registerPluginHandlers() { | |
} | ||
|
||
async function validateAttachment(req) { | ||
|
||
/* removing case condition for mediaType annotation as in our case binary value and metadata is stored in different database */ | ||
|
||
req?.query?.SELECT?.columns?.forEach((element) => { | ||
if(element.as === '[email protected]' && element.xpr){ | ||
if (element.as === "[email protected]" && element.xpr) { | ||
delete element.xpr; | ||
element.ref = ['mimeType']; | ||
element.ref = ["mimeType"]; | ||
} | ||
}); | ||
|
||
if(req?.req?.url?.endsWith("/content")) { | ||
if (req?.req?.url?.endsWith("/content")) { | ||
const attachmentID = req.req.url.match(attachmentIDRegex)[1]; | ||
const status = await AttachmentsSrv.getStatus(req.target, { ID : attachmentID }); | ||
const scanEnabled = cds.env.requires?.attachments?.scan ?? true | ||
if(scanEnabled && status !== 'Clean') { | ||
req.reject(403, 'Unable to download the attachment as scan status is not clean.'); | ||
const status = await AttachmentsSrv.getStatus(req.target, {ID: attachmentID,}); | ||
const scanEnabled = cds.env.requires?.attachments?.scan ?? true; | ||
if (scanEnabled && status !== "Clean") { | ||
req.reject( | ||
403, | ||
"Unable to download the attachment as scan status is not clean." | ||
); | ||
} | ||
} | ||
} | ||
|
||
async function readAttachment([attachment], req) { | ||
if (!req?.req?.url?.endsWith("/content") || !attachment || attachment?.content) return; | ||
let keys = { ID : req.req.url.match(attachmentIDRegex)[1]}; | ||
if (!req?.req?.url?.endsWith("/content") ||!attachment ||attachment?.content) return; | ||
let keys = { ID: req.req.url.match(attachmentIDRegex)[1] }; | ||
let { target } = req; | ||
attachment.content = await AttachmentsSrv.get(target, keys, req); //Dependency -> sending req object for usage in SDM plugin | ||
} | ||
}); | ||
|
||
function validateAttachmentSize(req) { | ||
const contentLengthHeader = req.headers["content-length"]; | ||
let fileSizeInBytes; | ||
|
||
if (contentLengthHeader) { | ||
fileSizeInBytes = Number(contentLengthHeader); | ||
const MAX_FILE_SIZE = 419430400; //400 MB in bytes | ||
if (fileSizeInBytes > MAX_FILE_SIZE) { | ||
return req.reject(403, "File Size limit exceeded beyond 400 MB."); | ||
} | ||
} else { | ||
return req.reject(403, "Invalid Content Size"); | ||
} | ||
} | ||
|
||
module.exports = { validateAttachmentSize }; | ||
|
||
const Ext2MimeTyes = { | ||
aac: "audio/aac", | ||
abw: "application/x-abiword", | ||
|
@@ -144,5 +167,5 @@ const Ext2MimeTyes = { | |
xml: "application/xml", | ||
zip: "application/zip", | ||
txt: "application/txt", | ||
lst: "application/txt" | ||
lst: "application/txt", | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
const { validateAttachmentSize } = require('../../lib/plugin'); | ||
|
||
describe('validateAttachmentSize', () => { | ||
let req; // Define a mock request object | ||
|
||
beforeEach(() => { | ||
req = { | ||
headers: {}, | ||
reject: jest.fn(), // Mocking the reject function | ||
}; | ||
}); | ||
|
||
it('should pass validation for a file size under 400 MB', () => { | ||
req.headers['content-length'] = '51200765'; | ||
|
||
validateAttachmentSize(req); | ||
|
||
expect(req.reject).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it('should reject for a file size over 400 MB', () => { | ||
req.headers['content-length'] = '20480000000'; | ||
|
||
validateAttachmentSize(req); | ||
|
||
expect(req.reject).toHaveBeenCalledWith(403, 'File Size limit exceeded beyond 400 MB.'); | ||
}); | ||
|
||
it('should reject when content-length header is missing', () => { | ||
validateAttachmentSize(req); | ||
|
||
expect(req.reject).toHaveBeenCalledWith(403, 'Invalid Content Size'); | ||
}); | ||
}); | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you remove all the formatting changes in this file, as these lines are out of scope for this specific task.