[issue-18924] - changes in review, and added possibility to insert a name along with URL

This commit is contained in:
GuiLeme 2023-10-19 10:27:38 -03:00
parent a22068be18
commit d6670a4145
4 changed files with 73 additions and 13 deletions

View File

@ -2,11 +2,14 @@ package org.bigbluebutton.api;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.UUID; import java.util.UUID;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
public final class Util { public final class Util {
@ -50,8 +53,19 @@ public final class Util {
return DigestUtils.sha1Hex(presFilename + uuid) + "-" + timestamp; return DigestUtils.sha1Hex(presFilename + uuid) + "-" + timestamp;
} }
public static String extractFilenameFromUrl(String preUploadedPresentation) throws MalformedURLException {
URL url = new URL(preUploadedPresentation);
String filename = FilenameUtils.getName(url.getPath());
String extension = FilenameUtils.getExtension(url.getPath());
if (extension == null || extension.isEmpty()) return null;
return filename;
}
public static String createNewFilename(String presId, String fileExt) { public static String createNewFilename(String presId, String fileExt) {
return presId + "." + fileExt; if (!fileExt.isEmpty()) {
return presId + "." + fileExt;
} else {
return presId;
}
} }
public static File createPresentationDir(String meetingId, String presentationDir, String presentationId) { public static File createPresentationDir(String meetingId, String presentationDir, String presentationId) {

View File

@ -1,5 +1,7 @@
package org.bigbluebutton.presentation; package org.bigbluebutton.presentation;
import org.bigbluebutton.api.domain.Extension;
import java.util.*; import java.util.*;
import static org.bigbluebutton.presentation.FileTypeConstants.*; import static org.bigbluebutton.presentation.FileTypeConstants.*;
@ -44,6 +46,15 @@ public class MimeTypeUtils {
} }
}; };
public String getExtensionBasedOnMimeType(String mimeType) {
return EXTENSIONS_MIME.entrySet()
.stream()
.filter(entry -> entry.getValue().contains(mimeType))
.map(Map.Entry::getKey)
.findFirst()
.orElse(null);
}
public Boolean extensionMatchMimeType(String mimeType, String finalExtension) { public Boolean extensionMatchMimeType(String mimeType, String finalExtension) {
finalExtension = finalExtension.toLowerCase(); finalExtension = finalExtension.toLowerCase();

View File

@ -108,14 +108,21 @@ public final class SupportedFileTypes {
return ""; return "";
} }
public static String detectFileExtensionBasedOnMimeType(File pres) {
String mimeType = detectMimeType(pres);
return mimeTypeUtils.getExtensionBasedOnMimeType(mimeType);
}
public static Boolean isPresentationMimeTypeValid(File pres, String fileExtension) { public static Boolean isPresentationMimeTypeValid(File pres, String fileExtension) {
String mimeType = detectMimeType(pres); String mimeType = detectMimeType(pres);
if (mimeType.equals("")) { if (mimeType.equals("")) {
log.error("Not able to detect mimeType.");
return false; return false;
} }
if (!mimeTypeUtils.getValidMimeTypes().contains(mimeType)) { if (!mimeTypeUtils.getValidMimeTypes().contains(mimeType)) {
log.error("MimeType is not valid for this meeting, [{}]", mimeType);
return false; return false;
} }

View File

@ -44,7 +44,7 @@ import org.bigbluebutton.web.services.turn.TurnEntry
import org.bigbluebutton.web.services.turn.StunServer import org.bigbluebutton.web.services.turn.StunServer
import org.bigbluebutton.web.services.turn.RemoteIceCandidate import org.bigbluebutton.web.services.turn.RemoteIceCandidate
import org.json.JSONArray import org.json.JSONArray
import org.apache.commons.io.FilenameUtils
import javax.servlet.ServletRequest import javax.servlet.ServletRequest
class ApiController { class ApiController {
@ -1383,17 +1383,27 @@ class ApiController {
String[] pu = request.getParameterMap().get("preUploadedPresentation") String[] pu = request.getParameterMap().get("preUploadedPresentation")
String[] puName = request.getParameterMap().get("preUploadedPresentationName")
if (pu != null) { if (pu != null) {
String preUploadedPresentation = pu[0] String preUploadedPresentation = pu[0]
hasPresentationUrlInParameter = true hasPresentationUrlInParameter = true
def xmlString = new StringWriter() def xmlString = new StringWriter()
def xml = new MarkupBuilder(xmlString) def xml = new MarkupBuilder(xmlString)
String filename
if (puName == null) {
filename = Util.extractFilenameFromUrl(preUploadedPresentation)
if (filename == null) {
filename = "untitled"
}
} else {
filename = puName[0]
}
xml.document ( xml.document (
removable: "true", removable: "true",
downloadable: "false", downloadable: "false",
url: preUploadedPresentation, url: preUploadedPresentation,
filename: extractFilenameFromUrl(preUploadedPresentation), filename: filename,
name: extractFilenameFromUrl(preUploadedPresentation) isPreUploadedPresentationFromParameter: "true"
) )
def parsedXml = new XmlSlurper().parseText(xmlString.toString()) def parsedXml = new XmlSlurper().parseText(xmlString.toString())
@ -1454,6 +1464,7 @@ class ApiController {
def Boolean isRemovable = true; def Boolean isRemovable = true;
def Boolean isDownloadable = false; def Boolean isDownloadable = false;
def Boolean isInitialPresentation = false; def Boolean isInitialPresentation = false;
def Boolean isPreUploadedPresentationFromParameter = false
if (document.name != null && "default".equals(document.name)) { if (document.name != null && "default".equals(document.name)) {
if (presentationService.defaultUploadedPresentation) { if (presentationService.defaultUploadedPresentation) {
@ -1462,11 +1473,15 @@ class ApiController {
} }
downloadAndProcessDocument(presentationService.defaultUploadedPresentation, conf.getInternalId(), downloadAndProcessDocument(presentationService.defaultUploadedPresentation, conf.getInternalId(),
document.current /* default presentation */, '', false, document.current /* default presentation */, '', false,
true, isInitialPresentation); true, isInitialPresentation, isPreUploadedPresentationFromParameter);
} else { } else {
log.error "Default presentation could not be read, it is (" + presentationService.defaultUploadedPresentation + ")", "error" log.error "Default presentation could not be read, it is (" + presentationService.defaultUploadedPresentation + ")", "error"
} }
} else { } else {
if (!StringUtils.isEmpty(document.@isPreUploadedPresentationFromParameter.toString())) {
isPreUploadedPresentationFromParameter = java.lang.Boolean.parseBoolean(
document.@isPreUploadedPresentationFromParameter.toString());
}
// Extracting all properties inside the xml // Extracting all properties inside the xml
if (!StringUtils.isEmpty(document.@removable.toString())) { if (!StringUtils.isEmpty(document.@removable.toString())) {
isRemovable = java.lang.Boolean.parseBoolean(document.@removable.toString()); isRemovable = java.lang.Boolean.parseBoolean(document.@removable.toString());
@ -1493,7 +1508,7 @@ class ApiController {
fileName = document.@filename.toString(); fileName = document.@filename.toString();
} }
downloadAndProcessDocument(document.@url.toString(), conf.getInternalId(), isCurrent /* default presentation */, downloadAndProcessDocument(document.@url.toString(), conf.getInternalId(), isCurrent /* default presentation */,
fileName, isDownloadable, isRemovable, isInitialPresentation); fileName, isDownloadable, isRemovable, isInitialPresentation, isPreUploadedPresentationFromParameter);
} else if (!StringUtils.isEmpty(document.@name.toString())) { } else if (!StringUtils.isEmpty(document.@name.toString())) {
def b64 = new Base64() def b64 = new Base64()
def decodedBytes = b64.decode(document.text().getBytes()) def decodedBytes = b64.decode(document.text().getBytes())
@ -1507,10 +1522,6 @@ class ApiController {
return true return true
} }
def extractFilenameFromUrl(String url) {
return url.split('/')[-1]
}
def processDocumentFromRawBytes(bytes, presOrigFilename, meetingId, current, isDownloadable, isRemovable, def processDocumentFromRawBytes(bytes, presOrigFilename, meetingId, current, isDownloadable, isRemovable,
isInitialPresentation) { isInitialPresentation) {
def uploadFailed = false def uploadFailed = false
@ -1567,7 +1578,8 @@ class ApiController {
} }
} }
def downloadAndProcessDocument(address, meetingId, current, fileName, isDownloadable, isRemovable, isInitialPresentation) { def downloadAndProcessDocument(address, meetingId, current, fileName, isDownloadable, isRemovable,
isInitialPresentation, isPreUploadedPresentationFromParameter) {
log.debug("ApiController#downloadAndProcessDocument(${address}, ${meetingId}, ${fileName})"); log.debug("ApiController#downloadAndProcessDocument(${address}, ${meetingId}, ${fileName})");
String presOrigFilename; String presOrigFilename;
if (StringUtils.isEmpty(fileName)) { if (StringUtils.isEmpty(fileName)) {
@ -1592,7 +1604,7 @@ class ApiController {
def pres = null def pres = null
def presId def presId
if (presFilename == "" || filenameExt == "") { if (presFilename == "" || (filenameExt == "" && !isPreUploadedPresentationFromParameter)) {
log.debug("presentation is null by default") log.debug("presentation is null by default")
return return
} else { } else {
@ -1609,6 +1621,22 @@ class ApiController {
uploadFailReasons.add("failed_to_download_file") uploadFailReasons.add("failed_to_download_file")
uploadFailed = true uploadFailed = true
} }
if (isPreUploadedPresentationFromParameter && filenameExt.isEmpty()) {
String fileExtension = SupportedFileTypes.detectFileExtensionBasedOnMimeType(pres)
newFilename = Util.createNewFilename(presId, fileExtension)
newFilePath = uploadDir.absolutePath + File.separatorChar + newFilename
File destination = new File(newFilePath)
filenameExt = fileExtension
presFilename = Util.createNewFilename(presFilename, fileExtension)
if (pres.renameTo(destination)) {
log.info("Presentation coming from URL parameter is at ${destination.getAbsolutePath()}")
pres = destination
} else {
log.error("Error while renaming presentation from URL parameter to ${destination.getAbsolutePath()}, " +
"consider sending it through `/insertDocument`")
}
}
} else { } else {
log.error("Null presentation directory meeting=[${meetingId}], presentationDir=[${presentationDir}], presId=[${presId}]") log.error("Null presentation directory meeting=[${meetingId}], presentationDir=[${presentationDir}], presId=[${presId}]")
uploadFailReasons.add("null_presentation_dir") uploadFailReasons.add("null_presentation_dir")