Skip to content

Commit 47489b4

Browse files
committed
[bugfix] override resource type from backup metadata
Signed-off-by: Patrick Reinhart <[email protected]>
1 parent 12ae764 commit 47489b4

File tree

2 files changed

+78
-51
lines changed

2 files changed

+78
-51
lines changed

exist-core/src/main/java/org/exist/backup/restore/RestoreHandler.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -304,11 +304,16 @@ private DeferredPermission restoreResourceEntry(final Attributes atts) throws SA
304304
}
305305

306306
MimeType mimeType = null;
307-
if (mimeTypeStr != null) {
307+
if (xmlType) {
308+
mimeType = MimeType.XML_TYPE;
309+
} else if (mimeTypeStr != null) {
308310
mimeType = MimeTable.getInstance().getContentType(mimeTypeStr);
309-
}
310-
if (mimeType == null) {
311-
mimeType = xmlType ? MimeType.XML_TYPE : MimeType.BINARY_TYPE;
311+
if (mimeType == null) {
312+
mimeType = MimeType.BINARY_TYPE;
313+
} else if (mimeType.isXMLType() != xmlType) {
314+
listener.warn("Calculated mime type " + mimeType + " type differs from the one specified in the backup, adjusting it");
315+
mimeType = new MimeType(mimeType.getName(), xmlType ? MimeType.XML : MimeType.BINARY);
316+
}
312317
}
313318

314319
Date dateCreated = null;

exist-core/src/test/java/org/exist/backup/XMLDBRestoreTest.java

Lines changed: 69 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,9 @@
2828
import org.exist.security.MessageDigester;
2929
import org.exist.security.SecurityManager;
3030
import org.exist.test.ExistWebServer;
31+
import org.exist.util.MimeTable;
3132
import org.exist.xmldb.*;
32-
import org.junit.ClassRule;
33-
import org.junit.Ignore;
34-
import org.junit.Rule;
35-
import org.junit.Test;
33+
import org.junit.*;
3634
import org.junit.rules.TemporaryFolder;
3735
import org.junit.runner.RunWith;
3836
import org.junit.runners.Parameterized;
@@ -85,6 +83,20 @@ private final String getBaseUri() {
8583
return baseUri.replace(PORT_PLACEHOLDER, Integer.toString(existWebServer.getPort()));
8684
}
8785

86+
@BeforeClass
87+
public static void prepare() throws IOException {
88+
Path mimeTypesDefinition = tempFolder.getRoot().toPath().resolve("mime-types.xml");
89+
String mimeTypesContent =
90+
"<mime-types default-mime-type=\"foo/bar\" default-resource-type=\"binary\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"schema/mime-types.xsd\">\n" +
91+
"<mime-type name=\"text/html\" type=\"xml\">\n" +
92+
"<description>HTML document</description>\n" +
93+
"<extensions>.html</extensions>\n" +
94+
"</mime-type>\n"+
95+
"</mime-types>";
96+
Files.write(mimeTypesDefinition, mimeTypesContent.getBytes(UTF_8));
97+
MimeTable.getInstance(mimeTypesDefinition);
98+
}
99+
88100
@Test
89101
public void restoreValidZipBackup() throws IOException, XMLDBException {
90102
final Path zipFile = createZipBackupWithValidContent();
@@ -93,8 +105,8 @@ public void restoreValidZipBackup() throws IOException, XMLDBException {
93105

94106
restoreBackup(rootUri, zipFile, null, listener);
95107

96-
assertEquals(5, listener.restored.size());
97-
assertEquals(0, listener.warnings.size());
108+
assertEquals(7, listener.restored.size());
109+
assertEquals(1, listener.warnings.size());
98110
assertEquals(0, listener.errors.size());
99111
}
100112

@@ -106,8 +118,8 @@ public void restoreValidDirBackup() throws IOException, XMLDBException {
106118

107119
restoreBackup(rootUri, contentsFile, null, listener);
108120

109-
assertEquals(5, listener.restored.size());
110-
assertEquals(0, listener.warnings.size());
121+
assertEquals(7, listener.restored.size());
122+
assertEquals(1, listener.warnings.size());
111123
assertEquals(0, listener.errors.size());
112124
}
113125

@@ -181,7 +193,7 @@ public void restoreUserWithoutGroupIsPlacedInNoGroup() throws IOException, XMLDB
181193
final Account account = userManagementService.getAccount(username);
182194
assertNotNull(account);
183195
assertEquals(SecurityManager.UNKNOWN_GROUP, account.getPrimaryGroup());
184-
assertArrayEquals(new String[] { SecurityManager.UNKNOWN_GROUP }, account.getGroups());
196+
assertArrayEquals(new String[]{SecurityManager.UNKNOWN_GROUP}, account.getGroups());
185197
}
186198

187199
@Test
@@ -202,7 +214,7 @@ public void restoreUserWithNoSuchGroupIsPlacedInNoGroup() throws IOException, XM
202214
final Account account = userManagementService.getAccount(username);
203215
assertNotNull(account);
204216
assertEquals(SecurityManager.UNKNOWN_GROUP, account.getPrimaryGroup());
205-
assertArrayEquals(new String[] { SecurityManager.UNKNOWN_GROUP }, account.getGroups());
217+
assertArrayEquals(new String[]{SecurityManager.UNKNOWN_GROUP}, account.getGroups());
206218
}
207219

