Skip to content

Commit 73a690e

Browse files
committed
add redact perm check and delete
1 parent 2392b56 commit 73a690e

5 files changed

Lines changed: 195 additions & 28 deletions

File tree

6.1curlcommands.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2054,11 +2054,29 @@ curl -X POST -H 'Content-type: application/json' http://localhost:8080/api/admin
20542054
"urlTemplate": "/api/v1/access/datafile/{fileId}/auxiliary/qdc/1.0",
20552055
"timeOut": 3600
20562056
},
2057+
{
2058+
"name": "deleteRedactedFile",
2059+
"httpMethod": "DELETE",
2060+
"urlTemplate": "/api/v1/access/datafile/{fileId}/auxiliary/qdc/1.0",
2061+
"timeOut": 3600
2062+
},
2063+
{
2064+
"name": "listAuxiliaryFiles",
2065+
"httpMethod": "GET",
2066+
"urlTemplate": "/api/v1/access/datafile/{fileId}/auxiliary",
2067+
"timeOut": 3600
2068+
},
20572069
{
20582070
"name": "getDatasetVersionMetadata",
20592071
"httpMethod": "GET",
20602072
"urlTemplate": "/api/v1/datasets/{datasetId}/versions/{datasetVersion}",
20612073
"timeOut": 3600
2074+
},
2075+
{
2076+
"name": "userPermissions",
2077+
"httpMethod": "GET",
2078+
"urlTemplate": "/api/v1/datasets/{datasetId}/userPermissions",
2079+
"timeOut": 3600
20622080
}
20632081
]
20642082
}'
@@ -2102,11 +2120,29 @@ curl -X POST -H 'Content-type: application/json' http://localhost:8080/api/admin
21022120
"urlTemplate": "/api/v1/access/datafile/{fileId}/auxiliary/qdpx/1.0",
21032121
"timeOut": 3600
21042122
},
2123+
{
2124+
"name": "deleteRedactedFile",
2125+
"httpMethod": "DELETE",
2126+
"urlTemplate": "/api/v1/access/datafile/{fileId}/auxiliary/qdpx/1.0",
2127+
"timeOut": 3600
2128+
},
2129+
{
2130+
"name": "listAuxiliaryFiles",
2131+
"httpMethod": "GET",
2132+
"urlTemplate": "/api/v1/access/datafile/{fileId}/auxiliary",
2133+
"timeOut": 3600
2134+
},
21052135
{
21062136
"name": "getDatasetVersionMetadata",
21072137
"httpMethod": "GET",
21082138
"urlTemplate": "/api/v1/datasets/{datasetId}/versions/{datasetVersion}",
21092139
"timeOut": 3600
2140+
},
2141+
{
2142+
"name": "userPermissions",
2143+
"httpMethod": "GET",
2144+
"urlTemplate": "/api/v1/datasets/{datasetId}/userPermissions",
2145+
"timeOut": 3600
21102146
}
21112147
]
21122148
}'

previewers/betatest/i18n/en.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@
6666
"refiqdaRedactCodeTooltip": "Create a redacted version of the datafile with the selected codes, and any related annotations, removed.",
6767
"refiqdaRedactSuccess": "Redacted file has been successfully uploaded to Dataverse.",
6868
"refiqdaRedactError": "An error occurred during the redaction process: $1",
69+
"refiqdaDeleteRedacted": "Delete Redacted",
70+
"refiqdaDeleteSuccess": "Existing redacted file has been successfully deleted.",
71+
"refiqdaDeleteError": "An error occurred while deleting the redacted file: $1",
72+
"refiqdaDeleteConfirm": "Are you sure you want to delete the existing redacted file?",
6973
"jupyterPreviewText": "Jupyter Notebook Preview",
7074
"cdiPreviewText": "CDI Preview",
7175
"prev": "Previous",

previewers/betatest/i18n/es.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@
6565
"refiqdaRedactCodeTooltip": "Cree una versión redactada del archivo de datos con los códigos seleccionados y cualquier anotación relacionada eliminadas.",
6666
"refiqdaRedactSuccess": "El archivo redactado se ha cargado correctamente en Dataverse.",
6767
"refiqdaRedactError": "Se produjo un error durante el proceso de redacción: $1",
68+
"refiqdaDeleteRedacted": "Eliminar redactado",
69+
"refiqdaDeleteSuccess": "El archivo redactado existente se ha eliminado correctamente.",
70+
"refiqdaDeleteError": "Se produjo un error al eliminar el archivo redactado: $1",
71+
"refiqdaDeleteConfirm": "¿Está seguro de que desea eliminar el archivo redactado existente?",
6872
"jupyterPreviewText": "Previsualización de Jupyter Notebook",
6973
"cdiPreviewText": "Previsualización de CDI",
7074
"prev": "Anterior",

