merge with update-api-create-join-validation
This commit is contained in:
commit
a2cd27c1f9
@ -95,3 +95,8 @@ pomExtra := (
|
||||
licenses := Seq("LGPL-3.0" -> url("http://opensource.org/licenses/LGPL-3.0"))
|
||||
|
||||
homepage := Some(url("http://www.bigbluebutton.org"))
|
||||
|
||||
libraryDependencies += "javax.validation" % "validation-api" % "2.0.1.Final"
|
||||
libraryDependencies += "org.springframework.boot" % "spring-boot-starter-validation" % "2.5.1"
|
||||
libraryDependencies += "org.glassfish" % "javax.el" % "3.0.1-b12"
|
||||
libraryDependencies += "org.apache.httpcomponents" % "httpclient" % "4.5.13"
|
@ -720,6 +720,26 @@ public class ParamsProcessorUtil {
|
||||
return "";
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
log.info("CONFIGXML CHECKSUM={} length={}", checksum, checksum.length());
|
||||
|
||||
String data = meetingID + configXML + securitySalt;
|
||||
String cs = DigestUtils.sha1Hex(data);
|
||||
if (checksum.length() == 64) {
|
||||
cs = DigestUtils.sha256Hex(data);
|
||||
log.info("CONFIGXML SHA256 {}", cs);
|
||||
}
|
||||
|
||||
if (cs == null || !cs.equals(checksum)) {
|
||||
log.info("checksumError: configXML checksum. our: [{}], client: [{}]", cs, checksum);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Can be removed. Checksum validation is performed by the ChecksumValidator
|
||||
>>>>>>> update-api-create-join-validation
|
||||
public boolean isChecksumSame(String apiCall, String checksum, String queryString) {
|
||||
if (StringUtils.isEmpty(securitySalt)) {
|
||||
log.warn("Security is disabled in this service. Make sure this is intentional.");
|
||||
|
@ -0,0 +1,21 @@
|
||||
package org.bigbluebutton.api.model.constraint;
|
||||
|
||||
import org.bigbluebutton.api.model.validator.ChecksumValidator;
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.Payload;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import static java.lang.annotation.ElementType.TYPE;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
@Constraint(validatedBy = ChecksumValidator.class)
|
||||
@Target(TYPE)
|
||||
@Retention(RUNTIME)
|
||||
public @interface ChecksumConstraint {
|
||||
|
||||
String message() default "Invalid checksum: checksums do not match";
|
||||
Class<?>[] groups() default {};
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
package org.bigbluebutton.api.model.request;
|
||||
|
||||
import org.bigbluebutton.api.model.shared.Checksum;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Pattern;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.Map;
|
||||
|
||||
public class CreateMeeting extends Request {
|
||||
|
||||
@NotEmpty(message = "You must provide a meeting name")
|
||||
@Size(min = 2, max = 256, message = "Meeting name must be between 2 and 256 characters")
|
||||
@Pattern(regexp = "^[a-zA-Z0-9\\s!@#$%^&*()_\\-+=\\[\\]{};:.'\"<>?\\\\|\\/]+$", message = "Meeting name cannot contain ','")
|
||||
private String name;
|
||||
|
||||
@NotEmpty(message = "You must provide a meeting ID")
|
||||
@Size(min = 2, max = 256, message = "Meeting ID must be between 2 and 256 characters")
|
||||
@Pattern(regexp = "^[a-zA-Z0-9\\s!@#$%^&*()_\\-+=\\[\\]{};:.'\"<>?\\\\|\\/]+$", message = "Meeting ID cannot contain ','")
|
||||
private String meetingID;
|
||||
|
||||
@NotEmpty(message = "You must provide a voice bridge")
|
||||
private String voiceBridge;
|
||||
|
||||
@NotEmpty(message = "You must provide an attendee password")
|
||||
private String attendeePW;
|
||||
|
||||
@NotEmpty(message = "You must provide a moderator password")
|
||||
private String moderatorPW;
|
||||
|
||||
@NotNull(message = "You must provide whether this meeting is breakout room")
|
||||
private Boolean isBreakoutRoom;
|
||||
|
||||
@NotNull(message = "You must provide whether to record this meeting")
|
||||
private Boolean record;
|
||||
|
||||
public CreateMeeting(Checksum checksum) {
|
||||
super(checksum);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getMeetingID() {
|
||||
return meetingID;
|
||||
}
|
||||
|
||||
public void setMeetingID(String meetingID) {
|
||||
this.meetingID = meetingID;
|
||||
}
|
||||
|
||||
public String getVoiceBridge() {
|
||||
return voiceBridge;
|
||||
}
|
||||
|
||||
public void setVoiceBridge(String voiceBridge) {
|
||||
this.voiceBridge = voiceBridge;
|
||||
}
|
||||
|
||||
public String getAttendeePW() {
|
||||
return attendeePW;
|
||||
}
|
||||
|
||||
public void setAttendeePW(String attendeePW) {
|
||||
this.attendeePW = attendeePW;
|
||||
}
|
||||
|
||||
public String getModeratorPW() {
|
||||
return moderatorPW;
|
||||
}
|
||||
|
||||
public void setModeratorPW(String moderatorPW) {
|
||||
this.moderatorPW = moderatorPW;
|
||||
}
|
||||
|
||||
public Boolean isBreakoutRoom() {
|
||||
return isBreakoutRoom;
|
||||
}
|
||||
|
||||
public void setBreakoutRoom(boolean breakoutRoom) {
|
||||
isBreakoutRoom = breakoutRoom;
|
||||
}
|
||||
|
||||
public Boolean isRecord() {
|
||||
return record;
|
||||
}
|
||||
|
||||
public void setRecord(boolean record) {
|
||||
this.record = record;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateFromParamsMap(Map<String, String[]> params) {
|
||||
if(params.containsKey("name")) setName(params.get("name")[0]);
|
||||
if(params.containsKey("meetingID")) setMeetingID(params.get("meetingID")[0]);
|
||||
if(params.containsKey("voiceBridge")) setVoiceBridge(params.get("voiceBridge")[0]);
|
||||
if(params.containsKey("attendeePW")) setAttendeePW(params.get("attendeePW")[0]);
|
||||
if(params.containsKey("moderatorPW")) setModeratorPW(params.get("moderatorPW")[0]);
|
||||
if(params.containsKey("isBreakoutRoom")) setBreakoutRoom(Boolean.parseBoolean(params.get("isBreakoutRoom")[0]));
|
||||
if(params.containsKey("record")) setRecord(Boolean.parseBoolean(params.get("record")[0]));
|
||||
}
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
package org.bigbluebutton.api.model.request;
|
||||
|
||||
import org.bigbluebutton.api.model.shared.Checksum;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.Pattern;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.Map;
|
||||
|
||||
public class JoinMeeting extends Request {
|
||||
|
||||
@NotEmpty(message = "You must provide a meeting ID")
|
||||
@Size(min = 2, max = 256, message = "Meeting ID must be between 2 and 256 characters")
|
||||
@Pattern(regexp = "^[a-zA-Z0-9\\s!@#$%^&*()_\\-+=\\[\\]{};:.'\"<>?\\\\|\\/]+$", message = "Meeting name cannot contain ','")
|
||||
private String meetingID;
|
||||
|
||||
private String userID;
|
||||
|
||||
@NotEmpty(message = "You must provide your name")
|
||||
private String fullName;
|
||||
|
||||
@NotEmpty(message = "You must provide your password")
|
||||
@Size(min = 2, max = 64, message = "Password must be between 8 and 20 characters")
|
||||
private String password;
|
||||
|
||||
private Boolean guest;
|
||||
|
||||
private Boolean auth;
|
||||
|
||||
private Long createTime;
|
||||
|
||||
public JoinMeeting(Checksum checksum) {
|
||||
super(checksum);
|
||||
}
|
||||
|
||||
public String getMeetingID() {
|
||||
return meetingID;
|
||||
}
|
||||
|
||||
public void setMeetingID(String meetingID) {
|
||||
this.meetingID = meetingID;
|
||||
}
|
||||
|
||||
public String getUserID() {
|
||||
return userID;
|
||||
}
|
||||
|
||||
public void setUserID(String userID) {
|
||||
this.userID = userID;
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
public void setFullName(String fullName) {
|
||||
this.fullName = fullName;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public Boolean getGuest() {
|
||||
return guest;
|
||||
}
|
||||
|
||||
public void setGuest(Boolean guest) {
|
||||
this.guest = guest;
|
||||
}
|
||||
|
||||
public Boolean getAuth() {
|
||||
return auth;
|
||||
}
|
||||
|
||||
public void setAuth(Boolean auth) {
|
||||
this.auth = auth;
|
||||
}
|
||||
|
||||
public Long getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(Long createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateFromParamsMap(Map<String, String[]> params) {
|
||||
if(params.containsKey("meetingID")) setMeetingID(params.get("meetingID")[0]);
|
||||
if(params.containsKey("userID")) setUserID(params.get("userID")[0]);
|
||||
if(params.containsKey("fullName")) setFullName(params.get("fullName")[0]);
|
||||
if(params.containsKey("password")) setPassword(params.get("password")[0]);
|
||||
if(params.containsKey("guest")) setGuest(Boolean.parseBoolean(params.get("guest")[0]));
|
||||
if(params.containsKey("auth")) setAuth(Boolean.parseBoolean(params.get("auth")[0]));
|
||||
if(params.containsKey("createTime")) setCreateTime(Long.parseLong(params.get("createTime")[0]));
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package org.bigbluebutton.api.model.request;
|
||||
|
||||
import org.bigbluebutton.api.model.shared.Checksum;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class Request {
|
||||
|
||||
@Valid
|
||||
protected Checksum checksum;
|
||||
|
||||
protected Request(Checksum checksum) {
|
||||
this.checksum = checksum;
|
||||
}
|
||||
|
||||
public Checksum getChecksum() {
|
||||
return checksum;
|
||||
}
|
||||
|
||||
public void setChecksum(Checksum checksum) {
|
||||
this.checksum = checksum;
|
||||
}
|
||||
|
||||
public abstract void populateFromParamsMap(Map<String, String[]> params);
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package org.bigbluebutton.api.model.shared;
|
||||
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.utils.URLEncodedUtils;
|
||||
import org.bigbluebutton.api.model.constraint.ChecksumConstraint;
|
||||
import org.bigbluebutton.api.util.ParamsUtil;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@ChecksumConstraint(message = "Checksums do not match")
|
||||
public class Checksum {
|
||||
|
||||
@NotEmpty(message = "You must provide the API call")
|
||||
private String apiCall;
|
||||
|
||||
@NotEmpty(message = "You must provide the checksum")
|
||||
private String checksum;
|
||||
|
||||
@NotEmpty(message = "You must provide the query string")
|
||||
private String queryString;
|
||||
|
||||
private String queryStringWithoutChecksum;
|
||||
|
||||
public Checksum(String apiCall, String checksum, String queryString) {
|
||||
this.apiCall = ParamsUtil.sanitizeString(apiCall);
|
||||
this.checksum = ParamsUtil.sanitizeString(checksum);
|
||||
this.queryString = ParamsUtil.sanitizeString(queryString);
|
||||
removeChecksumFromQueryString();
|
||||
}
|
||||
|
||||
private void removeChecksumFromQueryString() {
|
||||
List<NameValuePair> params = URLEncodedUtils.parse(queryString, StandardCharsets.UTF_8);
|
||||
|
||||
Iterator<NameValuePair> itr = params.iterator();
|
||||
while(itr.hasNext()) {
|
||||
NameValuePair pair = itr.next();
|
||||
if(pair.getName().equals("checksum")) {
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
|
||||
queryStringWithoutChecksum = URLEncodedUtils.format(params, '&', StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
public String getApiCall() {
|
||||
return apiCall;
|
||||
}
|
||||
|
||||
public void setApiCall(String apiCall) {
|
||||
this.apiCall = apiCall;
|
||||
}
|
||||
|
||||
public String getChecksum() {
|
||||
return checksum;
|
||||
}
|
||||
|
||||
public void setChecksum(String checksum) {
|
||||
this.checksum = checksum;
|
||||
}
|
||||
|
||||
public String getQueryString() {
|
||||
return queryString;
|
||||
}
|
||||
|
||||
public void setQueryString(String queryString) {
|
||||
this.queryString = queryString;
|
||||
}
|
||||
|
||||
public String getQueryStringWithoutChecksum() {
|
||||
return queryStringWithoutChecksum;
|
||||
}
|
||||
|
||||
public void setQueryStringWithoutChecksum(String queryStringWithoutChecksum) {
|
||||
this.queryStringWithoutChecksum = queryStringWithoutChecksum;
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package org.bigbluebutton.api.model.validator;
|
||||
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.bigbluebutton.api.model.shared.Checksum;
|
||||
import org.bigbluebutton.api.model.constraint.ChecksumConstraint;
|
||||
import org.bigbluebutton.api.service.ValidatorService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ChecksumValidator implements ConstraintValidator<ChecksumConstraint, Checksum> {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(ChecksumValidator.class);
|
||||
|
||||
@Override
|
||||
public void initialize(ChecksumConstraint checksumConstraint) {}
|
||||
|
||||
@Override
|
||||
public boolean isValid(Checksum checksum, ConstraintValidatorContext context) {
|
||||
String securitySalt = ValidatorService.getSecuritySalt();
|
||||
|
||||
log.info("Security salt: {}", securitySalt);
|
||||
|
||||
String queryStringWithoutChecksum = checksum.getQueryStringWithoutChecksum();
|
||||
log.info("query string after checksum removed: [{}]", queryStringWithoutChecksum);
|
||||
|
||||
String providedChecksum = checksum.getChecksum();
|
||||
log.info("CHECKSUM={} length={}", providedChecksum, providedChecksum.length());
|
||||
|
||||
String data = checksum.getApiCall() + queryStringWithoutChecksum + securitySalt;
|
||||
String createdCheckSum = DigestUtils.sha1Hex(data);
|
||||
|
||||
if (providedChecksum.length() == 64) {
|
||||
createdCheckSum = DigestUtils.sha256Hex(data);
|
||||
log.info("SHA256 {}", createdCheckSum);
|
||||
}
|
||||
|
||||
if (createdCheckSum == null || !createdCheckSum.equals(providedChecksum)) {
|
||||
log.info("checksumError: query string checksum failed. our: [{}], client: [{}]", createdCheckSum, providedChecksum);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
108
bbb-common-web/src/main/java/org/bigbluebutton/api/service/ValidatorService.java
Executable file
108
bbb-common-web/src/main/java/org/bigbluebutton/api/service/ValidatorService.java
Executable file
@ -0,0 +1,108 @@
|
||||
package org.bigbluebutton.api.service;
|
||||
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.utils.URLEncodedUtils;
|
||||
import org.bigbluebutton.api.model.request.CreateMeeting;
|
||||
import org.bigbluebutton.api.model.request.JoinMeeting;
|
||||
import org.bigbluebutton.api.model.request.Request;
|
||||
import org.bigbluebutton.api.model.shared.Checksum;
|
||||
import org.bigbluebutton.api.util.ParamsUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.Validation;
|
||||
import javax.validation.Validator;
|
||||
import javax.validation.ValidatorFactory;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
public class ValidatorService {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(ValidatorService.class);
|
||||
|
||||
public static enum ApiCall {
|
||||
CREATE("create"),
|
||||
JOIN("join");
|
||||
|
||||
private final String name;
|
||||
|
||||
private ApiCall(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() { return this.name; }
|
||||
}
|
||||
|
||||
private static String securitySalt;
|
||||
|
||||
private ValidatorFactory validatorFactory;
|
||||
private Validator validator;
|
||||
|
||||
public ValidatorService() {
|
||||
validatorFactory = Validation.buildDefaultValidatorFactory();
|
||||
validator = validatorFactory.getValidator();
|
||||
}
|
||||
|
||||
public Set<String> validate(ApiCall apiCall, Map<String, String[]> params, String queryString) {
|
||||
log.info("Validating {} request with parameters {}", apiCall.getName(), queryString);
|
||||
|
||||
params = sanitizeParams(params);
|
||||
|
||||
Checksum checksum = new Checksum(apiCall.getName(), params.get("checksum")[0], queryString);
|
||||
|
||||
Request request = null;
|
||||
Set<String> violations = new HashSet<>();
|
||||
|
||||
switch(apiCall) {
|
||||
case CREATE:
|
||||
request = new CreateMeeting(checksum);
|
||||
break;
|
||||
case JOIN:
|
||||
request = new JoinMeeting(checksum);
|
||||
break;
|
||||
default:
|
||||
violations.add("validationError: Request not recognized");
|
||||
break;
|
||||
}
|
||||
|
||||
if(request != null) {
|
||||
request.populateFromParamsMap(params);
|
||||
violations = performValidation(request);
|
||||
}
|
||||
|
||||
return violations;
|
||||
}
|
||||
|
||||
private <R extends Request> Set<String> performValidation(R classToValidate) {
|
||||
Set<ConstraintViolation<R>> violations = validator.validate(classToValidate);
|
||||
Set<String> violationSet = new HashSet<>();
|
||||
|
||||
for(ConstraintViolation<R> violation: violations) {
|
||||
violationSet.add(violation.getMessage());
|
||||
}
|
||||
|
||||
return violationSet;
|
||||
}
|
||||
|
||||
private Map<String, String[]> sanitizeParams(Map<String, String[]> params) {
|
||||
Map<String, String[]> sanitizedParams = new LinkedHashMap<>();
|
||||
|
||||
for(Map.Entry<String, String[]> param: params.entrySet()) {
|
||||
String paramName = ParamsUtil.sanitizeString(param.getKey());
|
||||
String[] sanitizedValues = new String[param.getValue().length];
|
||||
|
||||
for(int i = 0; i < sanitizedValues.length; i++) {
|
||||
String sanitziedValue = ParamsUtil.sanitizeString(param.getValue()[i]);
|
||||
sanitizedValues[i] = sanitziedValue;
|
||||
}
|
||||
|
||||
sanitizedParams.put(paramName, sanitizedValues);
|
||||
}
|
||||
|
||||
return sanitizedParams;
|
||||
}
|
||||
|
||||
public void setSecuritySalt(String securitySalt) { this.securitySalt = securitySalt; }
|
||||
public static String getSecuritySalt() { return securitySalt; }
|
||||
}
|
@ -69,4 +69,14 @@ public class ParamsUtil {
|
||||
}
|
||||
return padId;
|
||||
}
|
||||
|
||||
public static String sanitizeString(String inputString) {
|
||||
if(inputString == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String sanitizedString = stripControlChars(inputString);
|
||||
String trimmedString = sanitizedString.trim();
|
||||
return trimmedString;
|
||||
}
|
||||
}
|
||||
|
@ -85,6 +85,10 @@ dependencies {
|
||||
// https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload
|
||||
compile group: 'commons-fileupload', name: 'commons-fileupload', version: '1.4'
|
||||
|
||||
compile "javax.validation:validation-api:2.0.1.Final"
|
||||
// compile "org.hibernate:hibernate-validator:7.0.1.Final"
|
||||
compile 'org.springframework.boot:spring-boot-starter-validation:2.5.1'
|
||||
|
||||
//--- BigBlueButton Dependencies End
|
||||
console "org.grails:grails-console"
|
||||
profile "org.grails.profiles:web"
|
||||
|
@ -115,6 +115,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
<property name="clientConfigServiceHelper" ref="configServiceHelper"/>
|
||||
</bean>
|
||||
|
||||
<bean id="validatorService" class="org.bigbluebutton.api.service.ValidatorService">
|
||||
<property name="securitySalt" value="${securitySalt}"/>
|
||||
</bean>
|
||||
|
||||
<bean id="paramsProcessorUtil" class="org.bigbluebutton.api.ParamsProcessorUtil">
|
||||
<property name="apiVersion" value="${apiVersion}"/>
|
||||
<property name="serviceEnabled" value="${serviceEnabled}"/>
|
||||
|
@ -30,6 +30,7 @@ import org.bigbluebutton.api.domain.Config
|
||||
import org.bigbluebutton.api.domain.GuestPolicy
|
||||
import org.bigbluebutton.api.domain.Meeting
|
||||
import org.bigbluebutton.api.domain.UserSession
|
||||
import org.bigbluebutton.api.service.ValidatorService
|
||||
import org.bigbluebutton.api.util.ParamsUtil
|
||||
import org.bigbluebutton.api.util.ResponseBuilder
|
||||
import org.bigbluebutton.presentation.PresentationUrlDownloadService
|
||||
@ -60,6 +61,7 @@ class ApiController {
|
||||
StunTurnService stunTurnService
|
||||
HTML5LoadBalancingService html5LoadBalancingService
|
||||
ResponseBuilder responseBuilder = initResponseBuilder()
|
||||
ValidatorService validatorService
|
||||
|
||||
def initResponseBuilder = {
|
||||
String protocol = this.getClass().getResource("").getProtocol();
|
||||
@ -93,49 +95,68 @@ class ApiController {
|
||||
String API_CALL = 'create'
|
||||
log.debug CONTROLLER_NAME + "#${API_CALL}"
|
||||
log.debug request.getParameterMap().toMapString()
|
||||
log.debug request.getQueryString()
|
||||
|
||||
Set<String> violations = validatorService.validate(
|
||||
ValidatorService.ApiCall.CREATE,
|
||||
request.getParameterMap(),
|
||||
request.getQueryString()
|
||||
)
|
||||
|
||||
if(!violations.isEmpty()) {
|
||||
StringBuilder violationMessages = new StringBuilder()
|
||||
|
||||
for(String violation: violations) {
|
||||
violationMessages.append(violation + "\n");
|
||||
log.error violation
|
||||
}
|
||||
|
||||
invalid("validationError", violationMessages.toString())
|
||||
return
|
||||
}
|
||||
|
||||
//sanitizeInput
|
||||
params.each {
|
||||
key, value -> params[key] = sanitizeInput(value)
|
||||
}
|
||||
|
||||
// BEGIN - backward compatibility
|
||||
if (StringUtils.isEmpty(params.checksum)) {
|
||||
invalid("checksumError", "You did not pass the checksum security check")
|
||||
return
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(params.meetingID)) {
|
||||
params.meetingID = StringUtils.strip(params.meetingID);
|
||||
if (StringUtils.isEmpty(params.meetingID)) {
|
||||
invalid("missingParamMeetingID", "You must specify a meeting ID for the meeting.");
|
||||
return
|
||||
}
|
||||
} else {
|
||||
invalid("missingParamMeetingID", "You must specify a meeting ID for the meeting.");
|
||||
return
|
||||
}
|
||||
|
||||
if (!paramsProcessorUtil.isChecksumSame(API_CALL, params.checksum, request.getQueryString())) {
|
||||
invalid("checksumError", "You did not pass the checksum security check")
|
||||
return
|
||||
}
|
||||
// END - backward compatibility
|
||||
|
||||
ApiErrors errors = new ApiErrors();
|
||||
paramsProcessorUtil.processRequiredCreateParams(params, errors);
|
||||
|
||||
if (errors.hasErrors()) {
|
||||
respondWithErrors(errors)
|
||||
return
|
||||
}
|
||||
|
||||
// Do we agree with the checksum? If not, complain.
|
||||
if (!paramsProcessorUtil.isChecksumSame(API_CALL, params.checksum, request.getQueryString())) {
|
||||
errors.checksumError()
|
||||
respondWithErrors(errors)
|
||||
return
|
||||
}
|
||||
// params.each {
|
||||
// key, value -> params[key] = sanitizeInput(value)
|
||||
// }
|
||||
//
|
||||
// // BEGIN - backward compatibility
|
||||
// if (StringUtils.isEmpty(params.checksum)) {
|
||||
// invalid("checksumError", "You did not pass the checksum security check")
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// if (!StringUtils.isEmpty(params.meetingID)) {
|
||||
// params.meetingID = StringUtils.strip(params.meetingID);
|
||||
// if (StringUtils.isEmpty(params.meetingID)) {
|
||||
// invalid("missingParamMeetingID", "You must specify a meeting ID for the meeting.");
|
||||
// return
|
||||
// }
|
||||
// } else {
|
||||
// invalid("missingParamMeetingID", "You must specify a meeting ID for the meeting.");
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// if (!paramsProcessorUtil.isChecksumSame(API_CALL, params.checksum, request.getQueryString())) {
|
||||
// invalid("checksumError", "You did not pass the checksum security check")
|
||||
// return
|
||||
// }
|
||||
// // END - backward compatibility
|
||||
//
|
||||
// ApiErrors errors = new ApiErrors();
|
||||
// paramsProcessorUtil.processRequiredCreateParams(params, errors);
|
||||
//
|
||||
// if (errors.hasErrors()) {
|
||||
// respondWithErrors(errors)
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// // Do we agree with the checksum? If not, complain.
|
||||
// if (!paramsProcessorUtil.isChecksumSame(API_CALL, params.checksum, request.getQueryString())) {
|
||||
// errors.checksumError()
|
||||
// respondWithErrors(errors)
|
||||
// return
|
||||
// }
|
||||
|
||||
// Ensure unique TelVoice. Uniqueness is not guaranteed by paramsProcessorUtil.
|
||||
if (!params.voiceBridge) {
|
||||
@ -203,58 +224,79 @@ class ApiController {
|
||||
def join = {
|
||||
String API_CALL = 'join'
|
||||
log.debug CONTROLLER_NAME + "#${API_CALL}"
|
||||
ApiErrors errors = new ApiErrors()
|
||||
log.debug request.getParameterMap().toMapString()
|
||||
log.debug request.getQueryString()
|
||||
|
||||
//sanitizeInput
|
||||
params.each {
|
||||
key, value -> params[key] = sanitizeInput(value)
|
||||
}
|
||||
Set<String> violations = validatorService.validate(
|
||||
ValidatorService.ApiCall.JOIN,
|
||||
request.getParameterMap(),
|
||||
request.getQueryString()
|
||||
)
|
||||
|
||||
// BEGIN - backward compatibility
|
||||
if (StringUtils.isEmpty(params.checksum)) {
|
||||
invalid("checksumError", "You did not pass the checksum security check")
|
||||
return
|
||||
}
|
||||
if(!violations.isEmpty()) {
|
||||
StringBuilder violationMessages = new StringBuilder()
|
||||
|
||||
if (!paramsProcessorUtil.isChecksumSame(API_CALL, params.checksum, request.getQueryString())) {
|
||||
invalid("checksumError", "You did not pass the checksum security check")
|
||||
return
|
||||
}
|
||||
|
||||
//checking for an empty username or for a username containing whitespaces only
|
||||
if (!StringUtils.isEmpty(params.fullName)) {
|
||||
params.fullName = StringUtils.strip(params.fullName);
|
||||
if (StringUtils.isEmpty(params.fullName)) {
|
||||
invalid("missingParamFullName", "You must specify a name for the attendee who will be joining the meeting.", REDIRECT_RESPONSE);
|
||||
return
|
||||
for(String violation: violations) {
|
||||
violationMessages.append(violation + "\n");
|
||||
log.error violation
|
||||
}
|
||||
} else {
|
||||
invalid("missingParamFullName", "You must specify a name for the attendee who will be joining the meeting.", REDIRECT_RESPONSE);
|
||||
|
||||
invalid("validationError", violationMessages.toString())
|
||||
return
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(params.meetingID)) {
|
||||
params.meetingID = StringUtils.strip(params.meetingID);
|
||||
if (StringUtils.isEmpty(params.meetingID)) {
|
||||
invalid("missingParamMeetingID", "You must specify a meeting ID for the meeting.", REDIRECT_RESPONSE)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
invalid("missingParamMeetingID", "You must specify a meeting ID for the meeting.", REDIRECT_RESPONSE)
|
||||
return
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(params.password)) {
|
||||
invalid("invalidPassword", "You either did not supply a password or the password supplied is neither the attendee or moderator password for this conference.", REDIRECT_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
// END - backward compatibility
|
||||
|
||||
// Do we have a checksum? If none, complain.
|
||||
if (StringUtils.isEmpty(params.checksum)) {
|
||||
errors.missingParamError("checksum");
|
||||
}
|
||||
// ApiErrors errors = new ApiErrors()
|
||||
//
|
||||
// //sanitizeInput
|
||||
// params.each {
|
||||
// key, value -> params[key] = sanitizeInput(value)
|
||||
// }
|
||||
//
|
||||
// // BEGIN - backward compatibility
|
||||
// if (StringUtils.isEmpty(params.checksum)) {
|
||||
// invalid("checksumError", "You did not pass the checksum security check")
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// if (!paramsProcessorUtil.isChecksumSame(API_CALL, params.checksum, request.getQueryString())) {
|
||||
// invalid("checksumError", "You did not pass the checksum security check")
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// //checking for an empty username or for a username containing whitespaces only
|
||||
// if (!StringUtils.isEmpty(params.fullName)) {
|
||||
// params.fullName = StringUtils.strip(params.fullName);
|
||||
// if (StringUtils.isEmpty(params.fullName)) {
|
||||
// invalid("missingParamFullName", "You must specify a name for the attendee who will be joining the meeting.", REDIRECT_RESPONSE);
|
||||
// return
|
||||
// }
|
||||
// } else {
|
||||
// invalid("missingParamFullName", "You must specify a name for the attendee who will be joining the meeting.", REDIRECT_RESPONSE);
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// if (!StringUtils.isEmpty(params.meetingID)) {
|
||||
// params.meetingID = StringUtils.strip(params.meetingID);
|
||||
// if (StringUtils.isEmpty(params.meetingID)) {
|
||||
// invalid("missingParamMeetingID", "You must specify a meeting ID for the meeting.", REDIRECT_RESPONSE)
|
||||
// return
|
||||
// }
|
||||
// } else {
|
||||
// invalid("missingParamMeetingID", "You must specify a meeting ID for the meeting.", REDIRECT_RESPONSE)
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// if (StringUtils.isEmpty(params.password)) {
|
||||
// invalid("invalidPassword", "You either did not supply a password or the password supplied is neither the attendee or moderator password for this conference.", REDIRECT_RESPONSE);
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// // END - backward compatibility
|
||||
//
|
||||
// // Do we have a checksum? If none, complain.
|
||||
// if (StringUtils.isEmpty(params.checksum)) {
|
||||
// errors.missingParamError("checksum");
|
||||
// }
|
||||
|
||||
Boolean authenticated = false;
|
||||
|
||||
@ -273,6 +315,7 @@ class ApiController {
|
||||
}
|
||||
|
||||
// Do we have a name for the user joining? If none, complain.
|
||||
<<<<<<< HEAD
|
||||
if (!StringUtils.isEmpty(params.fullName)) {
|
||||
if (StringUtils.isEmpty(params.fullName)) {
|
||||
errors.missingParamError("fullName");
|
||||
@ -292,23 +335,43 @@ class ApiController {
|
||||
} else {
|
||||
errors.missingParamError("meetingID");
|
||||
}
|
||||
=======
|
||||
// if (!StringUtils.isEmpty(params.fullName)) {
|
||||
// if (StringUtils.isEmpty(params.fullName)) {
|
||||
// errors.missingParamError("fullName");
|
||||
// }
|
||||
// } else {
|
||||
// errors.missingParamError("fullName");
|
||||
// }
|
||||
String fullName = ParamsUtil.stripHTMLTags(params.fullName)
|
||||
//
|
||||
// // Do we have a meeting id? If none, complain.
|
||||
// if (!StringUtils.isEmpty(params.meetingID)) {
|
||||
// params.meetingID = StringUtils.strip(params.meetingID);
|
||||
// if (StringUtils.isEmpty(params.meetingID)) {
|
||||
// errors.missingParamError("meetingID");
|
||||
// }
|
||||
// } else {
|
||||
// errors.missingParamError("meetingID");
|
||||
// }
|
||||
>>>>>>> update-api-create-join-validation
|
||||
String externalMeetingId = params.meetingID
|
||||
|
||||
// Do we have a password? If not, complain.
|
||||
String attPW = params.password
|
||||
if (StringUtils.isEmpty(attPW)) {
|
||||
errors.missingParamError("password");
|
||||
}
|
||||
// if (StringUtils.isEmpty(attPW)) {
|
||||
// errors.missingParamError("password");
|
||||
// }
|
||||
|
||||
// Do we agree on the checksum? If not, complain.
|
||||
if (!paramsProcessorUtil.isChecksumSame(API_CALL, params.checksum, request.getQueryString())) {
|
||||
errors.checksumError()
|
||||
}
|
||||
|
||||
if (errors.hasErrors()) {
|
||||
respondWithErrors(errors, REDIRECT_RESPONSE)
|
||||
return
|
||||
}
|
||||
// if (!paramsProcessorUtil.isChecksumSame(API_CALL, params.checksum, request.getQueryString())) {
|
||||
// errors.checksumError()
|
||||
// }
|
||||
//
|
||||
// if (errors.hasErrors()) {
|
||||
// respondWithErrors(errors, REDIRECT_RESPONSE)
|
||||
// return
|
||||
// }
|
||||
|
||||
// Everything is good so far. Translate the external meeting id to an internal meeting id. If
|
||||
// we can't find the meeting, complain.
|
||||
@ -1667,6 +1730,7 @@ class ApiController {
|
||||
return us
|
||||
}
|
||||
|
||||
// Can be removed. Input sanitization is performed in the ValidatorService.
|
||||
private def sanitizeInput (input) {
|
||||
if(input == null)
|
||||
return
|
||||
|
Loading…
Reference in New Issue
Block a user