Skip to content
Snippets Groups Projects
Unverified Commit 6ea07374 authored by Khemissi Amir's avatar Khemissi Amir Committed by GitHub
Browse files

Fixes to complete the relative URL root path support. (#5106)

* Action cable: Added support for relative URL root path.

* Meeting start: Added support for relative URL root path.

* Application: Minor improvements to relative URL root path parsing.

* Email branding: Added support for relative URL root path.
	+ Refactored and improved Setting getter service.

* Manage users: Fixed edit user on custom relative URL root path.
parent 2de61fd7
No related branches found
No related tags found
No related merge requests found
...@@ -29,7 +29,7 @@ module Api ...@@ -29,7 +29,7 @@ module Api
# Starts a BigBlueButton meetings and joins in the meeting starter # Starts a BigBlueButton meetings and joins in the meeting starter
def start def start
begin begin
MeetingStarter.new(room: @room, base_url: root_url, current_user:, provider: current_provider).call MeetingStarter.new(room: @room, base_url: request.base_url, current_user:, provider: current_provider).call
rescue BigBlueButton::BigBlueButtonException => e rescue BigBlueButton::BigBlueButtonException => e
return render_error status: :bad_request unless e.key == 'idNotUnique' return render_error status: :bad_request unless e.key == 'idNotUnique'
end end
...@@ -68,7 +68,7 @@ module Api ...@@ -68,7 +68,7 @@ module Api
if !data[:status] && settings['glAnyoneCanStart'] == 'true' # Meeting isnt running and anyoneCanStart setting is enabled if !data[:status] && settings['glAnyoneCanStart'] == 'true' # Meeting isnt running and anyoneCanStart setting is enabled
begin begin
MeetingStarter.new(room: @room, base_url: root_url, current_user:, provider: current_provider).call MeetingStarter.new(room: @room, base_url: request.base_url, current_user:, provider: current_provider).call
rescue BigBlueButton::BigBlueButtonException => e rescue BigBlueButton::BigBlueButtonException => e
return render_error status: :bad_request unless e.key == 'idNotUnique' return render_error status: :bad_request unless e.key == 'idNotUnique'
end end
......
...@@ -25,17 +25,9 @@ module Api ...@@ -25,17 +25,9 @@ module Api
# GET /api/v1/site_settings # GET /api/v1/site_settings
# Returns the values of 1 or multiple site_settings that are not forbidden to access # Returns the values of 1 or multiple site_settings that are not forbidden to access
def index def index
settings = {}
return render_error status: :forbidden if forbidden_settings(params[:names]) return render_error status: :forbidden if forbidden_settings(params[:names])
if params[:names].is_a?(Array)
params[:names].each do |name|
settings[name] = SettingGetter.new(setting_name: name, provider: current_provider).call
end
else
# return the value directly
settings = SettingGetter.new(setting_name: params[:names], provider: current_provider).call settings = SettingGetter.new(setting_name: params[:names], provider: current_provider).call
end
render_data data: settings, status: :ok render_data data: settings, status: :ok
end end
......
...@@ -19,4 +19,4 @@ ...@@ -19,4 +19,4 @@
import { createConsumer } from '@rails/actioncable'; import { createConsumer } from '@rails/actioncable';
export default createConsumer(); export default createConsumer(`${process.env.RELATIVE_URL_ROOT}/cable`);
...@@ -15,11 +15,11 @@ ...@@ -15,11 +15,11 @@
// with Greenlight; if not, see <http://www.gnu.org/licenses/>. // with Greenlight; if not, see <http://www.gnu.org/licenses/>.
import { useQuery } from 'react-query'; import { useQuery } from 'react-query';
import axios from 'axios'; import axios from '../../../helpers/Axios';
export default function useUser(userId) { export default function useUser(userId) {
return useQuery( return useQuery(
['getUser', userId], ['getUser', userId],
() => axios.get(`/api/v1/users/${userId}.json`).then((resp) => resp.data.data), () => axios.get(`/users/${userId}.json`).then((resp) => resp.data.data),
); );
} }
...@@ -55,8 +55,7 @@ class UserMailer < ApplicationMailer ...@@ -55,8 +55,7 @@ class UserMailer < ApplicationMailer
end end
def branding def branding
branding_hash = SiteSetting.includes(:setting).where(provider: @provider, settings: { name: %w[PrimaryColor BrandingImage] }) branding_hash = SettingGetter.new(setting_name: %w[PrimaryColor BrandingImage], provider: @provider).call
.pluck(:name, :value).to_h
@brand_image = ActionController::Base.helpers.image_url(branding_hash['BrandingImage'], host: @base_url) @brand_image = ActionController::Base.helpers.image_url(branding_hash['BrandingImage'], host: @base_url)
@brand_color = branding_hash['PrimaryColor'] @brand_color = branding_hash['PrimaryColor']
end end
......
...@@ -56,7 +56,7 @@ class MeetingStarter ...@@ -56,7 +56,7 @@ class MeetingStarter
private private
def computed_options(access_code:) def computed_options(access_code:)
room_url = File.join(@base_url, '/rooms/', @room.friendly_id, '/join') room_url = "#{root_url(host: @base_url)}rooms/#{@room.friendly_id}/join"
moderator_message = "#{I18n.t('meeting.moderator_message')}<br>#{room_url}" moderator_message = "#{I18n.t('meeting.moderator_message')}<br>#{room_url}"
moderator_message += "<br>#{I18n.t('meeting.access_code', code: access_code)}" if access_code.present? moderator_message += "<br>#{I18n.t('meeting.access_code', code: access_code)}" if access_code.present?
{ {
......
...@@ -20,40 +20,51 @@ class SettingGetter ...@@ -20,40 +20,51 @@ class SettingGetter
include Rails.application.routes.url_helpers include Rails.application.routes.url_helpers
def initialize(setting_name:, provider:) def initialize(setting_name:, provider:)
@setting_name = setting_name @setting_name = Array(setting_name)
@provider = provider @provider = provider
end end
def call def call
setting = SiteSetting.joins(:setting) # Fetch the site settings records while eager loading their respective settings ↓
.find_by( site_settings = SiteSetting.includes(:setting)
.where(
provider: @provider, provider: @provider,
setting: { name: @setting_name } setting: { name: @setting_name }
) )
value = if @setting_name == 'BrandingImage' # Pessimist check: Pass only if all provided names were found ↓
if setting.image.attached? return nil unless @setting_name.size == site_settings.size
rails_blob_path setting.image, only_path: true
else site_settings_hash = {}
ActionController::Base.helpers.image_path('bbb_logo.png')
end # In memory prepare the result hash ↓
else site_settings.map do |site_setting|
setting&.value site_settings_hash[site_setting.setting.name] = transform_value(site_setting)
end end
transform_value(value) # If there's only one setting is being fetched no need for a hash ↓
return site_settings_hash.values.first if site_settings_hash.size == 1
# A Hash<setting_name => parsed_value> is returned otherwise ↓
site_settings_hash
end end
private private
def transform_value(value) def transform_value(site_setting)
case value if site_setting.setting.name == 'BrandingImage'
return rails_blob_path site_setting.image, only_path: true if site_setting.image.attached?
return ActionController::Base.helpers.image_path('bbb_logo.png')
end
case site_setting.value
when 'true' when 'true'
true true
when 'false' when 'false'
false false
else else
value site_setting.value
end end
end end
end end
...@@ -66,6 +66,8 @@ module Greenlight ...@@ -66,6 +66,8 @@ module Greenlight
config.bigbluebutton_secret = ENV.fetch('BIGBLUEBUTTON_SECRET', '8cd8ef52e8e101574e400365b55e11a6') config.bigbluebutton_secret = ENV.fetch('BIGBLUEBUTTON_SECRET', '8cd8ef52e8e101574e400365b55e11a6')
config.relative_url_root = ENV.fetch('RELATIVE_URL_ROOT', '/') # Fetch 'RELATIVE_URL_ROOT' ENV variable value while removing any trailing slashes.
config.relative_url_root = ENV.fetch('RELATIVE_URL_ROOT', nil)&.sub(%r{/*\z}, '')
config.relative_url_root = '/' if config.relative_url_root.blank?
end end
end end
import * as esbuild from 'esbuild'; import * as esbuild from 'esbuild';
const relativeUrlRoot = (process.env.RELATIVE_URL_ROOT || '').replace(/\/$/, ''); // Fetch 'RELATIVE_URL_ROOT' ENV variable value while removing any trailing slashes.
const relativeUrlRoot = (process.env.RELATIVE_URL_ROOT || '').replace(/\/*$/, '');
await esbuild.build({ await esbuild.build({
entryPoints: ['app/javascript/main.jsx'], entryPoints: ['app/javascript/main.jsx'],
......
import * as esbuild from 'esbuild'; import * as esbuild from 'esbuild';
const relativeUrlRoot = (process.env.RELATIVE_URL_ROOT || '').replace(/\/$/, ''); // Fetch 'RELATIVE_URL_ROOT' ENV variable value while removing any trailing slashes.
const relativeUrlRoot = (process.env.RELATIVE_URL_ROOT || '').replace(/\/*$/, '');
await esbuild.build({ await esbuild.build({
entryPoints: ['app/javascript/main.jsx'], entryPoints: ['app/javascript/main.jsx'],
......
...@@ -41,7 +41,7 @@ RSpec.describe Api::V1::MeetingsController, type: :controller do ...@@ -41,7 +41,7 @@ RSpec.describe Api::V1::MeetingsController, type: :controller do
describe '#start' do describe '#start' do
it 'makes a call to the MeetingStarter service with the right values and returns the join url' do it 'makes a call to the MeetingStarter service with the right values and returns the join url' do
expect(MeetingStarter).to receive(:new).with(room:, base_url: root_url, current_user: user, provider: 'greenlight').and_call_original expect(MeetingStarter).to receive(:new).with(room:, base_url: request.base_url, current_user: user, provider: 'greenlight').and_call_original
expect_any_instance_of(MeetingStarter).to receive(:call) expect_any_instance_of(MeetingStarter).to receive(:call)
expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room:, name: user.name, avatar_url: nil, role: 'Moderator') expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room:, name: user.name, avatar_url: nil, role: 'Moderator')
...@@ -343,7 +343,7 @@ RSpec.describe Api::V1::MeetingsController, type: :controller do ...@@ -343,7 +343,7 @@ RSpec.describe Api::V1::MeetingsController, type: :controller do
allow_any_instance_of(BigBlueButtonApi).to receive(:meeting_running?).and_return(false) allow_any_instance_of(BigBlueButtonApi).to receive(:meeting_running?).and_return(false)
expect(MeetingStarter).to receive(:new).with(room:, base_url: root_url, current_user: user, provider: 'greenlight').and_call_original expect(MeetingStarter).to receive(:new).with(room:, base_url: request.base_url, current_user: user, provider: 'greenlight').and_call_original
expect_any_instance_of(MeetingStarter).to receive(:call) expect_any_instance_of(MeetingStarter).to receive(:call)
post :status, params: { friendly_id: room.friendly_id, name: user.name } post :status, params: { friendly_id: room.friendly_id, name: user.name }
......
...@@ -38,15 +38,13 @@ RSpec.describe Api::V1::SiteSettingsController, type: :controller do ...@@ -38,15 +38,13 @@ RSpec.describe Api::V1::SiteSettingsController, type: :controller do
end end
it 'calls SettingGetter and returns multiple values' do it 'calls SettingGetter and returns multiple values' do
expect(SettingGetter).to receive(:new).with(setting_name: 'SettingName', provider: 'greenlight').and_call_original expect(SettingGetter).to receive(:new).with(setting_name: %w[Uno Dos Tres], provider: 'greenlight').and_call_original
expect(SettingGetter).to receive(:new).with(setting_name: 'SettingName2', provider: 'greenlight').and_call_original allow_any_instance_of(SettingGetter).to receive(:call).and_return({ 'Uno' => 1, 'Dos' => 2, 'Tres' => 3 })
allow_any_instance_of(SettingGetter).to receive(:call).and_return('false')
get :index, params: { names: %w[SettingName SettingName2] } get :index, params: { names: %w[Uno Dos Tres] }
expect(response).to have_http_status(:ok) expect(response).to have_http_status(:ok)
expect(JSON.parse(response.body)['data']['SettingName']).to eq('false') expect(JSON.parse(response.body)['data']).to eq({ 'Uno' => 1, 'Dos' => 2, 'Tres' => 3 })
expect(JSON.parse(response.body)['data']['SettingName2']).to eq('false')
end end
it 'returns forbidden if trying to access a forbidden setting' do it 'returns forbidden if trying to access a forbidden setting' do
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment