Skip to content
Snippets Groups Projects
Commit 939fdd9b authored by Tainan Felipe's avatar Tainan Felipe
Browse files

Merge remote-tracking branch 'upstream/develop' into virtualized-userlist

parents 04535332 9bdaf396
No related branches found
No related tags found
No related merge requests found
Showing
with 416 additions and 37 deletions
...@@ -21,6 +21,7 @@ HOW TO WRITE A GOOD PULL REQUEST? ...@@ -21,6 +21,7 @@ HOW TO WRITE A GOOD PULL REQUEST?
### Closes Issue(s) ### Closes Issue(s)
closes #...
<!-- List here all the issues closed by this pull request. Use keyword `closes` before each issue number --> <!-- List here all the issues closed by this pull request. Use keyword `closes` before each issue number -->
### Motivation ### Motivation
......
# Security Policy
## Supported Versions
We actively support BigBlueButton through the community forums and through security updates.
| Version | Supported |
| ------- | ------------------ |
| 2.0.x (or earlier) | :x: |
| 2.2.x | :white_check_mark: |
| 2.3-dev | :white_check_mark: |
## Reporting a Vulnerability
If you believe you have found a security vunerability in BigBlueButton please let us know directly by e-mailing security@bigbluebutton.org with as much detail as possible.
Regards,... [BigBlueButton Team](https://docs.bigbluebutton.org/support/faq.html#bigbluebutton-committer)
...@@ -21,7 +21,7 @@ object Dependencies { ...@@ -21,7 +21,7 @@ object Dependencies {
val apacheHttpAsync = "4.1.4" val apacheHttpAsync = "4.1.4"
// Office and document conversion // Office and document conversion
val jodConverter = "4.2.1" val jodConverter = "4.3.0"
val apachePoi = "4.1.2" val apachePoi = "4.1.2"
val nuProcess = "1.2.4" val nuProcess = "1.2.4"
val libreOffice = "5.4.2" val libreOffice = "5.4.2"
......
...@@ -36,6 +36,10 @@ public class ApiErrors { ...@@ -36,6 +36,10 @@ public class ApiErrors {
errors.add(new String[] {"NotUniqueMeetingID", "A meeting already exists with that meeting ID. Please use a different meeting ID."}); errors.add(new String[] {"NotUniqueMeetingID", "A meeting already exists with that meeting ID. Please use a different meeting ID."});
} }
public void nonUniqueVoiceBridgeError() {
errors.add(new String[] {"nonUniqueVoiceBridge", "The selected voice bridge is already in use."});
}
public void invalidMeetingIdError() { public void invalidMeetingIdError() {
errors.add(new String[] {"invalidMeetingId", "The meeting ID that you supplied did not match any existing meetings"}); errors.add(new String[] {"invalidMeetingId", "The meeting ID that you supplied did not match any existing meetings"});
} }
......
...@@ -277,8 +277,10 @@ public class MeetingService implements MessageListener { ...@@ -277,8 +277,10 @@ public class MeetingService implements MessageListener {
public synchronized boolean createMeeting(Meeting m) { public synchronized boolean createMeeting(Meeting m) {
String internalMeetingId = paramsProcessorUtil.convertToInternalMeetingId(m.getExternalId()); String internalMeetingId = paramsProcessorUtil.convertToInternalMeetingId(m.getExternalId());
Meeting existing = getNotEndedMeetingWithId(internalMeetingId); Meeting existingId = getNotEndedMeetingWithId(internalMeetingId);
if (existing == null) { Meeting existingTelVoice = getNotEndedMeetingWithTelVoice(m.getTelVoice());
Meeting existingWebVoice = getNotEndedMeetingWithWebVoice(m.getWebVoice());
if (existingId == null && existingTelVoice == null && existingWebVoice == null) {
meetings.put(m.getInternalId(), m); meetings.put(m.getInternalId(), m);
handle(new CreateMeeting(m)); handle(new CreateMeeting(m));
return true; return true;
...@@ -437,6 +439,32 @@ public class MeetingService implements MessageListener { ...@@ -437,6 +439,32 @@ public class MeetingService implements MessageListener {
return null; return null;
} }
public Meeting getNotEndedMeetingWithTelVoice(String telVoice) {
if (telVoice == null)
return null;
for (Map.Entry<String, Meeting> entry : meetings.entrySet()) {
Meeting m = entry.getValue();
if (telVoice.equals(m.getTelVoice())) {
if (!m.isForciblyEnded())
return m;
}
}
return null;
}
public Meeting getNotEndedMeetingWithWebVoice(String webVoice) {
if (webVoice == null)
return null;
for (Map.Entry<String, Meeting> entry : meetings.entrySet()) {
Meeting m = entry.getValue();
if (webVoice.equals(m.getWebVoice())) {
if (!m.isForciblyEnded())
return m;
}
}
return null;
}
public Boolean validateTextTrackSingleUseToken(String recordId, String caption, String token) { public Boolean validateTextTrackSingleUseToken(String recordId, String caption, String token) {
return recordingService.validateTextTrackSingleUseToken(recordId, caption, token); return recordingService.validateTextTrackSingleUseToken(recordId, caption, token);
} }
......
...@@ -362,7 +362,7 @@ public class Meeting { ...@@ -362,7 +362,7 @@ public class Meeting {
} else if (GuestPolicy.ALWAYS_DENY.equals(guestPolicy)) { } else if (GuestPolicy.ALWAYS_DENY.equals(guestPolicy)) {
return GuestPolicy.DENY; return GuestPolicy.DENY;
} else if (GuestPolicy.ASK_MODERATOR.equals(guestPolicy)) { } else if (GuestPolicy.ASK_MODERATOR.equals(guestPolicy)) {
if (guest || (!ROLE_MODERATOR.equals(role) && !authned)) { if (guest || (!ROLE_MODERATOR.equals(role) && authned)) {
return GuestPolicy.WAIT ; return GuestPolicy.WAIT ;
} }
return GuestPolicy.ALLOW; return GuestPolicy.ALLOW;
......
...@@ -13,7 +13,6 @@ import java.util.concurrent.ScheduledExecutorService; ...@@ -13,7 +13,6 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import com.sun.org.apache.xpath.internal.operations.Bool;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
......
...@@ -20,21 +20,33 @@ ...@@ -20,21 +20,33 @@
package org.bigbluebutton.presentation.imp; package org.bigbluebutton.presentation.imp;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import com.sun.org.apache.xerces.internal.impl.xs.opti.DefaultDocument;
import org.apache.commons.io.FilenameUtils;
import org.bigbluebutton.presentation.UploadedPresentation; import org.bigbluebutton.presentation.UploadedPresentation;
import org.jodconverter.OfficeDocumentConverter; import org.jodconverter.core.document.DefaultDocumentFormatRegistry;
import org.jodconverter.core.document.DocumentFormat;
import org.jodconverter.core.job.AbstractConverter;
import org.jodconverter.local.LocalConverter;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.google.gson.Gson; import com.google.gson.Gson;
public class Office2PdfPageConverter { public abstract class Office2PdfPageConverter {
private static Logger log = LoggerFactory.getLogger(Office2PdfPageConverter.class); private static Logger log = LoggerFactory.getLogger(Office2PdfPageConverter.class);
public boolean convert(File presentationFile, File output, int page, UploadedPresentation pres, public static boolean convert(File presentationFile, File output, int page, UploadedPresentation pres,
final OfficeDocumentConverter converter){ LocalConverter converter){
FileInputStream inputStream = null;
FileOutputStream outputStream = null;
try { try {
Map<String, Object> logData = new HashMap<>(); Map<String, Object> logData = new HashMap<>();
logData.put("meetingId", pres.getMeetingId()); logData.put("meetingId", pres.getMeetingId());
...@@ -46,7 +58,15 @@ public class Office2PdfPageConverter { ...@@ -46,7 +58,15 @@ public class Office2PdfPageConverter {
String logStr = gson.toJson(logData); String logStr = gson.toJson(logData);
log.info(" --analytics-- data={}", logStr); log.info(" --analytics-- data={}", logStr);
converter.convert(presentationFile, output); final DocumentFormat sourceFormat = DefaultDocumentFormatRegistry.getFormatByExtension(
FilenameUtils.getExtension(presentationFile.getName()));
inputStream = new FileInputStream(presentationFile);
outputStream = new FileOutputStream(output);
converter.convert(inputStream).as(sourceFormat).to(outputStream).as(DefaultDocumentFormatRegistry.PDF).execute();
outputStream.flush();
if (output.exists()) { if (output.exists()) {
return true; return true;
} else { } else {
...@@ -74,6 +94,22 @@ public class Office2PdfPageConverter { ...@@ -74,6 +94,22 @@ public class Office2PdfPageConverter {
String logStr = gson.toJson(logData); String logStr = gson.toJson(logData);
log.error(" --analytics-- data={}", logStr, e); log.error(" --analytics-- data={}", logStr, e);
return false; return false;
} finally {
if(inputStream!=null) {
try {
inputStream.close();
} catch(Exception e) {
}
}
if(outputStream!=null) {
try {
outputStream.close();
} catch(Exception e) {
}
}
} }
} }
......
package org.bigbluebutton.presentation.imp;
import org.jodconverter.core.office.OfficeContext;
import org.jodconverter.local.filter.Filter;
import org.jodconverter.local.filter.FilterChain;
import org.jodconverter.local.office.utils.Lo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sun.star.lang.XComponent;
import com.sun.star.sheet.XCalculatable;
public class OfficeDocumentConversionFilter implements Filter {
private static Logger log = LoggerFactory.getLogger(OfficeDocumentConversionFilter.class);
@Override
public void doFilter(OfficeContext context, XComponent document, FilterChain chain)
throws Exception {
log.info("Applying the OfficeDocumentConversionFilter");
Lo.qiOptional(XCalculatable.class, document).ifPresent((x) -> {
log.info("Turn AutoCalculate off");
x.enableAutomaticCalculation(false);
});
chain.doFilter(context, document);
}
}
...@@ -20,16 +20,18 @@ ...@@ -20,16 +20,18 @@
package org.bigbluebutton.presentation.imp; package org.bigbluebutton.presentation.imp;
import java.io.File; import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.bigbluebutton.presentation.ConversionMessageConstants; import org.bigbluebutton.presentation.ConversionMessageConstants;
import org.bigbluebutton.presentation.SupportedFileTypes; import org.bigbluebutton.presentation.SupportedFileTypes;
import org.bigbluebutton.presentation.UploadedPresentation; import org.bigbluebutton.presentation.UploadedPresentation;
import org.jodconverter.OfficeDocumentConverter; import org.jodconverter.core.office.OfficeException;
import org.jodconverter.office.DefaultOfficeManagerBuilder; import org.jodconverter.core.office.OfficeUtils;
import org.jodconverter.office.OfficeException; import org.jodconverter.local.LocalConverter;
import org.jodconverter.office.OfficeManager; import org.jodconverter.local.office.ExternalOfficeManager;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -39,15 +41,15 @@ public class OfficeToPdfConversionService { ...@@ -39,15 +41,15 @@ public class OfficeToPdfConversionService {
private static Logger log = LoggerFactory.getLogger(OfficeToPdfConversionService.class); private static Logger log = LoggerFactory.getLogger(OfficeToPdfConversionService.class);
private OfficeDocumentValidator2 officeDocumentValidator; private OfficeDocumentValidator2 officeDocumentValidator;
private final OfficeManager officeManager; private final ArrayList<ExternalOfficeManager> officeManagers;
private final OfficeDocumentConverter documentConverter; private ExternalOfficeManager currentManager = null;
private boolean skipOfficePrecheck = false; private boolean skipOfficePrecheck = false;
private int sofficeBasePort = 0;
private int sofficeManagers = 0;
private String sofficeWorkingDirBase = null;
public OfficeToPdfConversionService() { public OfficeToPdfConversionService() throws OfficeException {
final DefaultOfficeManagerBuilder configuration = new DefaultOfficeManagerBuilder(); officeManagers = new ArrayList<>();
configuration.setPortNumbers(8100, 8101, 8102, 8103, 8104);
officeManager = configuration.build();
documentConverter = new OfficeDocumentConverter(officeManager);
} }
/* /*
...@@ -116,8 +118,39 @@ public class OfficeToPdfConversionService { ...@@ -116,8 +118,39 @@ public class OfficeToPdfConversionService {
private boolean convertOfficeDocToPdf(UploadedPresentation pres, private boolean convertOfficeDocToPdf(UploadedPresentation pres,
File pdfOutput) { File pdfOutput) {
Office2PdfPageConverter converter = new Office2PdfPageConverter(); boolean success = false;
return converter.convert(pres.getUploadedFile(), pdfOutput, 0, pres, documentConverter); int attempts = 0;
while(!success) {
LocalConverter documentConverter = LocalConverter
.builder()
.officeManager(currentManager)
.filterChain(new OfficeDocumentConversionFilter())
.build();
success = Office2PdfPageConverter.convert(pres.getUploadedFile(), pdfOutput, 0, pres, documentConverter);
if(!success) {
// In case of failure, try with other open Office Manager
if(++attempts != officeManagers.size()) {
// Go to next Office Manager ( if the last retry with the first one )
int currentManagerIndex = officeManagers.indexOf(currentManager);
boolean isLastManager = ( currentManagerIndex == officeManagers.size()-1 );
if(isLastManager) {
currentManager = officeManagers.get(0);
} else {
currentManager = officeManagers.get(currentManagerIndex+1);
}
} else {
// We tried to use all our office managers and it's still failing
break;
}
}
}
return success;
} }
private void makePdfTheUploadedFileAndSetStepAsSuccess(UploadedPresentation pres, File pdf) { private void makePdfTheUploadedFileAndSetStepAsSuccess(UploadedPresentation pres, File pdf) {
...@@ -133,21 +166,66 @@ public class OfficeToPdfConversionService { ...@@ -133,21 +166,66 @@ public class OfficeToPdfConversionService {
this.skipOfficePrecheck = skipOfficePrecheck; this.skipOfficePrecheck = skipOfficePrecheck;
} }
public void setSofficeBasePort(int sofficeBasePort) {
this.sofficeBasePort = sofficeBasePort;
}
public void setSofficeManagers(int sofficeServiceManagers) {
this.sofficeManagers = sofficeServiceManagers;
}
public void setSofficeWorkingDirBase(String sofficeWorkingDirBase) {
this.sofficeWorkingDirBase = sofficeWorkingDirBase;
}
public void start() { public void start() {
try { log.info("Starting LibreOffice pool with " + sofficeManagers + " managers, starting from port " + sofficeBasePort);
officeManager.start();
} catch (OfficeException e) { for(int managerIndex = 0; managerIndex < sofficeManagers; managerIndex ++) {
log.error("Could not start Office Manager", e); Integer instanceNumber = managerIndex + 1; // starts at 1
try {
final File workingDir = new File(sofficeWorkingDirBase + String.format("%02d", instanceNumber));
if(!workingDir.exists()) {
workingDir.mkdir();
}
ExternalOfficeManager officeManager = ExternalOfficeManager
.builder()
.connectTimeout(2000L)
.retryInterval(500L)
.portNumber(sofficeBasePort + managerIndex)
.connectOnStart(false) // If it's true and soffice is not available, exception is thrown here ( we don't want exception here - we want the manager alive trying to reconnect )
.workingDir(workingDir)
.build();
// Workaround for jodconverter not calling makeTempDir when connectOnStart=false (issue 211)
Method method = officeManager.getClass().getSuperclass().getDeclaredMethod("makeTempDir");
method.setAccessible(true);
method.invoke(officeManager);
// End of workaround for jodconverter not calling makeTempDir
officeManager.start();
officeManagers.add(officeManager);
} catch (Exception e) {
log.error("Could not start Office Manager " + instanceNumber + ". Details: " + e.getMessage());
}
} }
if (officeManagers.size() == 0) {
log.error("No office managers could be started");
return;
}
currentManager = officeManagers.get(0);
} }
public void stop() { public void stop() {
try { try {
officeManager.stop(); officeManagers.forEach(officeManager -> officeManager.stop() );
} catch (OfficeException e) { } catch (Exception e) {
log.error("Could not stop Office Manager", e); log.error("Could not stop Office Manager", e);
} }
} }
} }
[Unit]
Description=BigBlueButton Libre Office container %i
Requires=network.target
[Service]
Type=simple
WorkingDirectory=/tmp
ExecStart=/usr/share/bbb-libreoffice/libreoffice_container.sh %i
ExecStop=/usr/bin/docker kill bbb-libreoffice-%i
Restart=always
RestartSec=60
SuccessExitStatus=
TimeoutStopSec=30
PermissionsStartOnly=true
LimitNOFILE=1024
[Install]
WantedBy=multi-user.target
#!/bin/bash
set -e
INSTANCE_NUMBER=$1
if [ -z "$INSTANCE_NUMBER" ]; then
INSTANCE_NUMBER=0
fi;
_kill() {
CHECK_CONTAINER=`docker inspect bbb-libreoffice-${INSTANCE_NUMBER} &> /dev/null && echo 1 || echo 0`
if [ "$CHECK_CONTAINER" = "1" ]; then
echo "Killing container"
docker kill bbb-libreoffice-${INSTANCE_NUMBER};
sleep 1
fi;
}
trap _kill SIGINT
if (($INSTANCE_NUMBER >= 1)); then
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
_kill
let PORT=8200+${INSTANCE_NUMBER}
SOFFICE_WORK_DIR="/var/tmp/soffice_"`printf "%02d\n" $INSTANCE_NUMBER`
INPUT_RULE="INPUT -i br-soffice -m state --state NEW -j DROP"
iptables -C $INPUT_RULE || iptables -I $INPUT_RULE
FORWARD_RULE="FORWARD -i br-soffice -m state --state NEW -j DROP"
iptables -C $FORWARD_RULE || iptables -I $FORWARD_RULE
docker run --network bbb-libreoffice --user `id -u bigbluebutton` --name bbb-libreoffice-${INSTANCE_NUMBER} -p $PORT:8000 -v${SOFFICE_WORK_DIR}:${SOFFICE_WORK_DIR} --rm bbb-libreoffice &
wait $!
else
echo ;
echo "Invalid or missing parameter INSTANCE_NUMBER"
echo " Usage: $0 INSTANCE_NUMBER"
exit 1
fi;
FROM openjdk:8-jre
ENV DEBIAN_FRONTEND noninteractive
RUN apt update
RUN apt -y install locales-all fontconfig libxt6 libxrender1
RUN apt -y install libreoffice --no-install-recommends
RUN dpkg-reconfigure fontconfig && fc-cache -f -s -v
VOLUME ["/usr/share/fonts/"]
ADD ./bbb-libreoffice-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["/usr/local/bin/bbb-libreoffice-entrypoint.sh" ]
#!/bin/bash
## Initialize environment
/usr/lib/libreoffice/program/soffice.bin -env:UserInstallation="file:///tmp/"
## Run daemon
/usr/lib/libreoffice/program/soffice.bin --accept="socket,host=0.0.0.0,port=8000,tcpNoDelay=1;urp;StarOffice.ServiceManager" --headless --invisible --nocrashreport --nodefault --nofirststartwizard --nolockcheck --nologo --norestore -env:UserInstallation="file:///tmp/"
#!/bin/bash
if [ "$EUID" -ne 0 ]; then
echo "Please run this script as root ( or with sudo )" ;
exit 1;
fi;
DOCKER_CHECK=`docker --version &> /dev/null && echo 1 || echo 0`
if [ "$DOCKER_CHECK" = "0" ]; then
echo "Docker not found";
apt update;
apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
apt update
apt install docker-ce -y
systemctl enable docker
systemctl start docker
systemctl status docker
else
echo "Docker already installed";
fi
IMAGE_CHECK=`docker image inspect bbb-libreoffice &> /dev/null && echo 1 || echo 0`
if [ "$IMAGE_CHECK" = "0" ]; then
echo "Docker image doesn't exists, building"
docker build -t bbb-libreoffice docker/
else
echo "Docker image already exists";
fi
NETWORK_CHECK=`docker network inspect bbb-libreoffice &> /dev/null && echo 1 || echo 0`
if [ "$NETWORK_CHECK" = "0" ]; then
echo "Docker network doesn't exists, creating"
docker network create bbb-libreoffice -d bridge --opt com.docker.network.bridge.name=br-soffice
fi
FOLDER_CHECK=`[ -d /usr/share/bbb-libreoffice/ ] && echo 1 || echo 0`
if [ "$FOLDER_CHECK" = "0" ]; then
echo "Install folder doesn't exists, installing"
mkdir -m 755 /usr/share/bbb-libreoffice/
cp assets/libreoffice_container.sh /usr/share/bbb-libreoffice/
chmod 700 /usr/share/bbb-libreoffice/libreoffice_container.sh
chown -R root /usr/share/bbb-libreoffice/
cp assets/bbb-libreoffice.service /lib/systemd/system/bbb-libreoffice@.service
systemctl daemon-reload
for i in `seq 1 4` ; do
systemctl enable bbb-libreoffice@${i}
systemctl start bbb-libreoffice@${i}
done
else
echo "Install folder already exists"
fi;
#!/bin/bash
set -e
if [ "$EUID" -ne 0 ]; then
echo "Please run this script as root ( or with sudo )" ;
exit 1;
fi;
IMAGE_CHECK=`docker image inspect bbb-libreoffice 2>&1 > /dev/null && echo 1 || echo 0`
if [ "$IMAGE_CHECK" = "1" ]; then
echo "Stopping services"
systemctl --no-pager --no-legend --value --state=running | grep bbb-libreoffice | awk -F '.service' '{print $1}' | xargs --no-run-if-empty -n 1 systemctl stop
echo "Removing image"
docker image rm bbb-libreoffice
fi
FOLDER_CHECK=`[ -d /usr/share/bbb-libreoffice/ ] && echo 1 || echo 0`
if [ "$FOLDER_CHECK" = "1" ]; then
echo "Stopping services"
systemctl --no-pager --no-legend --value --state=running | grep bbb-libreoffice | awk -F '.service' '{print $1}' | xargs --no-run-if-empty -n 1 systemctl stop
echo "Removing install folder"
rm -rf /usr/share/bbb-libreoffice/
echo "Removing service definitions"
rm /lib/systemd/system/bbb-libreoffice@.service
find /etc/systemd/ | grep bbb-libreoffice | xargs --no-run-if-empty -n 1 -I __ rm __
systemctl daemon-reload
fi;
NETWORK_CHECK=`docker network inspect bbb-libreoffice &> /dev/null && echo 1 || echo 0`
if [ "$NETWORK_CHECK" = "1" ]; then
echo "Removing docker network"
docker network remove bbb-libreoffice
fi
...@@ -2,7 +2,7 @@ FROM java:8-jdk AS builder ...@@ -2,7 +2,7 @@ FROM java:8-jdk AS builder
RUN mkdir -p /root/tools \ RUN mkdir -p /root/tools \
&& cd /root/tools \ && cd /root/tools \
&& wget http://services.gradle.org/distributions/gradle-2.12-bin.zip \ && wget https://services.gradle.org/distributions/gradle-2.12-bin.zip \
&& unzip gradle-2.12-bin.zip \ && unzip gradle-2.12-bin.zip \
&& ln -s gradle-2.12 gradle && ln -s gradle-2.12 gradle
......
...@@ -51,9 +51,7 @@ ...@@ -51,9 +51,7 @@
<g:if test="${r.published}"> <g:if test="${r.published}">
<div> <div>
<g:each in="${r.thumbnails}" var="thumbnail"> <g:each in="${r.thumbnails}" var="thumbnail">
<g:each in="${thumbnail.content}" var="thumbnail_url"> <img src="${thumbnail.content}" class="thumbnail"/>
<img src="${thumbnail_url}" class="thumbnail"/>
</g:each>
</g:each> </g:each>
</div> </div>
</g:if> </g:if>
......
...@@ -61,10 +61,11 @@ module.exports = class CallbackEmitter extends EventEmitter { ...@@ -61,10 +61,11 @@ module.exports = class CallbackEmitter extends EventEmitter {
} }
_emitMessage(callback) { _emitMessage(callback) {
let data,requestOptions; let data, requestOptions;
const serverDomain = config.get("bbb.serverDomain"); const serverDomain = config.get("bbb.serverDomain");
const sharedSecret = config.get("bbb.sharedSecret"); const sharedSecret = config.get("bbb.sharedSecret");
const bearerAuth = config.get("bbb.auth2_0"); const bearerAuth = config.get("bbb.auth2_0");
const timeout = config.get('hooks.requestTimeout');
// data to be sent // data to be sent
// note: keep keys in alphabetical order // note: keep keys in alphabetical order
...@@ -85,7 +86,8 @@ module.exports = class CallbackEmitter extends EventEmitter { ...@@ -85,7 +86,8 @@ module.exports = class CallbackEmitter extends EventEmitter {
form: data, form: data,
auth: { auth: {
bearer: sharedSecret bearer: sharedSecret
} },
timeout
}; };
} }
else { else {
...@@ -103,7 +105,8 @@ module.exports = class CallbackEmitter extends EventEmitter { ...@@ -103,7 +105,8 @@ module.exports = class CallbackEmitter extends EventEmitter {
maxRedirects: 10, maxRedirects: 10,
uri: callbackURL, uri: callbackURL,
method: "POST", method: "POST",
form: data form: data,
timeout
}; };
} }
......
...@@ -6,6 +6,9 @@ hooks: ...@@ -6,6 +6,9 @@ hooks:
permanentURLs: permanentURLs:
__name: PERMANENT_HOOKS __name: PERMANENT_HOOKS
__format: json __format: json
requestTimeout:
__name: REQUEST_TIMEOUT
__format: json
redis: redis:
host: REDIS_HOST host: REDIS_HOST
port: REDIS_PORT port: REDIS_PORT
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment