Commit 04d512e4 by Tuomas Riihimäki

Compo fixes, auth fixes, .... fixes

1 parent 2a6710eb
...@@ -83,7 +83,14 @@ public class AuthHelperBean implements AuthHelperBeanLocal { ...@@ -83,7 +83,14 @@ public class AuthHelperBean implements AuthHelperBeanLocal {
// username and domain to initial jaas-login query... // username and domain to initial jaas-login query...
if (restAuthStr != null) { if (restAuthStr != null) {
String decodedStr = new String(Base64.getDecoder().decode(restAuthStr.split(" ")[1]), StandardCharsets.UTF_8); String decodedStr = new String(Base64.getDecoder().decode(restAuthStr.split(" ")[1]), StandardCharsets.UTF_8);
if(!decodedStr.startsWith("appauth:")){
return null;
}
String[] splitStr = decodedStr.split(":"); String[] splitStr = decodedStr.split(":");
logger.warn("SplitDecoded {}", decodedStr);
if(splitStr.length < 3){
return null;
}
appkey = splitStr[1]; appkey = splitStr[1];
userkey = splitStr[2]; userkey = splitStr[2];
// final String appKey = splitStr[3]; // final String appKey = splitStr[3];
......
...@@ -23,15 +23,13 @@ ...@@ -23,15 +23,13 @@
package fi.codecrew.moya.model; package fi.codecrew.moya.model;
import java.security.MessageDigest; import java.time.Instant;
import java.security.NoSuchAlgorithmException; import java.time.ZoneId;
import java.util.Calendar; import java.time.format.DateTimeFormatter;
import java.util.Date; import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.Lob; import javax.persistence.Lob;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
...@@ -39,7 +37,6 @@ import javax.persistence.Table; ...@@ -39,7 +37,6 @@ import javax.persistence.Table;
import javax.persistence.Temporal; import javax.persistence.Temporal;
import javax.persistence.TemporalType; import javax.persistence.TemporalType;
import org.apache.commons.codec.binary.Hex;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -53,6 +50,8 @@ public class CompoEntryFile extends GenericEntity { ...@@ -53,6 +50,8 @@ public class CompoEntryFile extends GenericEntity {
private static final Logger logger = LoggerFactory.getLogger(CompoEntryFile.class); private static final Logger logger = LoggerFactory.getLogger(CompoEntryFile.class);
public static final String DEFAULT_FILENAMEPATTERN = "{entry.id}-{entry.title}-{filetype.name}-v{file.version}-{file.id}{file.origfilename}";
@Column(name = "mime_type") @Column(name = "mime_type")
private String mimeType; private String mimeType;
...@@ -66,21 +65,22 @@ public class CompoEntryFile extends GenericEntity { ...@@ -66,21 +65,22 @@ public class CompoEntryFile extends GenericEntity {
@Column(name = "hash", updatable = false) @Column(name = "hash", updatable = false)
private String hash; private String hash;
@Column(name="filepath", updatable = false, nullable = false) @Column(name = "filepath", updatable = false, nullable = false)
private String filepath; private String filepath;
@Column(name = "uploaded", nullable = false) @Column(name = "uploaded", nullable = false)
@Temporal(TemporalType.TIMESTAMP) @Temporal(TemporalType.TIMESTAMP)
private Date uploaded = new Date(); private Date uploaded = new Date();
@ManyToOne(optional=false) @ManyToOne(optional = false)
@JoinColumn(name="entryfiletype_id", referencedColumnName = "id", nullable = false, updatable = false) @JoinColumn(name = "entryfiletype_id", referencedColumnName = "id", nullable = false, updatable = false)
private CompoEntryFileType filetype; private CompoEntryFileType filetype;
public CompoEntryFile() { public CompoEntryFile() {
super(); super();
} }
public String getMimeType() { public String getMimeType() {
return mimeType; return mimeType;
} }
...@@ -137,4 +137,41 @@ public class CompoEntryFile extends GenericEntity { ...@@ -137,4 +137,41 @@ public class CompoEntryFile extends GenericEntity {
public void setFilepath(String filepath) { public void setFilepath(String filepath) {
this.filepath = filepath; this.filepath = filepath;
} }
public Long getVersionNumber() {
return 1 + getFiletype().getEntryFiles().stream().filter(file -> file.getUploaded().before(getUploaded())).count();
}
public String getFilenameFromPattern(String pattern) {
final CompoEntry entry = getFiletype().getEntry();
final Compo compo = entry.getCompo();
final CompoFileType type = getFiletype().getType();
return pattern
.replace("{file.id}", getId().toString())
.replace("{file.version}", getVersionNumber().toString())
.replace("{file.origfilename}", getFileName())
.replace("{file.hash}", getHash())
.replace("{file.uploaded}", formatDateteime(uploaded))
.replace("{filetype.name}", type.getName())
.replace("{filetype.id}", type.getId().toString())
.replace("{compo.id}", compo.getId().toString())
.replace("{compo.name}", compo.getName())
.replace("{entry.id}", entry.getId().toString())
.replace("{entry.title}", entry.getTitle())
.replace("{entry.sort}", entry.getSort().toString())
.replaceAll("[^0-9a-zA-Z._-]", "_");
}
private static String formatDateteime(Date d) {
return Instant
.ofEpochMilli(d.getTime())
.atZone(ZoneId.systemDefault())
.toOffsetDateTime()
.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
}
} }
...@@ -11,6 +11,9 @@ ...@@ -11,6 +11,9 @@
<h:outputLabel value="#{i18n['vip.host']}" for="host" /> <h:outputLabel value="#{i18n['vip.host']}" for="host" />
<h:outputText id="host" value="#{vipDeliverView.vip.host.wholeName}" /> <h:outputText id="host" value="#{vipDeliverView.vip.host.wholeName}" />
<h:outputLabel for="shortdescr" value="#{i18n['vip.shortdescr']}" />
<h:outputText id="shortdescr" value="#{vipDeliverView.vip.shortdescr}" />
<h:outputLabel for="description" value="#{i18n['vip.description']}" /> <h:outputLabel for="description" value="#{i18n['vip.description']}" />
<h:outputText id="description" value="#{vipDeliverView.vip.description}" /> <h:outputText id="description" value="#{vipDeliverView.vip.description}" />
</h:panelGrid> </h:panelGrid>
......
...@@ -81,6 +81,9 @@ ...@@ -81,6 +81,9 @@
<p:column headerText="CurrentFile"> <p:column headerText="CurrentFile">
<h:outputText value="X" rendered="#{entryEditView.selectedFiletype.currentFile==file}"/> <h:outputText value="X" rendered="#{entryEditView.selectedFiletype.currentFile==file}"/>
</p:column> </p:column>
<p:column headerText="Ver">
<h:outputText value="#{file.versionNumber}"/>
</p:column>
<p:column headerText="#{i18n['compofile.fileName']}"> <p:column headerText="#{i18n['compofile.fileName']}">
<a href="#{request.contextPath}/EntryFile/#{file.id}"> <a href="#{request.contextPath}/EntryFile/#{file.id}">
<h:outputText value="#{file.fileName}"/> <h:outputText value="#{file.fileName}"/>
......
...@@ -23,7 +23,6 @@ import fi.codecrew.moya.beans.auth.AuthHelperBeanLocal; ...@@ -23,7 +23,6 @@ import fi.codecrew.moya.beans.auth.AuthHelperBeanLocal;
import fi.codecrew.moya.clientutils.BortalLocalContextHolder; import fi.codecrew.moya.clientutils.BortalLocalContextHolder;
import fi.codecrew.moya.model.User; import fi.codecrew.moya.model.User;
import fi.codecrew.moya.rest.RestApplicationEntrypoint; import fi.codecrew.moya.rest.RestApplicationEntrypoint;
import fi.codecrew.moya.utilities.RestAuthHandler;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.slf4j.MDC; import org.slf4j.MDC;
...@@ -167,7 +166,6 @@ public class HostnameFilter implements Filter { ...@@ -167,7 +166,6 @@ public class HostnameFilter implements Filter {
try { try {
httpRequest = (HttpServletRequest) request; httpRequest = (HttpServletRequest) request;
insertServerLoggingContext(httpRequest, authtype); insertServerLoggingContext(httpRequest, authtype);
logger.info("Logging in with username {} and password {}, remote {}, authtype: {}", httpRequest.getUserPrincipal(), httpRequest.getRemoteUser(), httpRequest.getAuthType());
String hostname = authHelper.parseHostname(httpRequest); String hostname = authHelper.parseHostname(httpRequest);
......
...@@ -44,7 +44,7 @@ import javax.ws.rs.core.Response; ...@@ -44,7 +44,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.Response.Status;
import fi.codecrew.moya.beans.auth.AuthHelperBean; import fi.codecrew.moya.beans.auth.AuthHelperBeanLocal;
import fi.codecrew.moya.model.*; import fi.codecrew.moya.model.*;
import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
...@@ -108,7 +108,7 @@ public class UserRestView { ...@@ -108,7 +108,7 @@ public class UserRestView {
@EJB @EJB
private PlaceBeanLocal placebean; private PlaceBeanLocal placebean;
@EJB @EJB
private AuthHelperBean authHelperBean; private AuthHelperBeanLocal authHelperBean;
@POST @POST
@Path("/giveplace/{placeId}") @Path("/giveplace/{placeId}")
......
...@@ -86,22 +86,20 @@ public class EventInfoV1 { ...@@ -86,22 +86,20 @@ public class EventInfoV1 {
String authStr = new String(Base64.getDecoder().decode(authHeader.substring(AUTH_PREFIX.length()))); String authStr = new String(Base64.getDecoder().decode(authHeader.substring(AUTH_PREFIX.length())));
String[] splitAuth = authStr.split(":", 2); String[] splitAuth = authStr.split(":", 2);
Principal principal = servletRequest.getUserPrincipal();
// ensure logged out user
if (principal != null && principal.getName() != null) {
servletRequest.logout();
}
String domain = authHelperBean.parseHostname(servletRequest); String domain = authHelperBean.parseHostname(servletRequest);
username = splitAuth[0] + "@" + domain; username = splitAuth[0] + "@" + domain;
password = splitAuth[1]; password = splitAuth[1];
} }
Principal principal = servletRequest.getUserPrincipal();
// ensure logged out user
if (principal != null && principal.getName() != null) {
servletRequest.logout();
}
servletRequest.getSession(true); servletRequest.getSession(true);
servletRequest.login(username, password); servletRequest.login(username, password);
} }
return Response.ok(PojoUtils.parseEvents(eventBean.findAllEventsForCurrentUser())).build(); return Response.ok(PojoUtils.parseEvents(eventBean.findAllEventsForCurrentUser())).build();
} catch (ServletException e) { } catch (ServletException e) {
......
...@@ -9,6 +9,7 @@ import org.apache.commons.fileupload.FileItemStream; ...@@ -9,6 +9,7 @@ import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams; import org.apache.commons.fileupload.util.Streams;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -22,6 +23,15 @@ import javax.servlet.http.HttpServletResponse; ...@@ -22,6 +23,15 @@ import javax.servlet.http.HttpServletResponse;
import java.io.*; import java.io.*;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@WebServlet(value = "/EntryFile/*") @WebServlet(value = "/EntryFile/*")
public class CompoEntryFileServlet extends HttpServlet { public class CompoEntryFileServlet extends HttpServlet {
...@@ -42,8 +52,82 @@ public class CompoEntryFileServlet extends HttpServlet { ...@@ -42,8 +52,82 @@ public class CompoEntryFileServlet extends HttpServlet {
@Override @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
if (req.getPathInfo().startsWith("/compozip/")) {
int compoid = Integer.parseUnsignedInt(req.getPathInfo().replace("/compozip/", ""));
getCompoEntriesZip(req, resp, compoid);
} else {
int fileId = Integer.parseUnsignedInt(req.getPathInfo().substring(1)); int fileId = Integer.parseUnsignedInt(req.getPathInfo().substring(1));
getEntryFile(req, resp, fileId);
return;
}
}
private static String formatDateteime(Date d) {
return Instant
.ofEpochMilli(d.getTime())
.atZone(ZoneId.systemDefault())
.toOffsetDateTime()
.format(DateTimeFormatter.ISO_INSTANT);
}
public static String trimFilename(Object ... parts) {
StringBuilder sb = new StringBuilder();
for(Object i: parts){
sb.append(i.toString());
}
return sb.toString().trim().replaceAll("[^0-9a-zA-Z._-]","_");
}
private void getCompoEntriesZip(HttpServletRequest req, HttpServletResponse resp, int compoid) throws IOException {
Compo compo = votebean.getCompoById(compoid);
resp.setContentType("application/zip");
resp.setHeader("Content-Disposition", "filename=\"" + trimFilename("compofiles_", compo.getId(), "_",compo.getName(),OffsetDateTime.now().format(DateTimeFormatter.ISO_INSTANT)) + ".zip\"");
String filepattern = req.getParameter("filenamepattern");
if (filepattern == null || filepattern.isEmpty()) {
filepattern = CompoEntryFile.DEFAULT_FILENAMEPATTERN;
}
ZipOutputStream zos = new ZipOutputStream(resp.getOutputStream());
byte[] buff = new byte[1024 * 8];
for (CompoEntry e : compo.getCompoEntries()) {
for (CompoEntryFileType ft : e.getFiletypes()) {
if (ft.getCurrentFile() == null) {
continue;
}
CompoEntryFile file = ft.getCurrentFile();
ZipEntry zipEntry = new ZipEntry(file.getFilenameFromPattern(filepattern));
zos.putNextEntry(zipEntry);
FileInputStream fstream = new FileInputStream(new File(getCompofileDir(), file.getFilepath()));
try {
copyStream(fstream, zos, buff);
} finally {
fstream.close();
}
}
}
zos.close();
}
public File getCompofileDir() {
return new File(SystemProperty.MOYA_COMPOFILE_DIR.getValueOrDefault());
}
public static void copyStream(InputStream istream, OutputStream ostream, byte[] buff) throws IOException {
while (true) {
int len = istream.read(buff);
if (len < 1) {
break;
}
ostream.write(buff, 0, len);
}
}
private void getEntryFile(HttpServletRequest req, HttpServletResponse resp, int fileId) throws IOException {
Set<Closeable> closeables = new HashSet<>();
try {
CompoEntryFile entry = votebean.findEntryFile(fileId); CompoEntryFile entry = votebean.findEntryFile(fileId);
if (entry == null) { if (entry == null) {
resp.setStatus(HttpServletResponse.SC_NOT_FOUND); resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
...@@ -52,31 +136,39 @@ public class CompoEntryFileServlet extends HttpServlet { ...@@ -52,31 +136,39 @@ public class CompoEntryFileServlet extends HttpServlet {
} }
File file = new File(new File(SystemProperty.MOYA_COMPOFILE_DIR.getValueOrDefault()), entry.getFilepath()); File file = new File(getCompofileDir(), entry.getFilepath());
resp.setContentType(entry.getMimeType()); resp.setContentType(entry.getMimeType());
resp.setHeader("Content-Disposition", "filename=\"" + entry.getFileName() + "\""); resp.setHeader("Content-Disposition", "filename=\"" + entry.getFilenameFromPattern(entry.DEFAULT_FILENAMEPATTERN) + "\"");
resp.setContentLength((int) file.length()); resp.setContentLength((int) file.length());
FileInputStream inStream = new FileInputStream(file); FileInputStream inStream = new FileInputStream(file);
ServletOutputStream oStream = resp.getOutputStream(); ServletOutputStream oStream = resp.getOutputStream();
closeables.add(inStream);
closeables.add(oStream);
final byte[] buff = new byte[8192]; final byte[] buff = new byte[8192];
while (true) { copyStream(inStream, oStream, buff);
int len = inStream.read(buff); } finally {
if (len < 1) { for (Closeable c : closeables) {
break; try {
c.close();
} catch (Exception e) {
logger.warn("Error closing stream", e);
// Do not error on closing stream
} }
oStream.write(buff, 0, len);
} }
oStream.close(); }
} }
@Override @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
File dir = new File(SystemProperty.MOYA_COMPOFILE_DIR.getValueOrDefault()); File dir = new File(SystemProperty.MOYA_COMPOFILE_DIR.getValueOrDefault());
if (!dir.isDirectory()) { if (!dir.isDirectory()) {
dir.mkdirs(); if (!dir.mkdirs() && !dir.isDirectory()) {
throw new IOException("Unable to create destination directory: '" + dir.getAbsolutePath() + "'");
}
} }
boolean isMultipart = ServletFileUpload.isMultipartContent(req); boolean isMultipart = ServletFileUpload.isMultipartContent(req);
...@@ -103,6 +195,7 @@ public class CompoEntryFileServlet extends HttpServlet { ...@@ -103,6 +195,7 @@ public class CompoEntryFileServlet extends HttpServlet {
FileItemStream item = iter.next(); FileItemStream item = iter.next();
String name = item.getFieldName(); String name = item.getFieldName();
InputStream stream = item.openStream(); InputStream stream = item.openStream();
try {
if (item.isFormField()) { if (item.isFormField()) {
final String data = Streams.asString(stream); final String data = Streams.asString(stream);
...@@ -122,6 +215,7 @@ public class CompoEntryFileServlet extends HttpServlet { ...@@ -122,6 +215,7 @@ public class CompoEntryFileServlet extends HttpServlet {
MessageDigest algo = MessageDigest.getInstance("SHA"); MessageDigest algo = MessageDigest.getInstance("SHA");
FileOutputStream ostream = new FileOutputStream(tmpFile); FileOutputStream ostream = new FileOutputStream(tmpFile);
try {
while (true) { while (true) {
int len = stream.read(buff); int len = stream.read(buff);
if (len < 1) { if (len < 1) {
...@@ -132,20 +226,25 @@ public class CompoEntryFileServlet extends HttpServlet { ...@@ -132,20 +226,25 @@ public class CompoEntryFileServlet extends HttpServlet {
} }
String shasum = new String(Hex.encodeHex(algo.digest())).toLowerCase(); String shasum = new String(Hex.encodeHex(algo.digest())).toLowerCase();
logger.warn("File shasum " + shasum); logger.warn("File shasum " + shasum);
ostream.close();
entryfile.setFileName(item.getName()); entryfile.setFileName(item.getName());
entryfile.setMimeType(item.getContentType()); entryfile.setMimeType(item.getContentType());
entryfile.setHash(shasum); entryfile.setHash(shasum);
} finally {
ostream.close();
}
} }
} finally {
stream.close(); stream.close();
} }
}
CompoEntryFileType ft = votebean.findEntryFileType(entryId, typeId); CompoEntryFileType ft = votebean.findEntryFileType(entryId, typeId);
String ftPath = mkEntryFiletypePath(ft); String ftPath = mkEntryFiletypePath(ft);
File filetypepath = new File(dir, ftPath); File filetypepath = new File(dir, ftPath);
if (!filetypepath.isDirectory()) { if (!filetypepath.isDirectory()) {
filetypepath.mkdirs(); if (!filetypepath.mkdirs() && !filetypepath.isDirectory()) {
throw new IOException("Could not create directory: " + filetypepath.getAbsolutePath());
}
} }
String filePath = ftPath + mkPath(entryfile.getUploaded().getTime() + "_" + entryfile.getFileName()) + ".dat"; String filePath = ftPath + mkPath(entryfile.getUploaded().getTime() + "_" + entryfile.getFileName()) + ".dat";
logger.warn("Target file: {}, ftpath {}", filePath, ftPath); logger.warn("Target file: {}, ftpath {}", filePath, ftPath);
...@@ -162,11 +261,14 @@ public class CompoEntryFileServlet extends HttpServlet { ...@@ -162,11 +261,14 @@ public class CompoEntryFileServlet extends HttpServlet {
} catch (FileUploadException e) { } catch (FileUploadException e) {
logger.warn("Error uploading streaming file", e); logger.warn("Error uploading streaming file", e);
throw new IOException("Error uploading file");
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
logger.warn("Error calculating checksum", e); logger.warn("Error calculating checksum", e);
throw new IOException("Error uploading file");
} }
} }
/*
String asString(InputStream stream) throws IOException { String asString(InputStream stream) throws IOException {
final byte[] buff = new byte[100]; final byte[] buff = new byte[100];
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
...@@ -180,7 +282,7 @@ public class CompoEntryFileServlet extends HttpServlet { ...@@ -180,7 +282,7 @@ public class CompoEntryFileServlet extends HttpServlet {
} }
return baos.toString(); return baos.toString();
} }
*/
public static void main(String[] asd) { public static void main(String[] asd) {
logger.warn("asda {}", mkPath("Foo", "[]{}äöherp", "1239KKKKK")); logger.warn("asda {}", mkPath("Foo", "[]{}äöherp", "1239KKKKK"));
} }
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!