Skip to content

Commit 0fe56d6

Browse files
committed
changes to put and get permissions on folders
1 parent 392c7cd commit 0fe56d6

File tree

13 files changed

+215
-106
lines changed

13 files changed

+215
-106
lines changed

app/src/components/constants.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ module.exports = Object.freeze({
5757
/** Maximum Content Length supported by S3 CopyObjectCommand */
5858
MAXCOPYOBJECTLENGTH: 5 * 1024 * 1024 * 1024, // 5 GB
5959

60-
/** Maximum Content Length supported by S3 CopyObjectCommand */
60+
/** Maximum Content Length (file size) supported by S3 */
6161
MAXFILEOBJECTLENGTH: 5 * 1024 * 1024 * 1024 * 1024, // 5 TB
6262

6363
/** Allowable values for the Metadata Directive parameter */

app/src/components/queueManager.js

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class QueueManager {
5858
if (!this.isBusy && !this.toClose) {
5959
objectQueueService.queueSize().then(size => {
6060
if (size > 0) this.processNextJob();
61+
// if (size > 0);
6162
}).catch((err) => {
6263
log.error(`Error encountered while checking queue: ${err.message}`, { function: 'checkQueue', error: err });
6364
});

app/src/controllers/bucket.js

+37
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const log = require('../components/log')(module.filename);
99
const {
1010
addDashesToUuid,
1111
getCurrentIdentity,
12+
getBucket,
1213
isTruthy,
1314
joinPath,
1415
mixedQueryToArray,
@@ -323,6 +324,42 @@ const controller = {
323324
}
324325
},
325326

327+
328+
/**
329+
* @function togglePublic
330+
* Sets the public flag of a bucket (or folder)
331+
* @param {object} req Express request object
332+
* @param {object} res Express response object
333+
* @param {function} next The next callback function
334+
* @returns {function} Express middleware function
335+
*/
336+
async togglePublic(req, res, next) {
337+
try {
338+
const bucketId = addDashesToUuid(req.params.bucketId);
339+
const publicFlag = isTruthy(req.query.public) ?? false;
340+
const userId = await userService.getCurrentUserId(getCurrentIdentity(req.currentUser, SYSTEM_USER), SYSTEM_USER);
341+
342+
const bucket = await getBucket(bucketId);
343+
const data = {
344+
bucketId: bucketId,
345+
path: bucket.key + '/',
346+
public: publicFlag,
347+
userId: userId
348+
};
349+
await storageService.updatePublic(data).catch(() => {
350+
log.warn('Failed to apply permission changes to S3', { function: 'togglePublic', ...data });
351+
});
352+
s3Public = await storageService.getPublic({ path: data.path, bucketId: bucketId });
353+
354+
const response = await bucketService.update(data);
355+
356+
res.status(200).json(response);
357+
} catch (e) {
358+
next(errorToProblem(SERVICE, e));
359+
}
360+
},
361+
362+
326363
/**
327364
* @function updateBucket
328365
* Updates a bucket

app/src/controllers/object.js

+5-7
Original file line numberDiff line numberDiff line change
@@ -1076,19 +1076,17 @@ const controller = {
10761076
const data = {
10771077
id: objId,
10781078
bucketId: req.currentObject?.bucketId,
1079-
filePath: req.currentObject?.path,
1079+
path: req.currentObject?.path,
10801080
public: publicFlag,
10811081
userId: userId,
1082-
// TODO: Implement if/when we proceed with version-scoped public permission management
1083-
// s3VersionId: await getS3VersionId(
1084-
// req.query.s3VersionId, addDashesToUuid(req.query.versionId), objId
1085-
// )
10861082
};
10871083

1088-
storageService.updatePublicPermissions(data).catch(() => {
1089-
// Gracefully continue even when S3 ACL management operation fails
1084+
await storageService.updatePublic(data).catch(() => {
10901085
log.warn('Failed to apply permission changes to S3', { function: 'togglePublic', ...data });
10911086
});
1087+
1088+
s3Public = await storageService.getPublic({ path: data.path, bucketId: req.currentObject?.bucketId });
1089+
10921090
const response = await objectService.update(data);
10931091

10941092
res.status(200).json(response);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
exports.up = function (knex) {
2+
return Promise.resolve()
3+
// add public column to bucket table
4+
.then(() => knex.schema.alterTable('bucket', table => {
5+
table.boolean('public').notNullable().defaultTo(false);
6+
}));
7+
};
8+
9+
exports.down = function (knex) {
10+
return Promise.resolve()
11+
// drop public column in bucket table
12+
.then(() => knex.schema.alterTable('bucket', table => {
13+
table.dropColumn('public');
14+
}));
15+
};

app/src/db/models/tables/bucket.js

+1
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ class Bucket extends mixin(Model, [
9999
region: { type: 'string', maxLength: 255 },
100100
active: { type: 'boolean' },
101101
lastSyncRequestedDate: { type: ['string', 'null'], format: 'date-time' },
102+
public: { type: 'boolean' },
102103
...stamps
103104
},
104105
additionalProperties: false

app/src/middleware/authorization.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const log = require('../components/log')(module.filename);
44
const { AuthMode, AuthType, Permissions } = require('../components/constants');
55
const {
66
getAppAuthMode,
7+
getBucket,
78
getCurrentIdentity,
89
getConfigBoolean,
910
mixedQueryToArray, stripDelimit } = require('../components/utils');
@@ -106,6 +107,12 @@ const checkS3BasicAccess = async (req, _res, next) => {
106107
next();
107108
};
108109

110+
// get public boolean from COMS object or parent bucket record
111+
const _checkPublic = async (currentObject) => {
112+
const bucket = await getBucket(currentObject.bucketId);
113+
return currentObject.public || bucket.public;
114+
};
115+
109116
/**
110117
* @function checkAppMode
111118
* Rejects the request if the incoming authentication mode does not match the application mode
@@ -190,7 +197,7 @@ const hasPermission = (permission) => {
190197
throw new Error('Missing object record');
191198
} else if (authType === AuthType.BASIC && canBasicMode(authMode)) {
192199
log.debug('Basic authTypes are always permitted', { function: 'hasPermission' });
193-
} else if (req.params.objectId && req.currentObject.public && permission === Permissions.READ) {
200+
} else if (req.params.objectId && await _checkPublic(req.currentObject) && permission === Permissions.READ) {
194201
log.debug('Read requests on public objects are always permitted', { function: 'hasPermission' });
195202
} else if (!await _checkPermission(req, permission)) {
196203
throw new Error(`User lacks required permission ${permission}`);

app/src/routes/v1/bucket.js

+12
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,18 @@ router.patch('/:bucketId',
6161
}
6262
);
6363

64+
/** Sets the public flag of a bucket (or folder) */
65+
router.patch('/:bucketId/public',
66+
requireSomeAuth,
67+
bucketValidator.togglePublic,
68+
hasPermission(Permissions.MANAGE),
69+
(req, res, next) => {
70+
bucketController.togglePublic(req, res, next);
71+
}
72+
);
73+
74+
75+
6476
/** Deletes the bucket */
6577
router.delete('/:bucketId',
6678
bucketValidator.deleteBucket,

app/src/services/bucket.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,8 @@ const service = {
294294
region: data.region,
295295
active: data.active,
296296
updatedBy: data.userId,
297-
lastSyncRequestedDate: data.lastSyncRequestedDate
297+
lastSyncRequestedDate: data.lastSyncRequestedDate,
298+
public: data.public
298299
});
299300

300301
if (!etrx) await trx.commit();

0 commit comments

Comments
 (0)