208220
/**
@@ -251,9 +263,9 @@ public void restoreUserWithGroupsFromDbCollection() throws IOException, XMLDBExc
251263
private void restoreUserWithGroups(final Path backupPath, final Path restorePath, final int expectedRestoredCount) throws IOException, XMLDBException {
252264
final String username = UUID.randomUUID().toString() + "-user";
253265
final String primaryGroup = username; // personal group
254-
final String group1 = UUID.randomUUID().toString() + "-group-1";
255-
final String group2 = UUID.randomUUID().toString() + "-group-2";
256-
final String group3 = UUID.randomUUID().toString() + "-group-3";
266+
final String group1 = UUID.randomUUID().toString() + "-group-1";
267+
final String group2 = UUID.randomUUID().toString() + "-group-2";
268+
final String group3 = UUID.randomUUID().toString() + "-group-3";
257269
final TestRestoreListener listener = new TestRestoreListener();
258270
final XmldbURI rootUri = XmldbURI.create(getBaseUri()).append(XmldbURI.ROOT_COLLECTION_URI);
259271

@@ -269,7 +281,7 @@ private void restoreUserWithGroups(final Path backupPath, final Path restorePath
269281
final Account account = userManagementService.getAccount(username);
270282
assertNotNull(account);
271283
assertEquals(primaryGroup, account.getPrimaryGroup());
272-
assertArrayEquals(new String[] { primaryGroup, group1, group2, group3 }, account.getGroups());
284+
assertArrayEquals(new String[]{primaryGroup, group1, group2, group3}, account.getGroups());
273285
}
274286

275287
private static void restoreBackup(final XmldbURI uri, final Path backup, @Nullable final String backupPassword, final RestoreServiceTaskListener listener) throws XMLDBException {
@@ -305,20 +317,30 @@ private static Path createBackupWithValidContent() throws IOException {
305317
" <resource type=\"XMLResource\" name=\"doc2.xml\" owner=\"admin\" group=\"dba\" mode=\"644\" created=\"2019-05-15T15:58:48.638+04:00\" modified=\"2019-05-15T15:58:48.638+04:00\" filename=\"doc2.xml\" mimetype=\"application/xml\">\n" +
306318
" <acl entries=\"0\" version=\"1\"/>\n" +
307319
" </resource>\n" +
308-
" <resource type=\"XMLResource\" name=\"doc3.xml\" owner=\"admin\" group=\"dba\" mode=\"644\" created=\"2019-05-15T15:58:49.618+04:00\" modified=\"2019-05-15T15:58:49.618+04:00\" filename=\"doc3.xml\" mimetype=\"application/xml\">\n" +
320+
" <resource type=\"XMLResource\" name=\"doc3.xml\" owner=\"admin\" group=\"dba\" mode=\"644\" created=\"2019-05-15T15:58:49.618+04:00\" modified=\"2019-05-15T15:58:49.618+04:00\" filename=\"doc3.xml\" mimetype=\"application/special-xml\">\n" +
321+
" <acl entries=\"0\" version=\"1\"/>\n" +
322+
" </resource>\n" +
323+
" <resource type=\"BinaryResource\" name=\"doc4.html\" owner=\"admin\" group=\"dba\" mode=\"644\" created=\"2019-05-15T15:58:49.618+04:00\" modified=\"2019-05-15T15:58:49.618+04:00\" filename=\"doc4.html\" mimetype=\"text/xhtml\">\n" +
324+
" <acl entries=\"0\" version=\"1\"/>\n" +
325+
" </resource>\n" +
326+
" <resource type=\"BinaryResource\" name=\"doc5.html\" owner=\"admin\" group=\"dba\" mode=\"644\" created=\"2019-05-15T15:58:49.618+04:00\" modified=\"2019-05-15T15:58:49.618+04:00\" filename=\"doc5.html\" mimetype=\"text/html\">\n" +
309327
" <acl entries=\"0\" version=\"1\"/>\n" +
310328
" </resource>\n" +
311329
"</collection>";
312330

313331
final String doc1 = "<doc1/>";
314332
final String doc2 = "<doc2/>";
315333
final String doc3 = "<doc3/>";
334+
final String doc4 = "<html><body><hr/></body></html>";
335+
final String doc5 = "<html><body><hr></body></html>";
316336

317337
final Path dbContentsFile = Files.write(db.resolve(BackupDescriptor.COLLECTION_DESCRIPTOR), dbContents.getBytes(UTF_8));
318338
final Path col1ContentsFile = Files.write(col1.resolve(BackupDescriptor.COLLECTION_DESCRIPTOR), col1Contents.getBytes(UTF_8));
319-
Files.write(col1.resolve("doc1.xml"), doc1.getBytes(UTF_8));
320-
Files.write(col1.resolve("doc2.xml"), doc2.getBytes(UTF_8));
321-
Files.write(col1.resolve("doc3.xml"), doc3.getBytes(UTF_8));
339+
Files.write(col1.resolve("doc1.xml"), doc1.getBytes(UTF_8));
340+
Files.write(col1.resolve("doc2.xml"), doc2.getBytes(UTF_8));
341+
Files.write(col1.resolve("doc3.xml"), doc3.getBytes(UTF_8));
342+
Files.write(col1.resolve("doc4.html"), doc4.getBytes(UTF_8));
343+
Files.write(col1.resolve("doc5.html"), doc5.getBytes(UTF_8));
322344

323345
return dbContentsFile;
324346
}
@@ -335,26 +357,26 @@ private static Path createBackupWithInvalidContent() throws IOException {
335357

336358
final String contents =
337359
"<collection xmlns=\"http://exist.sourceforge.net/NS/exist\" name=\"/db/col1\" owner=\"admin\" group=\"dba\" mode=\"755\" created=\"2019-05-15T15:58:39.385+04:00\" deduplicate-blobs=\"false\" version=\"2\">\n" +
338-
" <acl entries=\"0\" version=\"1\"/>\n" +
339-
" <resource type=\"XMLResource\" name=\"doc1.xml\" owner=\"admin\" group=\"dba\" mode=\"644\" created=\"2019-05-15T15:58:48.638+04:00\" modified=\"2019-05-15T15:58:48.638+04:00\" filename=\"doc1.xml\" mimetype=\"application/xml\">\n" +
340-
" <acl entries=\"0\" version=\"1\"/>\n" +
341-
" </resource>\n" +
342-
" <resource type=\"XMLResource\" name=\"doc2.xml\" owner=\"admin\" group=\"dba\" mode=\"644\" created=\"2019-05-15T15:58:48.638+04:00\" modified=\"2019-05-15T15:58:48.638+04:00\" filename=\"doc2.xml\" mimetype=\"application/xml\">\n" +
343-
" <acl entries=\"0\" version=\"1\"/>\n" +
344-
" </resource>\n" +
345-
" <resource type=\"XMLResource\" name=\"doc3.xml\" owner=\"admin\" group=\"dba\" mode=\"644\" created=\"2019-05-15T15:58:49.618+04:00\" modified=\"2019-05-15T15:58:49.618+04:00\" filename=\"doc3.xml\" mimetype=\"application/xml\">\n" +
346-
" <acl entries=\"0\" version=\"1\"/>\n" +
347-
" </resource>\n" +
348-
"</collection>";
360+
" <acl entries=\"0\" version=\"1\"/>\n" +
361+
" <resource type=\"XMLResource\" name=\"doc1.xml\" owner=\"admin\" group=\"dba\" mode=\"644\" created=\"2019-05-15T15:58:48.638+04:00\" modified=\"2019-05-15T15:58:48.638+04:00\" filename=\"doc1.xml\" mimetype=\"application/xml\">\n" +
362+
" <acl entries=\"0\" version=\"1\"/>\n" +
363+
" </resource>\n" +
364+
" <resource type=\"XMLResource\" name=\"doc2.xml\" owner=\"admin\" group=\"dba\" mode=\"644\" created=\"2019-05-15T15:58:48.638+04:00\" modified=\"2019-05-15T15:58:48.638+04:00\" filename=\"doc2.xml\" mimetype=\"application/xml\">\n" +
365+
" <acl entries=\"0\" version=\"1\"/>\n" +
366+
" </resource>\n" +
367+
" <resource type=\"XMLResource\" name=\"doc3.xml\" owner=\"admin\" group=\"dba\" mode=\"644\" created=\"2019-05-15T15:58:49.618+04:00\" modified=\"2019-05-15T15:58:49.618+04:00\" filename=\"doc3.xml\" mimetype=\"application/xml\">\n" +
368+
" <acl entries=\"0\" version=\"1\"/>\n" +
369+
" </resource>\n" +
370+
"</collection>";
349371

350372
final String doc1 = "<doc1/>";
351373
final String doc2 = "<doc2>invalid";
352374
final String doc3 = "<doc3/>";
353375

354376
final Path contentsFile = Files.write(col1.resolve(BackupDescriptor.COLLECTION_DESCRIPTOR), contents.getBytes(UTF_8));
355-
Files.write(col1.resolve("doc1.xml"), doc1.getBytes(UTF_8));
356-
Files.write(col1.resolve("doc2.xml"), doc2.getBytes(UTF_8));
357-
Files.write(col1.resolve("doc3.xml"), doc3.getBytes(UTF_8));
377+
Files.write(col1.resolve("doc1.xml"), doc1.getBytes(UTF_8));
378+
Files.write(col1.resolve("doc2.xml"), doc2.getBytes(UTF_8));
379+
Files.write(col1.resolve("doc3.xml"), doc3.getBytes(UTF_8));
358380

359381
return contentsFile;
360382
}
@@ -417,10 +439,10 @@ private static Path createBackupWithUserWithoutPrimaryGroup(final String usernam
417439
"<enabled>true</enabled>\n" +
418440
"<umask>022</umask>\n" +
419441
"<name>" + username + "</name>\n" +
420-
"</account>";
442+
"</account>";
421443

422444
final Path contentsFile = Files.write(accountsCol.resolve(BackupDescriptor.COLLECTION_DESCRIPTOR), contents.getBytes(UTF_8));
423-
Files.write(accountsCol.resolve(username + ".xml"), invalidUserDoc.getBytes(UTF_8));
445+
Files.write(accountsCol.resolve(username + ".xml"), invalidUserDoc.getBytes(UTF_8));
424446

425447
return contentsFile;
426448
}
@@ -449,10 +471,10 @@ private static Path createBackupWithUserInNoSuchGroup(final String username) thr
449471
"<enabled>true</enabled>\n" +
450472
"<umask>022</umask>\n" +
451473
"<name>" + username + "</name>\n" +
452-
"</account>\n";
474+
"</account>\n";
453475

454476
final Path contentsFile = Files.write(accountsCol.resolve(BackupDescriptor.COLLECTION_DESCRIPTOR), contents.getBytes(UTF_8));
455-
Files.write(accountsCol.resolve(username + ".xml"), invalidUserDoc.getBytes(UTF_8));
477+
Files.write(accountsCol.resolve(username + ".xml"), invalidUserDoc.getBytes(UTF_8));
456478

457479
return contentsFile;
458480
}
@@ -497,11 +519,11 @@ private static void createBackupWithUserInGroups(final Path backupDir, final Str
497519
for (final String groupName : groupNames) {
498520
groupsContents.append(
499521
" <resource type=\"XMLResource\" name=\"" + groupName + ".xml\" owner=\"SYSTEM\" group=\"dba\" mode=\"770\" created=\"2019-05-15T15:58:48.638+04:00\" modified=\"2019-05-15T15:58:48.638+04:00\" filename=\"" + groupName + ".xml\" mimetype=\"application/xml\">\n" +
500-
" <acl entries=\"0\" version=\"1\"/>\n" +
501-
" </resource>\n");
522+
" <acl entries=\"0\" version=\"1\"/>\n" +
523+
" </resource>\n");
502524
}
503525
groupsContents.append(
504-
"</collection>");
526+
"</collection>");
505527

506528
final String accountsContents =
507529
"<collection xmlns=\"http://exist.sourceforge.net/NS/exist\" name=\"/db/system/security/exist/accounts\" owner=\"SYSTEM\" group=\"dba\" mode=\"770\" created=\"2019-05-15T15:58:39.385+04:00\" deduplicate-blobs=\"false\" version=\"2\">\n" +
@@ -520,14 +542,14 @@ private static void createBackupWithUserInGroups(final Path backupDir, final Str
520542
"<digestPassword>" + backupPasswordDigest + "</digestPassword>\n");
521543
for (final String groupName : groupNames) {
522544
userDoc.append(
523-
"<group name=\"" + groupName + "\"/>\n");
545+
"<group name=\"" + groupName + "\"/>\n");
524546
}
525547
userDoc.append(
526-
"<expired>false</expired>\n" +
548+
"<expired>false</expired>\n" +
527549
"<enabled>true</enabled>\n" +
528550
"<umask>022</umask>\n" +
529551
"<name>" + username + "</name>\n" +
530-
"</account>\n");
552+
"</account>\n");
531553

532554
final Path dbContentsFile = Files.write(dbCol.resolve(BackupDescriptor.COLLECTION_DESCRIPTOR), dbContents.getBytes(UTF_8));
533555
final Path systemContentsFile = Files.write(systemCol.resolve(BackupDescriptor.COLLECTION_DESCRIPTOR), systemContents.getBytes(UTF_8));
@@ -540,15 +562,15 @@ private static void createBackupWithUserInGroups(final Path backupDir, final Str
540562
for (final String groupName : groupNames) {
541563
final String groupDoc =
542564
"<group xmlns=\"http://exist-db.org/Configuration\" id=\"" + (groupId++) + "\">\n" +
543-
" <manager name=\"admin\"/>\n" +
544-
" <metadata key=\"http://exist-db.org/security/description\">Group named: " + groupName + "</metadata>\n" +
545-
" <name>" + groupName + "</name>\n" +
546-
"</group>";
565+
" <manager name=\"admin\"/>\n" +
566+
" <metadata key=\"http://exist-db.org/security/description\">Group named: " + groupName + "</metadata>\n" +
567+
" <name>" + groupName + "</name>\n" +
568+
"</group>";
547569

548570
Files.write(groupsCol.resolve(groupName + ".xml"), groupDoc.getBytes(UTF_8));
549571
}
550572

551-
Files.write(accountsCol.resolve(username + ".xml"), userDoc.toString().getBytes(UTF_8));
573+
Files.write(accountsCol.resolve(username + ".xml"), userDoc.toString().getBytes(UTF_8));
552574
}
553575

554576
private static byte[] ripemd160(final String s) {

0 commit comments

Comments
 (0)