previewers/betatest/i18n/fr.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@
6666
"refiqdaRedactCodeTooltip": "Créez une version expurgée du fichier de données en supprimant les codes sélectionnés et toutes les annotations associées.",
6767
"refiqdaRedactSuccess": "Le fichier expurgé a été téléchargé avec succès sur Dataverse.",
6868
"refiqdaRedactError": "Une erreur s'est produite lors du processus d'expurgation : $1",
69+
"refiqdaDeleteRedacted": "Supprimer l'expurgation",
70+
"refiqdaDeleteSuccess": "Le fichier expurgé existant a été supprimé avec succès.",
71+
"refiqdaDeleteError": "Une erreur s'est produite lors de la suppression du fichier expurgé: $1",
72+
"refiqdaDeleteConfirm": "Êtes-vous sûr de vouloir supprimer le fichier expurgé existant ?",
6973
"jupyterPreviewText": "Aperçu Jupyter Notebook",
7074
"cdiPreviewText": "Aperçu CDI",
7175
"prev": "Précédent",

previewers/betatest/js/refiqdacore.js

Lines changed: 147 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,31 @@ function isZipMode() {
3737
}
3838

3939
var redactedMode;
40+
var canRedact = false;
41+
var redactedFileExists = false;
42+
43+
async function checkPermissions() {
44+
let permissionsUrl = queryParams.signedUrls ? queryParams.signedUrls.userPermissions : null;
45+
if (!permissionsUrl && queryParams.siteUrl && queryParams.datasetid) {
46+
permissionsUrl = queryParams.siteUrl + "/api/datasets/" + queryParams.datasetid + "/userPermissions";
47+
if (queryParams.key) {
48+
permissionsUrl += (permissionsUrl.includes('?') ? '&' : '?') + "key=" + queryParams.key;
49+
}
50+
}
51+
if (permissionsUrl) {
52+
try {
53+
const response = await fetch(permissionsUrl);
54+
if (response.ok) {
55+
const json = await response.json();
56+
if (json.status === 'OK' && json.data && json.data.permissions) {
57+
canRedact = json.data.permissions.includes('EditDataset');
58+
}
59+
}
60+
} catch (error) {
61+
console.error("Error checking permissions:", error);
62+
}
63+
}
64+
}
4065

4166
var wait;
4267
var cy;
@@ -50,7 +75,14 @@ function parseData(data, filejson) {
5075
$('<span/>').text($.i18n('refiqdaParsingProject')).appendTo(wait);
5176
wait.appendTo($('.preview'));
5277

53-
new Promise((resolve) => setTimeout(resolve, 500)).then(() => { parseData2(data) });
78+
checkPermissions().then(() => {
79+
new Promise((resolve) => setTimeout(resolve, 500)).then(() => {
80+
parseData2(data);
81+
if (canRedact && !redactedMode) {
82+
checkForRedactedFile();
83+
}
84+
});
85+
});
5486
}
5587

5688
// Reads the project file and walks through the XML creating tables for all the entry types
@@ -69,6 +101,15 @@ function parseData2(data) {
69101
filterBlock.append($("<h2/>").html($.i18n('refiqdaEnableFilteringBy')));
70102
filterBlock.append($("<p/>").html($.i18n('refiqdaFilteringInstructions')));
71103
const filterBy = $('<select/>').prop('id', 'filterby').appendTo(filterBlock);
104+
if (canRedact && !redactedMode) {
105+
$('<button/>')
106+
.addClass('btn btn-danger delete-redacted-btn')
107+
.text($.i18n('refiqdaDeleteRedacted'))
108+
.css('margin-left', '10px')
109+
.hide()
110+
.click(deleteRedactedFile)
111+
.appendTo(filterBlock);
112+
}
72113
filterBy.append($('<option/>').prop('value', 'None').text($.i18n('refiqdaNoFiltering')));
73114
//As tables are created, they will be added to the option list here
74115

@@ -177,8 +218,10 @@ function parseData2(data) {
177218
};
178219
dataTableConfig.buttons = [
179220
'selectAll',
180-
'selectNone',
181-
{
221+
'selectNone'
222+
];
223+
if (canRedact) {
224+
dataTableConfig.buttons.push({
182225
text: $.i18n('refiqdaRedact'),
183226
className: 'redact-btn',
184227
titleAttr: $.i18n('refiqdaRedactCodeTooltip'),
@@ -191,8 +234,8 @@ function parseData2(data) {
191234
redactCodes(codeGuids);
192235
},
193236
enabled: false
194-
}
195-
];
237+
});
238+
}
196239
}
197240

