Skip to content

Commit dea1a1d

Browse files
committed
Added file-replace action
1 parent 68c6253 commit dea1a1d

File tree

9 files changed

+152
-3
lines changed

9 files changed

+152
-3
lines changed

doc/rest_api.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* [List files on the cloud server](#list-files-on-the-cloud-server)
99
* [Get file information](#get-file-information)
1010
* [Upload file to the cloud server](#upload-file-to-the-cloud-server)
11+
* [Replace file on the cloud server](#replace-file-to-the-cloud-server)
1112
* [Update file on the cloud server](#update-file-on-the-cloud-server)
1213
* [Update file access owner on the cloud server](#update-file-access-owner-on-the-cloud-server)
1314
* [Update file access mode on the cloud server](#update-file-access-mode-on-the-cloud-server)
@@ -251,6 +252,50 @@ PUT https://<host>:<port>/file-upload/?resource-name=<file-path>
251252
}
252253
```
253254

255+
### Replace file on the cloud server
256+
All files with given file name and owned by the requestor will be replaced (removed) by provided file.
257+
_NOTE: All additional information such as tags, version and custom access rights will be reset to initial values._
258+
```
259+
PUT https://<host>:<port>/file-replace/?resource-name=<file-path>
260+
```
261+
**Body:**
262+
```
263+
<content of the file to be uploaded>
264+
```
265+
**Response:**
266+
```
267+
{
268+
"upload": {
269+
"id": "<uid>",
270+
"path": "<file-path>",
271+
"size": "<bytes>",
272+
"created": "<seconds-since-epoch>",
273+
"updated": "<seconds-since-epoch>",
274+
"version": "<version>",
275+
"access": {
276+
"mode": {
277+
"user": <access-mode>,
278+
"group": <access-mode>,
279+
"other": <access-mode>
280+
},
281+
"owner": {
282+
"user": "<owner-username>",
283+
"group": "<owner-group>"
284+
}
285+
},
286+
"tags": [
287+
"<tag-1>",
288+
"<tag-2>",
289+
...
290+
"<tag-n>"
291+
]
292+
},
293+
"remove": [
294+
...
295+
]
296+
}
297+
```
298+
254299
### Update file on the cloud server
255300
```
256301
POST https://<host>:<port>/file-update/?resource-id=<uid>&resource-name=<file-path>

src/cloud-tool/src/application.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,13 @@ void Application::onStarted()
197197
this->toolInput.addAction(RCloudToolAction::requestFileUpload(this->httpClient, path, name, authUser, authToken));
198198
}
199199

200+
if (argumentsParser.isSet(RCloudAction::Action::FileReplace::key))
201+
{
202+
QString path = argumentsParser.getValue(RCloudAction::Resource::Path::key).toString();
203+
QString name = argumentsParser.getValue(RCloudAction::Resource::Name::key).toString();
204+
this->toolInput.addAction(RCloudToolAction::requestFileReplace(this->httpClient, path, name, authUser, authToken));
205+
}
206+
200207
if (argumentsParser.isSet(RCloudAction::Action::FileUpdate::key))
201208
{
202209
QString path = argumentsParser.getValue(RCloudAction::Resource::Path::key).toString();

src/cloud/src/action_handler.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,32 @@ void ActionHandler::resolveAction(const RCloudAction &action, const QString &fro
116116
QUuid requestId = this->fileManager->requestStoreFile(executorInfo,fileObject);
117117
this->fileRequests.insert(requestId,action.getId());
118118
}
119+
else if (action.getAction() == RCloudAction::Action::FileReplace::key)
120+
{
121+
FileObject *fileObject = new FileObject;
122+
fileObject->getInfo().setPath(action.getResourceName());
123+
fileObject->getInfo().setId(QUuid::createUuid());
124+
125+
RAccessOwner accessOwner;
126+
accessOwner.setUser(executorInfo.getName());
127+
accessOwner.setGroup(RUserInfo::userGroup);
128+
129+
RAccessMode accessMode;
130+
accessMode.setUserModeMask(RAccessMode::Mode::Read | RAccessMode::Mode::Write);
131+
accessMode.setGroupModeMask(RAccessMode::Mode::Read);
132+
accessMode.setOtherModeMask(RAccessMode::Mode::None);
133+
134+
RAccessRights accessRights;
135+
accessRights.setOwner(accessOwner);
136+
accessRights.setMode(accessMode);
137+
138+
fileObject->getInfo().setAccessRights(accessRights);
139+
140+
fileObject->setContent(action.getData());
141+
142+
QUuid requestId = this->fileManager->requestReplaceFile(executorInfo,fileObject);
143+
this->fileRequests.insert(requestId,action.getId());
144+
}
119145
else if (action.getAction() == RCloudAction::Action::FileUpdate::key)
120146
{
121147
FileObject *fileObject = new FileObject;

src/cloud/src/file_manager.cpp

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ int FileManager::perform()
6262
resultErrorType = this->storeFile(task.getExecutor(),*task.getObject(),result);
6363
writeIndex = true;
6464
}
65+
else if (task.getAction() == FileManagerTask::Action::ReplaceFile)
66+
{
67+
resultErrorType = this->replaceFile(task.getExecutor(),*task.getObject(),result);
68+
writeIndex = true;
69+
}
6570
else if (task.getAction() == FileManagerTask::Action::UpdateFile)
6671
{
6772
resultErrorType = this->updateFile(task.getExecutor(),*task.getObject(),result);
@@ -188,6 +193,11 @@ QUuid FileManager::requestStoreFile(const RUserInfo &executor, FileObject *objec
188193
return this->enqueueTask(FileManagerTask(executor,FileManagerTask::StoreFile,object));
189194
}
190195

196+
QUuid FileManager::requestReplaceFile(const RUserInfo &executor, FileObject *object)
197+
{
198+
return this->enqueueTask(FileManagerTask(executor,FileManagerTask::ReplaceFile,object));
199+
}
200+
191201
QUuid FileManager::requestUpdateFile(const RUserInfo &executor, FileObject *object)
192202
{
193203
return this->enqueueTask(FileManagerTask(executor,FileManagerTask::UpdateFile,object));
@@ -434,6 +444,57 @@ RError::Type FileManager::storeFile(const RUserInfo &executor, const FileObject
434444
R_LOG_TRACE_RETURN(RError::None);
435445
}
436446

447+
RError::Type FileManager::replaceFile(const RUserInfo &executor, const FileObject &object, QByteArray &output)
448+
{
449+
R_LOG_TRACE_IN;
450+
RLogger::debug("[%s] replaceFile: executor=\"%s\", storePath=\"%s\".\n",
451+
this->settings.getName().toUtf8().constData(),
452+
executor.getName().toUtf8().constData(),
453+
this->storePath.toUtf8().constData());
454+
455+
// List all files owned by executor.
456+
QList<RFileInfo> files = this->fileIndex.listUserObjects(
457+
[=](const RFileInfo &fileInfo)
458+
{
459+
460+
return (fileInfo.getPath() == object.getInfo().getPath() && // File paths must be equal
461+
executor.isUser(fileInfo.getAccessRights().getOwner().getUser()) && // File must be owned by the executor
462+
UserManager::authorizeUserAccess(executor,fileInfo.getAccessRights(),RAccessMode::Write)); // File must be writable
463+
}
464+
);
465+
466+
QJsonObject jsonOutput;
467+
QJsonArray jsonRemoveFileArray;
468+
469+
// Store new file object.
470+
QByteArray uploadFileOutput;
471+
RError::Type errorType = this->storeFile(executor,object,uploadFileOutput);
472+
if (errorType == RError::None)
473+
{
474+
if (!files.isEmpty())
475+
{
476+
// Remove all replaced files.
477+
for (const RFileInfo &fileInfo : std::as_const(files))
478+
{
479+
QByteArray removeFileOutput;
480+
errorType = this->removeFile(executor,fileInfo.getId(),removeFileOutput);
481+
jsonRemoveFileArray.append(QJsonDocument::fromJson(removeFileOutput).object());
482+
if (errorType != RError::None)
483+
{
484+
break;
485+
}
486+
}
487+
}
488+
}
489+
490+
jsonOutput["upload"] = QJsonDocument::fromJson(uploadFileOutput).object();
491+
jsonOutput["remove"] = jsonRemoveFileArray;
492+
493+
output = QJsonDocument(jsonOutput).toJson();
494+
495+
R_LOG_TRACE_RETURN(errorType);
496+
}
497+
437498
RError::Type FileManager::updateFile(const RUserInfo &executor, const FileObject &object, QByteArray &output)
438499
{
439500
R_LOG_TRACE_IN;
@@ -757,7 +818,7 @@ RError::Type FileManager::removeFile(const RUserInfo &executor, const QUuid &id,
757818
R_LOG_TRACE_RETURN(RError::InvalidInput);
758819
}
759820

760-
RFileInfo fileInfo = this->fileIndex.unregisterObject(id);
821+
RFileInfo fileInfo(this->fileIndex.getObjectInfo(id));
761822

762823
if (!UserManager::authorizeUserAccess(executor,fileInfo.getAccessRights(),RAccessMode::Write))
763824
{
@@ -767,6 +828,7 @@ RError::Type FileManager::removeFile(const RUserInfo &executor, const QUuid &id,
767828
output.constData());
768829
R_LOG_TRACE_RETURN(RError::Unauthorized);
769830
}
831+
fileInfo = this->fileIndex.unregisterObject(id);
770832

771833
QDir storeDir(this->storePath);
772834
if (!storeDir.remove(fileInfo.getId().toString(QUuid::WithoutBraces)))

src/cloud/src/file_manager.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ class FileManager : public RJob
6868
//! Request store file.
6969
QUuid requestStoreFile(const RUserInfo &executor, FileObject *object);
7070

71+
//! Request replace file.
72+
QUuid requestReplaceFile(const RUserInfo &executor, FileObject *object);
73+
7174
//! Request update file.
7275
QUuid requestUpdateFile(const RUserInfo &executor, FileObject *object);
7376

@@ -118,6 +121,9 @@ class FileManager : public RJob
118121
//! Store file.
119122
RError::Type storeFile(const RUserInfo &executor, const FileObject &object, QByteArray &output);
120123

124+
//! Replace file.
125+
RError::Type replaceFile(const RUserInfo &executor, const FileObject &object, QByteArray &output);
126+
121127
//! Update file.
122128
RError::Type updateFile(const RUserInfo &executor, const FileObject &object, QByteArray &output);
123129

src/cloud/src/file_manager_task.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ QString FileManagerTask::actionToString(const Action &action)
7373
return QString("File information");
7474
case StoreFile:
7575
return QString("Store file");
76+
case ReplaceFile:
77+
return QString("Replace file");
7678
case UpdateFile:
7779
return QString("Update file");
7880
case UpdateFileAccessOwner:

src/cloud/src/file_manager_task.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class FileManagerTask
2323
ListFiles,
2424
FileInfo,
2525
StoreFile,
26+
ReplaceFile,
2627
UpdateFile,
2728
UpdateFileAccessOwner,
2829
UpdateFileAccessMode,

0 commit comments

Comments
 (0)