Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GRN-59: Implemented pagination on the API call #370

Merged
merged 4 commits into from
Mar 12, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Added the env variable and functionality to paginate the call to the …
…bbbapi
  • Loading branch information
farhatahmad committed Feb 12, 2019
commit c3c54a1f1e93fcad342c175432b73a3a03e14624
55 changes: 55 additions & 0 deletions app/controllers/recordings_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# frozen_string_literal: true

# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
#
# This program 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.0 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, see <http://www.gnu.org/licenses/>

class RecordingsController < ApplicationController
before_action :find_room
before_action :verify_room_ownership

META_LISTED = "gl-listed"

# POST /:meetingID/:record_id
def update_recording
meta = {
"meta_#{META_LISTED}" => (params[:state] == "public"),
}

res = @room.update_recording(params[:record_id], meta)

# Redirects to the page that made the initial request
redirect_to request.referrer if res[:updated]
end

# DELETE /:meetingID/:record_id
def delete_recording
@room.delete_recording(params[:record_id])

# Redirects to the page that made the initial request
redirect_to request.referrer
end

private

def find_room
@room = Room.find_by!(bbb_id: params[:meetingID])
end

# Ensure the user is logged into the room they are accessing.
def verify_room_ownership
redirect_to root_path unless @room.owned_by?(current_user)
end
end
30 changes: 3 additions & 27 deletions app/controllers/rooms_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,13 @@
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.

class RoomsController < ApplicationController
include RecordingsHelper

before_action :validate_accepted_terms, unless: -> { !Rails.configuration.terms }
before_action :validate_verified_email, unless: -> { !Rails.configuration.enable_email_verification }
before_action :find_room, except: :create
before_action :verify_room_ownership, except: [:create, :show, :join, :logout]

include RecordingsHelper
META_LISTED = "gl-listed"

# POST /
def create
redirect_to(root_path) && return unless current_user
Expand All @@ -50,10 +49,7 @@ def create
def show
if current_user && @room.owned_by?(current_user)
recs = @room.recordings
# Add the room id to each recording object
recs.each do |rec|
rec[:room_uid] = @room.uid
end

@recordings = recs
@is_running = @room.running?
else
Expand Down Expand Up @@ -161,26 +157,6 @@ def logout
redirect_to @room
end

# POST /:room_uid/:record_id
def update_recording
meta = {
"meta_#{META_LISTED}" => (params[:state] == "public"),
}

res = @room.update_recording(params[:record_id], meta)

# Redirects to the page that made the initial request
redirect_to request.referrer if res[:updated]
end

# DELETE /:room_uid/:record_id
def delete_recording
@room.delete_recording(params[:record_id])

# Redirects to the page that made the initial request
redirect_to request.referrer
end

private

def update_room_attributes(update_type)
Expand Down
18 changes: 3 additions & 15 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.

class UsersController < ApplicationController
include RecordingsHelper

before_action :find_user, only: [:edit, :update, :destroy]
before_action :ensure_unauthenticated, only: [:new, :create]

include RecordingsHelper

# POST /u
def create
# Verify that GreenLight is configured to allow user signup.
Expand Down Expand Up @@ -117,19 +117,7 @@ def destroy
# GET /u/:user_uid/recordings
def recordings
if current_user && current_user.uid == params[:user_uid]
@recordings = []
current_user.rooms.each do |room|
# Check that current user is the room owner
next unless room.owner == current_user

recs = room.recordings
# Add the room id to each recording object
recs.each do |rec|
rec[:room_uid] = room.uid
end
# Adds an array to another array
@recordings.push(*recs)
end
@recordings = current_user.all_recordings
else
redirect_to root_path
end
Expand Down
101 changes: 101 additions & 0 deletions app/models/concerns/api_concern.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# frozen_string_literal: true

# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
#
# This program 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.0 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, see <http://www.gnu.org/licenses/>.

module APIConcern
extend ActiveSupport::Concern
def bbb_endpoint
Rails.configuration.bigbluebutton_endpoint
end

def bbb_secret
Rails.configuration.bigbluebutton_secret
end

# Sets a BigBlueButtonApi object for interacting with the API.
def bbb
@bbb ||= if Rails.configuration.loadbalanced_configuration
lb_user = retrieve_loadbalanced_credentials(owner.provider)
BigBlueButton::BigBlueButtonApi.new(remove_slash(lb_user["apiURL"]), lb_user["secret"], "0.8")
else
BigBlueButton::BigBlueButtonApi.new(remove_slash(bbb_endpoint), bbb_secret, "0.8")
end
end

# Rereives the loadbalanced BigBlueButton credentials for a user.
def retrieve_loadbalanced_credentials(provider)
# Include Omniauth accounts under the Greenlight provider.
provider = "greenlight" if Rails.configuration.providers.include?(provider.to_sym)

# Build the URI.
uri = encode_bbb_url(
Rails.configuration.loadbalancer_endpoint + "getUser",
Rails.configuration.loadbalancer_secret,
name: provider
)

# Make the request.
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = (uri.scheme == 'https')
response = http.get(uri.request_uri)

unless response.is_a?(Net::HTTPSuccess)
raise "Error retrieving provider credentials: #{response.code} #{response.message}"
end

# Parse XML.
doc = XmlSimple.xml_in(response.body, 'ForceArray' => false)

# Return the user credentials if the request succeeded on the loadbalancer.
return doc['user'] if doc['returncode'] == RETURNCODE_SUCCESS

raise "User with provider #{provider} does not exist." if doc['messageKey'] == "noSuchUser"
raise "API call #{url} failed with #{doc['messageKey']}."
end