198241
if (hasColorAttribute) {
@@ -253,7 +296,9 @@ function parseData2(data) {
253296
if (filterBy.val() === 'Codes') {
254297
codeDataTable.on('select deselect', function () {
255298
var selectedRows = codeDataTable.rows({ selected: true }).count();
256-
codeDataTable.button('.redact-btn').enable(selectedRows > 0);
299+
if (canRedact) {
300+
codeDataTable.button('.redact-btn').enable(selectedRows > 0);
301+
}
257302
});
258303
}
259304

@@ -692,8 +737,10 @@ $("#filterby")
692737
};
693738
codeConfig.buttons = [
694739
'selectAll',
695-
'selectNone',
696-
{
740+
'selectNone'
741+
];
742+
if (canRedact) {
743+
codeConfig.buttons.push({
697744
text: $.i18n('refiqdaRedact'),
698745
className: 'redact-btn',
699746
titleAttr: $.i18n('refiqdaRedactCodeTooltip'),
@@ -706,8 +753,8 @@ $("#filterby")
706753
redactCodes(codeGuids);
707754
},
708755
enabled: false
709-
}
710-
];
756+
});
757+
}
711758
}
712759

713760
if (hasColorColumn) {
@@ -770,7 +817,9 @@ $("#filterby")
770817
if ($('#filterby').val() === 'Codes') {
771818
codeDataTable.on('select deselect', function () {
772819
var selectedRows = codeDataTable.rows({ selected: true }).count();
773-
codeDataTable.button('.redact-btn').enable(selectedRows > 0);
820+
if (canRedact) {
821+
codeDataTable.button('.redact-btn').enable(selectedRows > 0);
822+
}
774823
});
775824
}
776825

@@ -808,30 +857,34 @@ $("#filterby")
808857
};
809858
dtOptions.buttons = [
810859
'selectAll',
811-
'selectNone',
812-
{
813-
text: $.i18n('refiqdaRedact'),
814-
className: 'redact-btn',
815-
titleAttr: $.i18n('refiqdaRedactSourceTooltip'),
816-
action: function ( e, dt, node, config ) {
817-
let selectedRows = dt.rows( { selected: true } );
818-
let sourceGuids = [];
819-
selectedRows.nodes().to$().each(function() {
820-
sourceGuids.push($(this).data('guid'));
821-
});
822-
redactSources(sourceGuids);
823-
},
824-
enabled: false
825-
}
860+
'selectNone'
826861
];
862+
if (canRedact) {
863+
dtOptions.buttons.push({
864+
text: $.i18n('refiqdaRedact'),
865+
className: 'redact-btn',
866+
titleAttr: $.i18n('refiqdaRedactSourceTooltip'),
867+
action: function ( e, dt, node, config ) {
868+
let selectedRows = dt.rows( { selected: true } );
869+
let sourceGuids = [];
870+
selectedRows.nodes().to$().each(function() {
871+
sourceGuids.push($(this).data('guid'));
872+
});
873+
redactSources(sourceGuids);
874+
},
875+
enabled: false
876+
});
877+
}
827878
}
828879

829880
sourceDataTable = new DataTable(".sourcetable", dtOptions);
830881

831882
if (filterBy.val() === 'Sources') {
832883
sourceDataTable.on('select deselect', function () {
833884
var selectedRows = sourceDataTable.rows({ selected: true }).count();
834-
sourceDataTable.button('.redact-btn').enable(selectedRows > 0);
885+
if (canRedact) {
886+
sourceDataTable.button('.redact-btn').enable(selectedRows > 0);
887+
}
835888
});
836889
}
837890

