From 4b3102e5218bb3043c1fcc95ddbfb05391c23363 Mon Sep 17 00:00:00 2001 From: Jeremy Thomerson Date: Fri, 25 Sep 2009 03:00:15 +0000 Subject: [PATCH] merging my branch into trunk git-svn-id: http://bigbluebutton.googlecode.com/svn/trunk@2608 af16638f-c34d-0410-8cfa-b39d5352b314 --- bigbluebutton-web/.project | 7 +- .../grails-app/conf/SecurityFilters.groovy | 3 +- .../grails-app/conf/UrlMappings.groovy | 2 + .../web/controllers/ApiController.groovy | 156 ++++++++++++++++++ .../api/domain/DynamicConference.groovy | 61 +++++++ merge-info.txt | 10 ++ 6 files changed, 232 insertions(+), 7 deletions(-) create mode 100644 bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy create mode 100644 bigbluebutton-web/src/groovy/org/bigbluebutton/api/domain/DynamicConference.groovy create mode 100644 merge-info.txt diff --git a/bigbluebutton-web/.project b/bigbluebutton-web/.project index 481530a029..d4190fef67 100644 --- a/bigbluebutton-web/.project +++ b/bigbluebutton-web/.project @@ -10,14 +10,9 @@ - - org.codehaus.groovy.eclipse.groovyBuilder - - - + org.eclipse.jdt.groovy.core.groovyNature org.eclipse.jdt.core.javanature - org.codehaus.groovy.eclipse.groovyNature diff --git a/bigbluebutton-web/grails-app/conf/SecurityFilters.groovy b/bigbluebutton-web/grails-app/conf/SecurityFilters.groovy index 7748fe3709..ed7b8add49 100644 --- a/bigbluebutton-web/grails-app/conf/SecurityFilters.groovy +++ b/bigbluebutton-web/grails-app/conf/SecurityFilters.groovy @@ -27,7 +27,8 @@ class SecurityFilters { //if ((controllerName == "join") || (controllerName == "presentation")) return true switch (controllerName) { - case 'portal': + case 'api': + case 'portal': case 'join': case 'adhoc': case 'presentation': diff --git a/bigbluebutton-web/grails-app/conf/UrlMappings.groovy b/bigbluebutton-web/grails-app/conf/UrlMappings.groovy index aa88af606e..01ea0c3aa3 100644 --- a/bigbluebutton-web/grails-app/conf/UrlMappings.groovy +++ b/bigbluebutton-web/grails-app/conf/UrlMappings.groovy @@ -45,6 +45,8 @@ class UrlMappings { "/portal/$action"(controller:"portal") + "/api/$action"(controller:"api") + "/conference-session/$action?/$id?"(controller:"publicScheduledSession") diff --git a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy new file mode 100644 index 0000000000..d02e4130fe --- /dev/null +++ b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy @@ -0,0 +1,156 @@ +/* BigBlueButton - http://www.bigbluebutton.org + * + * + * Copyright (c) 2008-2009 by respective authors (see below). All rights reserved. + * + * BigBlueButton is free software; you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free Software + * Foundation; either version 3 of the License, or (at your option) any later + * version. + * + * BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with BigBlueButton; if not, If not, see . + * + * @author Jeremy Thomerson + * @version $Id: $ + */ +package org.bigbluebutton.web.controllers + + + +import org.apache.commons.codec.binary.Hex; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.lang.StringUtils; + +import org.bigbluebutton.api.domain.DynamicConference; +import org.bigbluebutton.web.services.AdhocConferenceService +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +class ApiController { + + // TODO: turn println back into log.debug and log.info - not sure why those weren't working + // but it must be a configuration thing + + private static final String CONTROLLER_NAME = 'ApiController' + + private static final String RESP_CODE_SUCCESS = 'SUCCESS' + private static final String RESP_CODE_FAILED = 'FAILED' + + private static final String SECURITY_SALT = '639259d4-9dd8-4b25-bf01-95f9567eaf4b' + + // TODO: security salt will obviously need to be a part of the server configuration + // and not hard-coded here. This is just for development / testing + String securitySalt = SECURITY_SALT + AdhocConferenceService adhocConferenceService + + /* general methods */ + def index = { + println CONTROLLER_NAME + "#index" + invalid("noActionSpecified", "You did not specify an API action.") + } + + /* interface (API) methods */ + def create = { + println CONTROLLER_NAME + "#create" + + if (!doChecksumSecurity()) { + invalid("checksumError", "You did not pass the checksum security check") + return + } + + String name = params.name + if (name == null) { + invalid("missingParamName", "You must specify a name for the meeting."); + return + } + + println("passed parameter validation - creating conference"); + String mtgID = params.meetingID + String attPW = params.attendeePW + String modPW = params.moderatorPW + Integer maxParts = params.maxParticipants + String mmRoom = params.meetmeRoom + String mmServer = params.meetmeServer + + DynamicConference conf = new DynamicConference(name, mtgID, attPW, modPW, maxParts) + println("Conference created: " + conf); + // TODO: put this into a service that holds the active dynamic conferences + // TODO: support meetmeRoom and meetmeServer + + // success! + respondWithConference(conf, params) + } + + /* helper methods */ + def doChecksumSecurity() { + println CONTROLLER_NAME + "#doChecksumSecurity" + println "checksum: " + params.checksum + "; query string: " + request.getQueryString() + if (StringUtils.isEmpty(request.getQueryString())) { + invalid("noQueryString", "No query string was found in your request.") + return false; + } + if (StringUtils.isEmpty(securitySalt) == false) { + String qs = request.getQueryString() + // handle either checksum as first or middle / end parameter + // TODO: this is hackish - should be done better + qs = qs.replace("&checksum=" + params.checksum, "") + qs = qs.replace("checksum=" + params.checksum + "&", "") + println "query string after checksum removed: " + qs + String cs = getHash(qs, securitySalt) + println "our checksum: " + cs + return cs != null && cs.equals(params.checksum) + } + println "Security is disabled in this service currently." + return true; + } + + public String getHash(String string, String salt) throws NoSuchAlgorithmException { + return DigestUtils.shaHex(string + salt) + } + + def beforeInterceptor = { + if (!adhocConferenceService.serviceEnabled) { + invalid("apiNotEnabled", "The API service and/or controller is not enabled on this server. To use it, you must first enable it.") + } + } + + def respondWithConference(conf, params) { + response.addHeader("Cache-Control", "no-cache") + withFormat { + xml { + println "Rendering as xml" + render(contentType:"text/xml") { + response() { + returncode(RESP_CODE_SUCCESS) + meetingToken("${conf.meetingToken}") + meetingID("${conf.meetingID}") + attendeePW("${conf.attendeePassword}") + moderatorPW("${conf.moderatorPassword}") + } + } + } + } + } + + def invalid(key, msg) { + println CONTROLLER_NAME + "#invalid" + response.addHeader("Cache-Control", "no-cache") + withFormat { + xml { + render(contentType:"text/xml") { + response() { + returncode(RESP_CODE_FAILED) + messageKey(key) + message(msg) + } + } + } + } + } + +} diff --git a/bigbluebutton-web/src/groovy/org/bigbluebutton/api/domain/DynamicConference.groovy b/bigbluebutton-web/src/groovy/org/bigbluebutton/api/domain/DynamicConference.groovy new file mode 100644 index 0000000000..3767320ef2 --- /dev/null +++ b/bigbluebutton-web/src/groovy/org/bigbluebutton/api/domain/DynamicConference.groovy @@ -0,0 +1,61 @@ +/* BigBlueButton - http://www.bigbluebutton.org + * + * + * Copyright (c) 2008-2009 by respective authors (see below). All rights reserved. + * + * BigBlueButton is free software; you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free Software + * Foundation; either version 3 of the License, or (at your option) any later + * version. + * + * BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with BigBlueButton; if not, If not, see . + * + * @author Jeremy Thomerson + * @version $Id: $ + */ +package org.bigbluebutton.api.domain; + +import org.apache.commons.lang.RandomStringUtils; +import java.util.UUID; + +import org.apache.commons.lang.StringUtils; +import org.bigbluebutton.web.domain.Conference; + +public class DynamicConference extends Conference { + + String meetingID + String meetingToken + + String moderatorPassword + String attendeePassword + + int maxParticipants + + public DynamicConference() { + + } + public DynamicConference(name, meetingID, attendeePW, moderatorPW, maxParticipants) { + this.setName(name) + this.setMeetingID(StringUtils.isEmpty(meetingID) ? "" : meetingID) + this.setAttendeePassword(attendeePW == null ? createPassword() : attendeePW) + this.setModeratorPassword(moderatorPW == null ? createPassword() : moderatorPW) + this.setMaxParticipants(maxParticipants == null || maxParticipants < 0 ? -1 : maxParticipants) + this.setMeetingToken(createMeetingToken()) + } + + public static String createMeetingToken() { + return UUID.randomUUID().toString() + } + + public static String createPassword() { + return RandomStringUtils.randomAlphanumeric(8).toLowerCase(); + } + + String toString() {"DynamicConference: ${this.meetingToken} [${this.meetingID}]:${this.name}"} + +} \ No newline at end of file diff --git a/merge-info.txt b/merge-info.txt new file mode 100644 index 0000000000..28020d5b00 --- /dev/null +++ b/merge-info.txt @@ -0,0 +1,10 @@ +# This file simply contains up-to-date merge information for this branch. +# +# All changes from trunk will be merged into this trunk during development. +# + +# Last update was: +# -r 2575:HEAD - Sep 22 13:43 + +# Command used +svn merge -r 2575:HEAD https://bigbluebutton.googlecode.com/svn/trunk/