# Builds a request to retrieve credentials from the load balancer.
def encode_bbb_url(base_url, secret, params)
encoded_params = OAuth::Helper.normalize(params)
string = "getUser" + encoded_params + secret
checksum = OpenSSL::Digest.digest('sha1', string).unpack("H*").first

URI.parse("#{base_url}?#{encoded_params}&checksum=#{checksum}")
end

# Removes trailing forward slash from a URL.
def remove_slash(s)
s.nil? ? nil : s.chomp("/")
end

# Format recordings to match their current use in the app
def format_recordings(api_res)
api_res[:recordings].each do |r|
next if r.key?(:error)
# Format playbacks in a more pleasant way.
r[:playbacks] = if !r[:playback] || !r[:playback][:format]
[]
elsif r[:playback][:format].is_a?(Array)
r[:playback][:format]
else
[r[:playback][:format]]
end
r.delete(:playback)
end

api_res[:recordings].sort_by { |rec| rec[:endTime] }.reverse
end
end
80 changes: 3 additions & 77 deletions app/models/room.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.

class Room < ApplicationRecord
include ::APIConcern

before_create :setup

before_destroy :delete_all_recordings
Expand Down Expand Up @@ -118,21 +120,8 @@ def participants
# Fetches all recordings for a room.
def recordings
res = bbb.get_recordings(meetingID: bbb_id)
# Format playbacks in a more pleasant way.
res[:recordings].each do |r|
next if r.key?(:error)
r[:playbacks] = if !r[:playback] || !r[:playback][:format]
[]
elsif r[:playback][:format].is_a?(Array)
r[:playback][:format]
else
[r[:playback][:format]]
end

r.delete(:playback)
end

res[:recordings].sort_by { |rec| rec[:endTime] }.reverse
format_recordings(res)
end

# Fetches a rooms public recordings.
Expand All @@ -152,24 +141,6 @@ def delete_recording(record_id)

private

def bbb_endpoint
Rails.configuration.bigbluebutton_endpoint
end

def bbb_secret
Rails.configuration.bigbluebutton_secret
end

# Sets a BigBlueButtonApi object for interacting with the API.
def bbb
@bbb ||= if Rails.configuration.loadbalanced_configuration
lb_user = retrieve_loadbalanced_credentials(owner.provider)
BigBlueButton::BigBlueButtonApi.new(remove_slash(lb_user["apiURL"]), lb_user["secret"], "0.8")
else
BigBlueButton::BigBlueButtonApi.new(remove_slash(bbb_endpoint), bbb_secret, "0.8")
end
end

# Generates a uid for the room and BigBlueButton.
def setup
self.uid = random_room_uid
Expand All @@ -193,51 +164,6 @@ def random_room_uid
[owner.name_chunk, uid_chunk, uid_chunk].join('-').downcase
end

# Rereives the loadbalanced BigBlueButton credentials for a user.
def retrieve_loadbalanced_credentials(provider)
# Include Omniauth accounts under the Greenlight provider.
provider = "greenlight" if Rails.configuration.providers.include?(provider.to_sym)

# Build the URI.
uri = encode_bbb_url(
Rails.configuration.loadbalancer_endpoint + "getUser",
Rails.configuration.loadbalancer_secret,
name: provider
)

# Make the request.
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = (uri.scheme == 'https')
response = http.get(uri.request_uri)

unless response.is_a?(Net::HTTPSuccess)
raise "Error retrieving provider credentials: #{response.code} #{response.message}"
end

# Parse XML.
doc = XmlSimple.xml_in(response.body, 'ForceArray' => false)

# Return the user credentials if the request succeeded on the loadbalancer.
return doc['user'] if doc['returncode'] == RETURNCODE_SUCCESS

raise "User with provider #{provider} does not exist." if doc['messageKey'] == "noSuchUser"
raise "API call #{url} failed with #{doc['messageKey']}."
end

# Builds a request to retrieve credentials from the load balancer.
def encode_bbb_url(base_url, secret, params)
encoded_params = OAuth::Helper.normalize(params)
string = "getUser" + encoded_params + secret
checksum = OpenSSL::Digest.digest('sha1', string).unpack("H*").first

URI.parse("#{base_url}?#{encoded_params}&checksum=#{checksum}")
end

# Removes trailing forward slash from a URL.
def remove_slash(s)
s.nil? ? nil : s.chomp("/")
end

# Generates a random password for a meeting.
def random_password(length)
charset = ("a".."z").to_a + ("A".."Z").to_a
Expand Down
26 changes: 26 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.

class User < ApplicationRecord
include ::APIConcern

attr_accessor :reset_token
after_create :initialize_main_room
before_save { email.try(:downcase!) }
Expand Down Expand Up @@ -94,6 +96,30 @@ def auth_image(auth)
end
end

def all_recordings
pag_num = Rails.configuration.pagination_number

pag_loops = rooms.length / pag_num - 1

res = { recordings: [] }

(0..pag_loops).each do |i|
pag_rooms = rooms[pag_num * i, pag_num]

# bbb.get_recordings returns an object
# take only the array portion of the object that is returned
full_res = bbb.get_recordings(meetingID: pag_rooms.pluck(:bbb_id))
res[:recordings].push(*full_res[:recordings])
end

last_pag_room = rooms[pag_num * (pag_loops + 1), rooms.length % pag_num]

full_res = bbb.get_recordings(meetingID: last_pag_room.pluck(:bbb_id))
res[:recordings].push(*full_res[:recordings])

format_recordings(res)
end

# Sets the password reset attributes.
def create_reset_digest
self.reset_token = User.new_token
Expand Down
Loading