@@ -1416,7 +1469,16 @@ async function uploadRedactedFile(blob, filename) {
14161469
formData.append("type", "qda");
14171470

14181471
console.log(`Uploading redacted file: ${filename}`);
1419-
const response = await fetch(queryParams.signedUrls.uploadRedactedFile, {
1472+
let uploadUrl = queryParams.signedUrls ? queryParams.signedUrls.uploadRedactedFile : null;
1473+
if (!uploadUrl && queryParams.siteUrl && queryParams.fileid) {
1474+
const type = isZipMode() ? 'qdpx' : 'qdc';
1475+
uploadUrl = queryParams.siteUrl + "/api/access/datafile/" + queryParams.fileid + "/auxiliary/" + type + "/1.0";
1476+
if (queryParams.key) {
1477+
uploadUrl += (uploadUrl.includes('?') ? '&' : '?') + "key=" + queryParams.key;
1478+
}
1479+
}
1480+
1481+
const response = await fetch(uploadUrl, {
14201482
method: 'POST',
14211483
body: formData,
14221484
});
@@ -1429,6 +1491,7 @@ async function uploadRedactedFile(blob, filename) {
14291491
const responseData = await response.json();
14301492
console.log("Upload successful:", responseData);
14311493
alert($.i18n('refiqdaRedactSuccess'));
1494+
checkForRedactedFile();
14321495
} catch (error) {
14331496
console.error("Error during upload:", error);
14341497
alert($.i18n('refiqdaRedactError', error.message));
@@ -1497,3 +1560,59 @@ function redactCodes(guidsToRedact) {
14971560
uploadRedactedFile(redactedXmlBlob, redactedFilename);
14981561
}
14991562
}
1563+
1564+
async function checkForRedactedFile() {
1565+
let listUrl = queryParams.signedUrls ? queryParams.signedUrls.listAuxiliaryFiles : null;
1566+
if (!listUrl && queryParams.siteUrl && queryParams.fileid) {
1567+
listUrl = queryParams.siteUrl + "/api/access/datafile/" + queryParams.fileid + "/auxiliary";
1568+
if (queryParams.key) {
1569+
listUrl += (listUrl.includes('?') ? '&' : '?') + "key=" + queryParams.key;
1570+
}
1571+
}
1572+
if (listUrl) {
1573+
try {
1574+
const response = await fetch(listUrl);
1575+
if (response.ok) {
1576+
const auxFiles = await response.json();
1577+
const type = isZipMode() ? 'qdpx' : 'qdc';
1578+
redactedFileExists = auxFiles.some(f => f.formatTag === type && f.formatVersion === '1.0');
1579+
if (redactedFileExists) {
1580+
$('.delete-redacted-btn').show();
1581+
} else {
1582+
$('.delete-redacted-btn').hide();
1583+
}
1584+
}
1585+
} catch (error) {
1586+
console.error("Error checking for redacted file:", error);
1587+
}
1588+
}
1589+
}
1590+
1591+
async function deleteRedactedFile() {
1592+
if (confirm($.i18n('refiqdaDeleteConfirm'))) {
1593+
try {
1594+
let deleteUrl = queryParams.signedUrls ? queryParams.signedUrls.deleteRedactedFile : null;
1595+
if (!deleteUrl && queryParams.siteUrl && queryParams.fileid) {
1596+
const type = isZipMode() ? 'qdpx' : 'qdc';
1597+
deleteUrl = queryParams.siteUrl + "/api/access/datafile/" + queryParams.fileid + "/auxiliary/" + type + "/1.0";
1598+
if (queryParams.key) {
1599+
deleteUrl += (deleteUrl.includes('?') ? '&' : '?') + "key=" + queryParams.key;
1600+
}
1601+
}
1602+
const response = await fetch(deleteUrl, {
1603+
method: 'DELETE'
1604+
});
1605+
if (response.ok) {
1606+
alert($.i18n('refiqdaDeleteSuccess'));
1607+
redactedFileExists = false;
1608+
$('.delete-redacted-btn').hide();
1609+
} else {
1610+
const errorText = await response.text();
1611+
throw new Error(`Delete failed: ${response.statusText} - ${errorText}`);
1612+
}
1613+
} catch (error) {
1614+
console.error("Error deleting redacted file:", error);
1615+
alert($.i18n('refiqdaDeleteError', error.message));
1616+
}
1617+
}
1618+
}

0 commit comments

Comments
 (0)