Skip to content

Commit

Permalink
feat: Add get and delete file
Browse files Browse the repository at this point in the history
  • Loading branch information
apburnes committed Feb 6, 2025
1 parent 7748290 commit 84a7e3e
Show file tree
Hide file tree
Showing 9 changed files with 544 additions and 3 deletions.
57 changes: 55 additions & 2 deletions api/controllers/file-storage-service.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const { isEmpty } = require('underscore');
const EventCreator = require('../services/EventCreator');
const {
canCreateSiteStorage,
Expand Down Expand Up @@ -65,6 +66,58 @@ module.exports = wrapHandlers({
}
},

async deleteFile(req, res) {
const { params, user } = req;

const fssId = parseInt(params.file_storage_id, 10);
const fileId = parseInt(params.file_id, 10);

try {
const { fileStorageService } = await isFileStorageUser(
{ id: user.id },
{ id: fssId },
);

const siteStorageService = new SiteFileStorageSerivce(fileStorageService, user.id);
const client = await siteStorageService.createClient();
const results = await client.deleteFile(fileId);

if (!results) {
return res.notFound();
}

return res.send(results);
} catch (error) {
return res.status(error.status).send(error);
}
},

async getFile(req, res) {
const { params, user } = req;

const fssId = parseInt(params.file_storage_id, 10);
const fileId = parseInt(params.file_id, 10);

try {
const { fileStorageService } = await isFileStorageUser(
{ id: user.id },
{ id: fssId },
);

const siteStorageService = new SiteFileStorageSerivce(fileStorageService, user.id);
const client = await siteStorageService.createClient();
const results = await client.getFile(fileId);

if (isEmpty(results)) {
return res.notFound();
}

return res.send(results);
} catch (error) {
return res.status(error.status).send(error);
}
},

async listDirectoryFiles(req, res) {
const { params, query, user } = req;
const {
Expand All @@ -88,7 +141,7 @@ module.exports = wrapHandlers({
const client = await siteStorageService.createClient();
const results = await client.listDirectoryFiles(path, { limit, page, order });

res.send(results);
return res.send(results);
} catch (error) {
return res.status(error.status).send(error);
}
Expand All @@ -115,7 +168,7 @@ module.exports = wrapHandlers({
page,
});

res.send(results);
return res.send(results);
} catch (error) {
return res.status(error.status).send(error);
}
Expand Down
2 changes: 2 additions & 0 deletions api/responses/siteErrors.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ module.exports = {
SITE_FILE_STORAGE_EXISTS:
'The site already has an existing file storage services available.',
SITE_DOES_NOT_EXIST: 'The specified site does not exist',
DIRECTORY_MUST_BE_EMPTIED:
'This directory cannot be deleted. Please delete file contents first.',
};
8 changes: 8 additions & 0 deletions api/routers/file-storage-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ router.get(
'/file-storage/:file_storage_id/',
FileStorageServiceController.listDirectoryFiles,
);
router.get(
'/file-storage/:file_storage_id/file/:file_id',
FileStorageServiceController.getFile,
);
router.delete(
'/file-storage/:file_storage_id/file/:file_id',
FileStorageServiceController.deleteFile,
);
router.get(
'/file-storage/:file_storage_id/user-actions',
FileStorageServiceController.listUserActions,
Expand Down
2 changes: 2 additions & 0 deletions api/serializers/file-storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const allowedFileStorageFileFields = [
];

const serializeFileStorageFile = (serializable) => {
if (!serializable) return {};

return pick(allowedFileStorageFileFields, serializable.dataValues);
};

Expand Down
11 changes: 11 additions & 0 deletions api/services/S3Helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const {
GetObjectCommand,
waitUntilBucketExists,
DeleteObjectsCommand,
DeleteObjectCommand,
} = require('@aws-sdk/client-s3');

const S3_DEFAULT_MAX_KEYS = 1000;
Expand Down Expand Up @@ -145,6 +146,16 @@ class S3Client {
}
}

async deleteObject(key, extras = {}) {
const { bucket, client } = this;
const command = new DeleteObjectCommand({
Bucket: bucket,
Key: key,
...extras,
});
return client.send(command);
}

async putObject(body, key, extras = {}) {
const { bucket, client } = this;
const command = new PutObjectCommand({
Expand Down
49 changes: 48 additions & 1 deletion api/services/file-storage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ const S3Helper = require('../S3Helper');
const CloudFoundryAPIClient = require('../../utils/cfApiClient');
const { normalizeDirectoryPath, paginate, slugify } = require('../../utils');
const {
serializeFileStorageFile,
serializeFileStorageFiles,
serializeFileStorageUserActions,
} = require('../../serializers/file-storage');
const siteErrors = require('../../responses/siteErrors');

const apiClient = new CloudFoundryAPIClient();

Expand Down Expand Up @@ -143,10 +145,55 @@ class SiteFileStorageSerivce {
return fss;
}

async deleteFile() {}
async deleteFile(id) {
const record = await FileStorageFile.findOne({
where: { id, fileStorageServiceId: this.id },
});

if (!record) {
return null;
}

if (record.type === 'directory') {
const children = await FileStorageFile.count({
where: {
fileStorageServiceId: this.id,
key: { [Op.like]: `${record.key}%` },
},
});

if (children > 1) {
return {
message: siteErrors.DIRECTORY_MUST_BE_EMPTIED,
};
}
}

await this.s3Client.deleteObject(record.key);

const result = await record.destroy();

await FileStorageUserAction.create({
userId: this.userId,
fileStorageServiceId: this.id,
fileStorageFileId: id,
method: FileStorageUserAction.METHODS.DELETE,
description: FileStorageUserAction.ACTION_TYPES.DELETE_FILE,
});

return result;
}

async deleteDirectory() {}

async getFile(id) {
const record = await FileStorageFile.findOne({
where: { id, fileStorageServiceId: this.id },
});

return serializeFileStorageFile(record);
}

async listUserActions({ fileStorageFileId = null, limit = 50, page = 1 } = {}) {
const order = ['createdAt', 'DESC'];

Expand Down
50 changes: 50 additions & 0 deletions public/swagger/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,56 @@ paths:
description: Not found
schema:
$ref: 'Error.json'
/file-storage/{file_storage_id}/file/{file_id}:
parameters:
- name: file_storage_id
in: path
description: The id of the file storage service
type: integer
required: true
- name: file_id
in: path
description: The id of the file storage file
type: integer
required: true
get:
summary: Returns a file storage file
responses:
200:
description: A list of files
schema:
$ref: 'FileStorageFile.json'
400:
description: Bad request
schema:
$ref: 'Error.json'
403:
description: Not authorized
schema:
$ref: 'Error.json'
404:
description: Not found
schema:
$ref: 'Error.json'
delete:
summary: Deletes a file storage file
responses:
200:
description: An empty object
schema:
type: object
400:
description: Bad request
schema:
$ref: 'Error.json'
403:
description: Not authorized
schema:
$ref: 'Error.json'
404:
description: Not found
schema:
$ref: 'Error.json'
/file-storage/{file_storage_id}/user-actions:
parameters:
- name: file_storage_id
Expand Down
Loading

0 comments on commit 84a7e3e

Please sign in to comment.