diff --git a/.gitignore b/.gitignore index e4089d81..64c671b9 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ # Ignore Byebug command history file. .byebug_history +.env diff --git a/Gemfile b/Gemfile index afc9399f..084a990e 100644 --- a/Gemfile +++ b/Gemfile @@ -31,9 +31,11 @@ gem 'jbuilder', '~> 2.5' # gem 'capistrano-rails', group: :development group :development, :test do + # For environment configuration + gem 'dotenv-rails' + # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platform: :mri - gem 'dotenv-rails' end group :development do @@ -48,7 +50,13 @@ end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] -gem 'omniauth' -gem 'omniauth-twitter' -gem 'omniauth-google-oauth2' +gem 'omniauth', '1.3.1' +gem 'omniauth-twitter', '1.2.1' +gem 'omniauth-google-oauth2', '0.4.1' + gem 'bigbluebutton-api-ruby' + +gem 'bootstrap-sass', '3.3.0.0' +gem 'bootstrap-social-rails', '~> 4.12' +gem 'jquery-ui-rails' +gem 'jquery-datatables-rails', '~> 3.4.0' diff --git a/Gemfile.lock b/Gemfile.lock index aa954982..b24c67ff 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -41,6 +41,10 @@ GEM arel (7.1.4) bigbluebutton-api-ruby (1.6.0) xml-simple (~> 1.1) + bootstrap-sass (3.3.0.0) + sass (~> 3.2) + bootstrap-social-rails (4.12.0) + railties (>= 3.1) builder (3.2.2) byebug (9.0.6) coffee-rails (4.2.1) @@ -63,17 +67,24 @@ GEM ffi (1.9.14) globalid (0.3.7) activesupport (>= 4.1.0) - hashie (3.4.6) + hashie (3.4.4) i18n (0.7.0) jbuilder (2.6.0) activesupport (>= 3.0.0, < 5.1) multi_json (~> 1.2) + jquery-datatables-rails (3.4.0) + actionpack (>= 3.1) + jquery-rails + railties (>= 3.1) + sass-rails jquery-rails (4.2.1) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) + jquery-ui-rails (5.0.5) + railties (>= 3.2.16) json (1.8.3) - jwt (1.5.6) + jwt (1.5.4) listen (3.0.8) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) @@ -193,15 +204,19 @@ PLATFORMS DEPENDENCIES bigbluebutton-api-ruby + bootstrap-sass (= 3.3.0.0) + bootstrap-social-rails (~> 4.12) byebug coffee-rails (~> 4.2) dotenv-rails jbuilder (~> 2.5) + jquery-datatables-rails (~> 3.4.0) jquery-rails + jquery-ui-rails listen (~> 3.0.5) - omniauth - omniauth-google-oauth2 - omniauth-twitter + omniauth (= 1.3.1) + omniauth-google-oauth2 (= 0.4.1) + omniauth-twitter (= 1.2.1) puma (~> 3.0) rails (~> 5.0.0, >= 5.0.0.1) sass-rails (~> 5.0) @@ -214,4 +229,4 @@ DEPENDENCIES web-console BUNDLED WITH - 1.13.4 + 1.13.5 diff --git a/app/assets/images/bbb-logo.png b/app/assets/images/bbb-logo.png new file mode 100644 index 00000000..3737f7c5 Binary files /dev/null and b/app/assets/images/bbb-logo.png differ diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index b12018d0..ce912696 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -10,7 +10,8 @@ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details // about supported directives. // -//= require jquery -//= require jquery_ujs +//= require jquery2 +//= require jquery-ui +//= require bootstrap-sprockets //= require turbolinks //= require_tree . diff --git a/app/assets/javascripts/bbb.coffee b/app/assets/javascripts/bbb.coffee new file mode 100644 index 00000000..24f83d18 --- /dev/null +++ b/app/assets/javascripts/bbb.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 0ebd7fe8..a15c8c86 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -11,5 +11,7 @@ * It is generally better to create a new file per style scope. * *= require_tree . + *= require jquery-ui + *= require dataTables/jquery.dataTables *= require_self */ diff --git a/app/assets/stylesheets/bbb.scss b/app/assets/stylesheets/bbb.scss new file mode 100644 index 00000000..687fe4e6 --- /dev/null +++ b/app/assets/stylesheets/bbb.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the bbb controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/landing.scss b/app/assets/stylesheets/landing.scss index f33d6f8d..0dbe3ca0 100644 --- a/app/assets/stylesheets/landing.scss +++ b/app/assets/stylesheets/landing.scss @@ -1,3 +1,7 @@ // Place all the styles related to the landing controller here. // They will automatically be included in application.css. // You can use Sass (SCSS) here: http://sass-lang.com/ + +// Bootstrap +@import "bootstrap-sprockets"; +@import "bootstrap"; diff --git a/app/assets/stylesheets/narrow-jumbotron.css b/app/assets/stylesheets/narrow-jumbotron.css new file mode 100644 index 00000000..a2dbf869 --- /dev/null +++ b/app/assets/stylesheets/narrow-jumbotron.css @@ -0,0 +1,79 @@ +/* Space out content a bit */ +body { + padding-top: 1.5rem; + padding-bottom: 1.5rem; +} + +/* Everything but the jumbotron gets side spacing for mobile first views */ +.header, +.marketing, +.footer { + padding-right: 1rem; + padding-left: 1rem; +} + +/* Custom page header */ +.header { + padding-bottom: 1rem; + border-bottom: .05rem solid #e5e5e5; +} +/* Make the masthead heading the same height as the navigation */ +.header h3 { + margin-top: 0; + margin-bottom: 0; + line-height: 3rem; +} + +/* Custom page footer */ +.footer { + padding-top: 1.5rem; + color: #777; + border-top: .05rem solid #e5e5e5; +} + +/* Customize container */ +@media (min-width: 48em) { + .container { + max-width: 72rem; + } +} +.container-narrow > hr { + margin: 2rem 0; +} + +/* Main marketing message and sign up button */ +.jumbotron { + text-align: center; + border-bottom: .05rem solid #e5e5e5; +} +.jumbotron .btn { + padding: .75rem 1.5rem; + font-size: 1.5rem; +} + +/* Supporting marketing content */ +.marketing { + margin: 3rem 0; +} +.marketing p + h4 { + margin-top: 1.5rem; +} + +/* Responsive: Portrait tablets and up */ +@media screen and (min-width: 48em) { + /* Remove the padding we set earlier */ + .header, + .marketing, + .footer { + padding-right: 0; + padding-left: 0; + } + /* Space out the masthead */ + .header { + margin-bottom: 2rem; + } + /* Remove the bottom border on the jumbotron for visual effect */ + .jumbotron { + border-bottom: 0; + } +} diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 5e1257af..06835456 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,5 +1,9 @@ +require 'bigbluebutton_api' +require 'digest/sha1' + class ApplicationController < ActionController::Base protect_from_forgery with: :exception + include ApplicationHelper def current_user @current_user ||= User.find_by(id: session[:user_id]) diff --git a/app/controllers/bbb_controller.rb b/app/controllers/bbb_controller.rb new file mode 100644 index 00000000..e51f7c36 --- /dev/null +++ b/app/controllers/bbb_controller.rb @@ -0,0 +1,38 @@ +class BbbController < ApplicationController + include BbbHelper + + # GET /join + # GET /join.json + def join + logger.info params.to_json + if ( !params.has_key?(:id) ) + render_response("missing_parameter", "meeting token was not included", :bad_request) + elsif ( !params.has_key?(:name) ) + render_response("missing_parameter", "user name was not included", :bad_request) + else + bbb_join_url = bbb_join_url(params[:id], false, params[:name], false) + if bbb_join_url[:returncode] + logger.info "#Execute the redirect" + render_response("ok", "execute the redirect", :ok, {:join_url => bbb_join_url[:join_url]}) + else + render_response("bigbluebutton_error", "join url could not be created", :internal_server_error) + end + end + end + + def close + end + + private + def render_response(messageKey, message, status, response={}) + respond_to do |format| + if (status == :ok) + format.html { render :template => "bbb/join" } + format.json { render :json => { :messageKey => messageKey, :message => message, :status => status, :response => response }, :status => status } + else + format.html { render :template => "errors/error" } + format.json { render :json => { :messageKey => messageKey, :message => message, :status => status, :response => response }, :status => status } + end + end + end +end diff --git a/app/controllers/landing_controller.rb b/app/controllers/landing_controller.rb index 135fd099..b02805b7 100644 --- a/app/controllers/landing_controller.rb +++ b/app/controllers/landing_controller.rb @@ -1,15 +1,8 @@ class LandingController < ApplicationController + include LandingHelper + def index @meeting_token = params[:id] || @meeting_token = rand.to_s[2..10] @meeting_url = meeting_url(@meeting_token) end - - private - def meeting_url(meeting_token) - _meeting_url = "#{request.original_url}" - _meeting_url += "meeting" if ( request.original_url == "#{request.base_url}/" ) - _meeting_url += "/" unless _meeting_url.end_with?('/') - _meeting_url += "#{meeting_token}" if !params.has_key?(:id) - _meeting_url - end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index de6be794..3b958476 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,2 +1,24 @@ module ApplicationHelper + def bbb_endpoint + logger.info APP_CONFIG + #if ((defined? APP_CONFIG).to_s == 'constant') && (APP_CONFIG.has_key?('bbb_endpoint')) + # APP_CONFIG['bbb_endpoint'] + #else + 'http://test-install.blindsidenetworks.com/bigbluebutton/' + #end + end + + def bbb_secret + #if (defined? APP_CONFIG).to_s == 'constant' && (APP_CONFIG.has_key? 'bbb_secret') + # APP_CONFIG['bbb_secret'] + #else + '8cd8ef52e8e101574e400365b55e11a6' + #end + end + + def random_password(length) + o = [('a'..'z'), ('A'..'Z')].map { |i| i.to_a }.flatten + password = (0...length).map { o[rand(o.length)] }.join + return password + end end diff --git a/app/helpers/bbb_helper.rb b/app/helpers/bbb_helper.rb new file mode 100644 index 00000000..c603b4a9 --- /dev/null +++ b/app/helpers/bbb_helper.rb @@ -0,0 +1,36 @@ +module BbbHelper + def bbb_join_url(meeting_token, meeting_recorded=false, user_fullname='User', user_is_moderator=false) + bbb ||= BigBlueButton::BigBlueButtonApi.new(helpers.bbb_endpoint + "api", bbb_secret, "0.8", true) + if !bbb + return { :returncode => false, :messageKey => "BBBAPICallInvalid", :message => "BBB API call invalid." } + else + meeting_id = (Digest::SHA1.hexdigest(Rails.application.secrets[:secret_key_base]+meeting_token)).to_s + + #See if the meeting is running + begin + bbb_meeting_info = bbb.get_meeting_info( meeting_id, nil ) + rescue BigBlueButton::BigBlueButtonException => exc + logger.info "Message for the log file #{exc.key}: #{exc.message}" + #This means that is not created, so create the meeting + logout_url = "#{request.base_url}/bbb/close" #Closes the window after correct logout + moderator_password = random_password(12) + viewer_password = random_password(12) + meeting_options = {:record => meeting_recorded.to_s, :logoutURL => logout_url, :moderatorPW => moderator_password, :attendeePW => viewer_password } + bbb.create_meeting(meeting_token, meeting_id, meeting_options) + + #And then get meeting info + bbb_meeting_info = bbb.get_meeting_info( meeting_id, nil ) + end + + #Get the join url + if (user_is_moderator) + password = bbb_meeting_info[:moderatorPW] + else + passord = bbb_meeting_info[:attendeePW] + end + join_url = bbb.join_meeting_url(meeting_id, user_fullname, password ) + return { :returncode => true, :join_url => join_url, :messageKey => "", :message => "" } + end + end + +end diff --git a/app/helpers/landing_helper.rb b/app/helpers/landing_helper.rb index 6aa3ee92..3f9b3bc7 100644 --- a/app/helpers/landing_helper.rb +++ b/app/helpers/landing_helper.rb @@ -1,2 +1,9 @@ module LandingHelper + def meeting_url(meeting_token) + _meeting_url = "#{request.original_url}" + _meeting_url += "meeting" if ( request.original_url == "#{request.base_url}/" ) + _meeting_url += "/" unless _meeting_url.end_with?('/') + _meeting_url += "#{meeting_token}" if !params.has_key?(:id) + _meeting_url.gsub(/\/+$/, '') + end end diff --git a/app/views/bbb/end.html.erb b/app/views/bbb/end.html.erb new file mode 100644 index 00000000..ad2b2d3f --- /dev/null +++ b/app/views/bbb/end.html.erb @@ -0,0 +1,2 @@ +

