Skip to content

Commit

Permalink
GUI Data sharing service: object storage access audit, backported to …
Browse files Browse the repository at this point in the history
…stage/0.16/uat

Add storage id to storage audit logs (#3187), Data Sharing Service GUI, backported to stage/0.16/uat
  • Loading branch information
rodichenko committed Jul 28, 2023
1 parent b9c3215 commit 2a3a973
Show file tree
Hide file tree
Showing 5 changed files with 315 additions and 139 deletions.
6 changes: 6 additions & 0 deletions data-sharing-service/client/src/components/browser/Browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import displayDate from '../../utils/displayDate';
import roleModel from '../../utils/roleModel';
import styles from './Browser.css';
import {NoStorage} from '../main/App';
import auditStorageAccessManager from '../../utils/audit-storage-access';

const PAGE_SIZE = 40;

Expand Down Expand Up @@ -184,6 +185,11 @@ export default class Browser extends React.Component {
message.error(request.error);
} else {
hide();
auditStorageAccessManager.reportReadAccess({
storageId: this.props.storageId,
path: item.path,
reportStorageType: 'S3'
});
const a = document.createElement('a');
a.href = request.value.url;
a.download = item.name;
Expand Down
139 changes: 6 additions & 133 deletions data-sharing-service/client/src/models/s3Storage/s3Storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,7 @@
import AWS from 'aws-sdk/index';
import DataStorageTempCredentials from '../dataStorage/DataStorageTempCredentials';
import Credentials from './Credentials';

const asyncForEach = async (array, callback) => {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
};
import auditStorageAccessManager from '../../utils/audit-storage-access';

class S3Storage {

Expand All @@ -49,7 +44,7 @@ class S3Storage {
}

get prefix () {
return this._prefix;
return this._prefix || '';
}

set prefix (value) {
Expand Down Expand Up @@ -107,27 +102,6 @@ class S3Storage {
return success;
};

listObjects = () => {
let params = {
Bucket: this._storage.path,
Prefix: this._prefix
};
if (this._storage.delimiter) {
params.Delimiter = this._storage.delimiter;
}

return this._s3.listObjects(params).promise();
};

getStorageObject = async (key, startBytes, endBytes) => {
const params = {
Bucket: this._storage.path,
Key: key,
Range: `bytes=${startBytes}-${endBytes}`
};
return this._s3.getObject(params).promise();
};

completeMultipartUploadStorageObject = async (name, parts, uploadId) => {
const params = {
Bucket: this._storage.path,
Expand Down Expand Up @@ -168,115 +142,14 @@ class S3Storage {
PartNumber: partNumber,
UploadId: uploadId
};
auditStorageAccessManager.reportWriteAccess({
fullPath: `s3://${this._storage.path}/${this.prefix + name}`,
storageId: this._storage.id
});
const upload = this._s3.uploadPart(params);
upload.on('httpUploadProgress', uploadProgress);
return upload;
};

uploadStorageObject = async (name, body, uploadProgress) => {
const params = {
Body: body,
Bucket: this._storage.path,
Key: this.prefix + name
};
const upload = this._s3.upload(params);
upload.on('httpUploadProgress', uploadProgress);
return upload.promise();
};

putStorageObject = async (name, buffer) => {
const params = {
Body: buffer,
Bucket: this._storage.path,
Key: this._prefix + name
};

return this._s3.putObject(params).promise();
};

renameStorageObject = async (key, newName) => {
let success = true;

let params = {
Bucket: this._storage.path,
Prefix: key
};

if (key.endsWith(this._storage.delimiter)) {
try {
const data = await this._s3.listObjects(params).promise();
await asyncForEach(data.Contents, async file => {
params = {
Bucket: this._storage.path,
CopySource: this._storage.path + this._storage.delimiter + file.Key,
Key: file.Key.replace(key, this._prefix + newName + this._storage.delimiter)
};

await this._s3.copyObject(params).promise();
await this.deleteStorageObjects([file.Key]);
});
success = true;
} catch (err) {
success = false;
return Promise.reject(new Error(err.message));
}
} else {
params = {
Bucket: this._storage.path,
CopySource: this._storage.path + this._storage.delimiter + key,
Key: this._prefix + newName
};
try {
await this._s3.copyObject(params).promise();
await this.deleteStorageObjects([key]);
} catch (err) {
success = false;
return Promise.reject(new Error(err.message));
}
}
return success;
};

deleteStorageObjects = async (keys) => {
let deleteObjects = [];
let success = true;

try {
await asyncForEach(keys, async key => {
if (key.endsWith(this._storage.delimiter)) {
let params = {
Bucket: this._storage.path,
Prefix: key
};

const data = await this._s3.listObjects(params).promise();
data.Contents.forEach(content => {
deleteObjects.push({
Key: content.Key
});
});
} else {
deleteObjects.push({
Key: key
});
}
});

const params = {
Bucket: this._storage.path,
Delete: {
Objects: deleteObjects
}
};

await this._s3.deleteObjects(params).promise();
} catch (err) {
success = false;
return Promise.reject(new Error(err.message));
}
return success;
};

}

export default new S3Storage();
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*
* Copyright 2017-2019 EPAM Systems, Inc. (https://www.epam.com/)
* Copyright 2017-2023 EPAM Systems, Inc. (https://www.epam.com/)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
Expand All @@ -14,11 +14,13 @@
* limitations under the License.
*/

import Remote from '../basic/Remote';
import RemotePost from '../basic/RemotePost';

export default class DataStorageGenerateUploadUrl extends Remote {
constructor (id, path) {
class SendSystemLogs extends RemotePost {
constructor () {
super();
this.url = `/datastorage/${id}/generateUploadUrl?path=${path}`;
this.url = '/log';
}
}

export default SendSystemLogs;
28 changes: 28 additions & 0 deletions data-sharing-service/client/src/models/user/WhoAmI.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
*
* * Copyright 2017-2023 EPAM Systems, Inc. (https://www.epam.com/)
* *
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/

import Remote from '../basic/Remote';

class WhoAmI extends Remote {
constructor () {
super();
this.url = '/whoami';
}
}

export default new WhoAmI();
Loading

0 comments on commit 2a3a973

Please sign in to comment.