Skip to content

Commit

Permalink
Cloud data: update objects permissions after copy / create operations…
Browse files Browse the repository at this point in the history
… for NFS storages
  • Loading branch information
rodichenko committed Aug 24, 2023
1 parent 03c0374 commit 633a0d9
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class Configuration extends React.Component {
modified: false,
version: undefined,
pingAfterCopy: false,
updatePermissions: false,
maxWaitSeconds: undefined,
pingTimeoutSeconds: undefined,
pending: false,
Expand Down Expand Up @@ -63,7 +64,8 @@ class Configuration extends React.Component {
let {
maxWaitSeconds = copyPingConfiguration.maxWaitSeconds,
pingTimeoutSeconds = copyPingConfiguration.pingTimeoutSeconds,
name
name,
updatePermissions = false
} = webdavClientConfig;
if (
Number.isNaN(Number(maxWaitSeconds)) ||
Expand All @@ -89,6 +91,7 @@ class Configuration extends React.Component {
version: webdavClientConfig.version,
name,
pingAfterCopy,
updatePermissions,
maxWaitSeconds,
pingTimeoutSeconds,
pending: false,
Expand Down Expand Up @@ -135,6 +138,17 @@ class Configuration extends React.Component {
});
};

onUpdatePermissionsChanged = (e) => {
const updatePermissions = e.target.checked;
const cfg = electron.remote.getGlobal('webdavClient');
cfg.config.updatePermissions = updatePermissions;
writeWebDavConfiguration(cfg.config);
this.setState({
updatePermissions,
modified: true
});
};

onIgnoreCertificateErrorsSettingChanged = (e) => {
this.setState({
ignoreCertificateErrors: e.target.checked,
Expand Down Expand Up @@ -277,6 +291,7 @@ class Configuration extends React.Component {
maxWaitSeconds,
pingTimeoutSeconds,
pingAfterCopy,
updatePermissions,
pending,
webDavDiagnoseFile,
webDavDiagnoseState,
Expand Down Expand Up @@ -429,6 +444,20 @@ class Configuration extends React.Component {
</div>
)
}
{
pingAfterCopy && (
<div
className="row"
>
<Checkbox
checked={updatePermissions}
onChange={this.onUpdatePermissionsChanged}
>
Update destination file permissions after copy / create operation
</Checkbox>
</div>
)
}
{
version && (
<div className="app-version">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,36 @@ import {error, log} from './log';

const REQUEST_TIMEOUT_SECONDS = 30;

function wrapRequest (url, method, body, authToken, ignoreCertificateErrors = false) {
const getAPIHeaders = (token) => ({
"Authorization": `Bearer ${token}`,
"Content-type": "application/json",
"Accept": "application/json",
"Accept-Charset": "utf-8"
});

const getWebdavAPIHeaders = (token) => ({
"Cookie": `bearer=${token}`,
"Content-type": "application/json",
"Accept": "application/json",
"Accept-Charset": "utf-8"
});

class NetworkError extends Error {

}

class APIError extends Error {

}

function wrapRequest (url, method, body, headers = {}, ignoreCertificateErrors = false) {
return new Promise((resolve, reject) => {
log(`${method} ${url}...`);
const request = https.request(url, {
method,
timeout: REQUEST_TIMEOUT_SECONDS * 1000,
rejectUnauthorized: !ignoreCertificateErrors,
headers: {
"Authorization": `Bearer ${authToken}`,
"Content-type": "application/json",
"Accept": "application/json",
"Accept-Charset": "utf-8"
}
headers
}, (response) => {
let data = '';
response.on('data', (chunk) => {
Expand All @@ -31,7 +48,7 @@ function wrapRequest (url, method, body, authToken, ignoreCertificateErrors = fa
resolve(json.payload);
} else {
error(`${method} ${url}: ${json.message}`);
reject(new Error(json.message || 'Request error'));
reject(new APIError(json.message || 'Request error'));
}
} else {
resolve(undefined);
Expand All @@ -44,11 +61,11 @@ function wrapRequest (url, method, body, authToken, ignoreCertificateErrors = fa
});
request.on('error', (e) => {
error(`${method} ${url}: ${e.toString()}`);
reject(new Error(`Request error: ${e.toString()}`));
reject(new NetworkError(`Request error: ${e.toString()}`));
});
request.on('timeout', () => {
error(`${method} ${url}: timeout`);
reject(new Error('Request timeout'));
reject(new NetworkError('Request timeout'));
});
if (body) {
log(`${method} ${url}: sending ${body.length} bytes`);
Expand All @@ -68,6 +85,18 @@ class CloudPipelineApi {
}
const {config: webdavClientConfig = {}} = cfg || {};
this.api = webdavClientConfig.api;
let webdavServer = (webdavClientConfig.server || '');
if (webdavServer && webdavServer.endsWith('/')) {
webdavServer = webdavServer.slice(0, -1);
}
if (webdavServer) {
this.webdavAPI = webdavServer
.split('/')
.slice(0, -1)
.join('/');
} else {
this.webdavAPI = undefined;
}
this.password = webdavClientConfig.password;
this.ignoreCertificateErrors = webdavClientConfig.ignoreCertificateErrors;
return this;
Expand All @@ -89,7 +118,31 @@ class CloudPipelineApi {
`${api}/${endpoint}`,
method,
body ? JSON.stringify(body) : undefined,
this.password,
getAPIHeaders(this.password),
this.ignoreCertificateErrors
)
}

webdavAPIRequest (endpoint, options = {}) {
if (!this.webdavAPI) {
return Promise.reject('Webdav API not initialized');
}
const {
body,
method = body ? 'POST' : 'GET'
} = options;
let api = this.webdavAPI || '';
if (api.endsWith('/')) {
api = api.slice(0, -1);
}
if (endpoint.startsWith('/')) {
endpoint = endpoint.slice(1);
}
return wrapRequest(
`${api}/${endpoint}`,
method,
body ? JSON.stringify(body) : undefined,
getWebdavAPIHeaders(this.password),
this.ignoreCertificateErrors
)
}
Expand Down Expand Up @@ -217,6 +270,21 @@ class CloudPipelineApi {
.catch(reject);
});
}

sendWebdavPermissionsRequest(path = []) {
if (path.length > 0) {
return this.webdavAPIRequest('/extra/chown', {
body: {
path: path.map((o) => o.startsWith('/') ? o.slice(1) : o)
}
});
}
return Promise.resolve();
}
}

export {
APIError,
NetworkError,
};
export default new CloudPipelineApi();
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class CopyOperation extends Operation {
)
.then(() => destinationAdapter.ensurePathExists(element.to))
.then(() => {
destinationAdapter.updateRemotePermissions(element.to);
progressCallback(100);
resolve();
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ class FileSystem {
pathExists(path) {
return Promise.resolve(true);
}
updateRemotePermissions(...path) {
// empty
}
ensurePathExists(destinationPath) {
if (this.pingAfterCopy) {
const max = Number(this.maxWaitSeconds);
Expand Down
Loading

0 comments on commit 633a0d9

Please sign in to comment.