Bbb#end

+

Find me in app/views/bbb/end.html.erb

diff --git a/app/views/bbb/join.html.erb b/app/views/bbb/join.html.erb new file mode 100644 index 00000000..55f29286 --- /dev/null +++ b/app/views/bbb/join.html.erb @@ -0,0 +1,2 @@ +

Bbb#join

+

Find me in app/views/bbb/join.html.erb

diff --git a/app/views/errors/error.html.erb b/app/views/errors/error.html.erb new file mode 100644 index 00000000..f3066b91 --- /dev/null +++ b/app/views/errors/error.html.erb @@ -0,0 +1,2 @@ +

Errors#error

+

Find me in app/views/errors/error.html.erb

diff --git a/app/views/landing/index.html.erb b/app/views/landing/index.html.erb index 935f565a..58d2872c 100644 --- a/app/views/landing/index.html.erb +++ b/app/views/landing/index.html.erb @@ -1,38 +1,71 @@ -

Landing#index

-
-

<%= @meeting_url %>

-
+
-
-
- - -
-
+ +
-
- - - - -
+
+
+ +

+
+ <%= @meeting_url %> +
+

+ + +
+
+
+ + +
+ +
+
+
+ +

Hi Everyone

-

The meeting will be at this URL

-

<%= @meeting_url %>

-

Please join!

-
+ + + + + + +
+ +
+
- - - + <% if current_user.nil? %>