parent
99a189534b
commit
3a72c79cd8
|
|
@ -20,6 +20,8 @@ package org.libreccm.api.themes;
|
|||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.hibernate.engine.jdbc.internal.BinaryStreamImpl;
|
||||
import org.libreccm.core.UnexpectedErrorException;
|
||||
import org.libreccm.security.AuthorizationRequired;
|
||||
import org.libreccm.security.RequiresPrivilege;
|
||||
import org.libreccm.theming.ThemeFileInfo;
|
||||
|
|
@ -28,17 +30,27 @@ import org.libreccm.theming.ThemeProvider;
|
|||
import org.libreccm.theming.ThemeVersion;
|
||||
import org.libreccm.theming.ThemingPrivileges;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.rmi.UnexpectedException;
|
||||
import java.security.DigestInputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
|
|
@ -497,12 +509,85 @@ public class Themes implements Serializable {
|
|||
)
|
||||
);
|
||||
|
||||
// Read every file from ZIP
|
||||
// Try to find file in theme
|
||||
// Create or update file in theme
|
||||
// remove files not in ZIP from theme
|
||||
final Set<String> pathsInTheme = createThemeFilesSet(
|
||||
provider, themeName
|
||||
);
|
||||
|
||||
throw new UnsupportedOperationException();
|
||||
try (
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(updatedTheme);
|
||||
ZipInputStream zis = new ZipInputStream(bais)) {
|
||||
ZipEntry entry = zis.getNextEntry();
|
||||
while (entry != null) {
|
||||
final String path = entry.getName();
|
||||
entry = zis.getNextEntry();
|
||||
if (pathsInTheme.contains(path)) {
|
||||
final ByteArrayOutputStream zipBaos
|
||||
= new ByteArrayOutputStream();
|
||||
byte[] zipBuffer = new byte[1024];
|
||||
int zipRead = zis.read(zipBuffer, 0, 1024);
|
||||
while (zipRead != -1) {
|
||||
zipBaos.writeBytes(zipBuffer);
|
||||
zipRead = zis.read(zipBuffer, 0, 1024);
|
||||
}
|
||||
|
||||
final byte[] bytesFromZip = zipBaos.toByteArray();
|
||||
|
||||
final InputStream inputStream = provider
|
||||
.getThemeFileAsStream(
|
||||
themeName, ThemeVersion.DRAFT, path
|
||||
)
|
||||
.orElseThrow(() -> new UnexpectedErrorException());
|
||||
final ByteArrayOutputStream themeBaos
|
||||
= new ByteArrayOutputStream();
|
||||
byte[] themeBuffer = new byte[1024];
|
||||
int themeRead = inputStream.read(themeBuffer);
|
||||
while (themeRead != -1) {
|
||||
themeBaos.writeBytes(zipBuffer);
|
||||
themeRead = inputStream.read(themeBuffer);
|
||||
}
|
||||
|
||||
final byte[] bytesFromTheme = themeBaos.toByteArray();
|
||||
|
||||
final byte[] fromZipChecksum = MessageDigest
|
||||
.getInstance("SHA-256")
|
||||
.digest(bytesFromZip);
|
||||
final byte[] fromThemeChecksum = MessageDigest
|
||||
.getInstance("SHA-256")
|
||||
.digest(bytesFromTheme);
|
||||
|
||||
if (!MessageDigest.isEqual(
|
||||
fromZipChecksum, fromThemeChecksum
|
||||
)) {
|
||||
try(OutputStream outputStream = provider
|
||||
.getOutputStreamForThemeFile(themeName, path)) {
|
||||
outputStream.write(bytesFromZip);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
copyFileFromZipToTheme(
|
||||
zis,
|
||||
provider,
|
||||
themeName,
|
||||
path
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (final String path : pathsInTheme) {
|
||||
provider.deleteThemeFile(themeName, path);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
throw new UnexpectedErrorException(
|
||||
String.format("Failed to update theme %s", themeName),
|
||||
ex
|
||||
);
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
throw new UnexpectedErrorException(
|
||||
"Message digest SHA-256 is not available.", ex
|
||||
);
|
||||
}
|
||||
|
||||
return Response.ok().build();
|
||||
}
|
||||
|
||||
private String getProviderName(final ThemeProvider provider) {
|
||||
|
|
@ -592,4 +677,50 @@ public class Themes implements Serializable {
|
|||
);
|
||||
}
|
||||
|
||||
private SortedSet<String> createThemeFilesSet(
|
||||
final ThemeProvider provider, final String themeName
|
||||
) {
|
||||
return createThemeFilesSet(provider, themeName, "/");
|
||||
}
|
||||
|
||||
private SortedSet<String> createThemeFilesSet(
|
||||
final ThemeProvider provider,
|
||||
final String themeName,
|
||||
final String currentPath
|
||||
) {
|
||||
final SortedSet<String> files = new TreeSet<>();
|
||||
final List<ThemeFileInfo> filesInfo = provider
|
||||
.listThemeFiles(themeName, ThemeVersion.DRAFT, currentPath);
|
||||
for (final ThemeFileInfo fileInfo : filesInfo) {
|
||||
final String filePath = String.format(
|
||||
"%s/%s", currentPath, fileInfo.getName()
|
||||
);
|
||||
files.add(filePath);
|
||||
if (fileInfo.isDirectory()) {
|
||||
final Set<String> subFiles = createThemeFilesSet(
|
||||
provider, themeName, filePath);
|
||||
files.addAll(subFiles);
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
private void copyFileFromZipToTheme(
|
||||
final ZipInputStream zis,
|
||||
final ThemeProvider themeProvider,
|
||||
final String themeName,
|
||||
final String path
|
||||
) throws IOException {
|
||||
try (OutputStream outputStream = themeProvider
|
||||
.getOutputStreamForThemeFile(themeName, path)) {
|
||||
final byte[] buffer = new byte[1024];
|
||||
int read = zis.read(buffer, 0, 1024);
|
||||
while (read != -1) {
|
||||
outputStream.write(buffer);
|
||||
read = zis.read(buffer, 0, 1024);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue