forked from External/greenlight
commit
2af1f7242f
|
@ -13,6 +13,7 @@ tmp
|
|||
/db/**/*.sqlite3
|
||||
/db/**/*.sqlite3-journal
|
||||
/db/production
|
||||
/db/production-postgres
|
||||
public/assets
|
||||
public/b
|
||||
coverage/
|
||||
|
|
|
@ -19,6 +19,7 @@ vendor/bundle
|
|||
|
||||
# Ignore production paths.
|
||||
/db/production
|
||||
/db/production-postgres
|
||||
|
||||
# Ignore all logfiles and tempfiles.
|
||||
/log/*
|
||||
|
|
62
Dockerfile
62
Dockerfile
|
@ -1,34 +1,58 @@
|
|||
FROM ruby:2.5
|
||||
FROM ruby:2.5.1-alpine AS base
|
||||
|
||||
# Install app dependencies.
|
||||
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev curl
|
||||
|
||||
ADD https://dl.yarnpkg.com/debian/pubkey.gpg /tmp/yarn-pubkey.gpg
|
||||
|
||||
RUN apt-key add /tmp/yarn-pubkey.gpg && rm /tmp/yarn-pubkey.gpg && \
|
||||
echo 'deb http://dl.yarnpkg.com/debian/ stable main' > /etc/apt/sources.list.d/yarn.list && \
|
||||
curl -sL https://deb.nodesource.com/setup_10.x | bash - && \
|
||||
apt-get update && apt-get install -y nodejs yarn
|
||||
|
||||
# Set an environment variable for the install location.
|
||||
ENV RAILS_ROOT /usr/src/app
|
||||
# Set a variable for the install location.
|
||||
ARG RAILS_ROOT=/usr/src/app
|
||||
# Set Rails environment.
|
||||
ENV RAILS_ENV production
|
||||
ENV BUNDLE_APP_CONFIG="$RAILS_ROOT/.bundle"
|
||||
|
||||
# Make the directory and set as working.
|
||||
RUN mkdir -p $RAILS_ROOT
|
||||
WORKDIR $RAILS_ROOT
|
||||
|
||||
# Set Rails environment.
|
||||
ENV RAILS_ENV production
|
||||
ARG BUILD_PACKAGES="build-base curl-dev git"
|
||||
ARG DEV_PACKAGES="postgresql-dev sqlite-libs sqlite-dev yaml-dev zlib-dev nodejs yarn"
|
||||
ARG RUBY_PACKAGES="tzdata"
|
||||
|
||||
# Install app dependencies.
|
||||
RUN apk update \
|
||||
&& apk upgrade \
|
||||
&& apk add --update --no-cache $BUILD_PACKAGES $DEV_PACKAGES $RUBY_PACKAGES
|
||||
|
||||
COPY Gemfile* ./
|
||||
RUN bundle install --without development test --deployment --clean
|
||||
COPY Gemfile Gemfile.lock $RAILS_ROOT/
|
||||
|
||||
RUN bundle config --global frozen 1 \
|
||||
&& bundle install --deployment --without development:test:assets -j4 --path=vendor/bundle \
|
||||
&& rm -rf vendor/bundle/ruby/2.5.0/cache/*.gem \
|
||||
&& find vendor/bundle/ruby/2.5.0/gems/ -name "*.c" -delete \
|
||||
&& find vendor/bundle/ruby/2.5.0/gems/ -name "*.o" -delete
|
||||
|
||||
# Adding project files.
|
||||
COPY . .
|
||||
|
||||
# Precompile assets
|
||||
RUN SECRET_KEY_BASE="$(bundle exec rake secret)" bundle exec rake assets:clean
|
||||
RUN SECRET_KEY_BASE="$(bundle exec rake secret)" bundle exec rake assets:precompile
|
||||
# Remove folders not needed in resulting image
|
||||
RUN rm -rf tmp/cache spec
|
||||
|
||||
############### Build step done ###############
|
||||
|
||||
FROM ruby:2.5.1-alpine
|
||||
|
||||
# Set a variable for the install location.
|
||||
ARG RAILS_ROOT=/usr/src/app
|
||||
ARG PACKAGES="tzdata curl postgresql-client sqlite-libs yarn nodejs bash"
|
||||
|
||||
ENV RAILS_ENV=production
|
||||
ENV BUNDLE_APP_CONFIG="$RAILS_ROOT/.bundle"
|
||||
|
||||
WORKDIR $RAILS_ROOT
|
||||
|
||||
RUN apk update \
|
||||
&& apk upgrade \
|
||||
&& apk add --update --no-cache $PACKAGES
|
||||
|
||||
|
||||
COPY --from=base $RAILS_ROOT $RAILS_ROOT
|
||||
|
||||
# Expose port 80.
|
||||
EXPOSE 80
|
||||
|
|
5
Gemfile
5
Gemfile
|
@ -23,7 +23,7 @@ gem 'uglifier', '>= 1.3.0'
|
|||
gem 'coffee-rails', '~> 4.2'
|
||||
|
||||
# See https://github.com/rails/execjs#readme for more supported runtimes
|
||||
gem 'mini_racer', platforms: :ruby
|
||||
# gem 'mini_racer', platforms: :ruby
|
||||
|
||||
# Use jquery as the JavaScript library
|
||||
gem 'jquery-rails', '~> 4.3.3'
|
||||
|
@ -77,6 +77,7 @@ gem 'cancancan', '~> 2.0'
|
|||
group :production do
|
||||
# Use a postgres database in production.
|
||||
gem 'pg', '~> 0.18'
|
||||
gem 'sequel'
|
||||
|
||||
# For a better logging library in production
|
||||
gem "lograge"
|
||||
|
@ -121,7 +122,7 @@ end
|
|||
gem 'remote_syslog_logger'
|
||||
|
||||
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
||||
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
|
||||
gem 'tzinfo-data'
|
||||
|
||||
gem 'coveralls', require: false
|
||||
|
||||
|
|
|
@ -153,7 +153,6 @@ GEM
|
|||
railties (>= 3.2.16)
|
||||
json (2.2.0)
|
||||
jwt (2.2.1)
|
||||
libv8 (7.3.492.27.1)
|
||||
listen (3.0.8)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
|
@ -173,8 +172,6 @@ GEM
|
|||
mimemagic (0.3.3)
|
||||
mini_mime (1.0.2)
|
||||
mini_portile2 (2.4.0)
|
||||
mini_racer (0.2.6)
|
||||
libv8 (>= 6.9.411)
|
||||
minitest (5.11.3)
|
||||
msgpack (1.3.0)
|
||||
multi_json (1.13.1)
|
||||
|
@ -295,6 +292,7 @@ GEM
|
|||
sprockets (> 3.0)
|
||||
sprockets-rails
|
||||
tilt
|
||||
sequel (5.29.0)
|
||||
shoulda-matchers (3.1.3)
|
||||
activesupport (>= 4.0.0)
|
||||
simplecov (0.16.1)
|
||||
|
@ -326,6 +324,8 @@ GEM
|
|||
turbolinks-source (5.2.0)
|
||||
tzinfo (1.2.5)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo-data (1.2019.3)
|
||||
tzinfo (>= 1.0.0)
|
||||
uglifier (4.1.20)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
unicode-display_width (1.6.0)
|
||||
|
@ -369,7 +369,6 @@ DEPENDENCIES
|
|||
jquery-ui-rails
|
||||
listen (~> 3.0.5)
|
||||
lograge
|
||||
mini_racer
|
||||
net-ldap
|
||||
omniauth
|
||||
omniauth-bn-launcher!
|
||||
|
@ -389,6 +388,7 @@ DEPENDENCIES
|
|||
rspec-rails (~> 3.7)
|
||||
rubocop
|
||||
sassc-rails
|
||||
sequel
|
||||
shoulda-matchers (~> 3.1)
|
||||
spring
|
||||
spring-watcher-listen (~> 2.0.0)
|
||||
|
|
|
@ -41,6 +41,49 @@ $(document).on('turbolinks:load', function(){
|
|||
|
||||
updateTabParams(this.id)
|
||||
})
|
||||
|
||||
$('.selectpicker').selectpicker({
|
||||
liveSearchPlaceholder: getLocalizedString('javascript.search.start')
|
||||
});
|
||||
// Fixes turbolinks issue with bootstrap select
|
||||
$(window).trigger('load.bs.select.data-api');
|
||||
|
||||
// Display merge accounts modal with correct info
|
||||
$(".merge-user").click(function() {
|
||||
// Update the path of save button
|
||||
$("#merge-save-access").attr("data-path", $(this).data("path"))
|
||||
|
||||
let userInfo = $(this).data("info")
|
||||
|
||||
$("#merge-to").html("<span>" + userInfo.name + "</span>" + "<span class='text-muted d-block'>" + userInfo.email + "</span>" + "<span class='text-muted d-block'>" + userInfo.uid + "</span>")
|
||||
|
||||
})
|
||||
|
||||
$("#mergeUserModal").on("show.bs.modal", function() {
|
||||
$(".selectpicker").selectpicker('val','')
|
||||
})
|
||||
|
||||
$(".bootstrap-select").on("click", function() {
|
||||
$(".bs-searchbox").siblings().hide()
|
||||
})
|
||||
|
||||
$(".bs-searchbox input").on("input", function() {
|
||||
if ($(".bs-searchbox input").val() == '' || $(".bs-searchbox input").val().length < 3) {
|
||||
$(".bs-searchbox").siblings().hide()
|
||||
} else {
|
||||
$(".bs-searchbox").siblings().show()
|
||||
}
|
||||
})
|
||||
|
||||
// User selects an option from the Room Access dropdown
|
||||
$(".bootstrap-select").on("changed.bs.select", function(){
|
||||
// Get the uid of the selected user
|
||||
let user = $(".selectpicker").selectpicker('val')
|
||||
if (user != "") {
|
||||
userInfo = JSON.parse(user)
|
||||
$("#merge-from").html("<span>" + userInfo.name + "</span>" + "<span class='text-muted d-block'>" + userInfo.email + "</span>" + "<span id='from-uid' class='text-muted d-block'>" + userInfo.uid + "</span>")
|
||||
}
|
||||
})
|
||||
}
|
||||
else if(action == "site_settings"){
|
||||
loadColourSelectors()
|
||||
|
@ -79,6 +122,11 @@ function changeBrandingImage(path) {
|
|||
$.post(path, {value: url})
|
||||
}
|
||||
|
||||
function mergeUsers() {
|
||||
let userToMerge = $("#from-uid").text()
|
||||
$.post($("#merge-save-access").data("path"), {merge: userToMerge})
|
||||
}
|
||||
|
||||
// Filters by role
|
||||
function filterRole(role) {
|
||||
var search = new URL(location.href).searchParams.get('search')
|
||||
|
|
|
@ -34,4 +34,5 @@
|
|||
//= require jquery-ui/widget
|
||||
//= require jquery-ui/widgets/sortable
|
||||
//= require pickr.min.js
|
||||
//= require bootstrap-select.min.js
|
||||
//= require_tree .
|
||||
|
|
|
@ -49,7 +49,16 @@ $(document).on('turbolinks:load', function(){
|
|||
$("#create-room-block").click(function(){
|
||||
showCreateRoom(this)
|
||||
})
|
||||
}
|
||||
|
||||
// Autofocus on the Room Name label when creating a room only
|
||||
$('#createRoomModal').on('shown.bs.modal', function (){
|
||||
if ($(".create-only").css("display") == "block"){
|
||||
$('#create-room-name').focus()
|
||||
}
|
||||
})
|
||||
|
||||
if (controller == "rooms" && action == "show" || controller == "admins" && action == "server_rooms"){
|
||||
// Display and update all fields related to creating a room in the createRoomModal
|
||||
$(".update-room").click(function(){
|
||||
showUpdateRoom(this)
|
||||
|
@ -58,6 +67,69 @@ $(document).on('turbolinks:load', function(){
|
|||
$(".delete-room").click(function() {
|
||||
showDeleteRoom(this)
|
||||
})
|
||||
|
||||
$('.selectpicker').selectpicker({
|
||||
liveSearchPlaceholder: getLocalizedString('javascript.search.start')
|
||||
});
|
||||
// Fixes turbolinks issue with bootstrap select
|
||||
$(window).trigger('load.bs.select.data-api');
|
||||
|
||||
$(".share-room").click(function() {
|
||||
// Update the path of save button
|
||||
$("#save-access").attr("data-path", $(this).data("path"))
|
||||
|
||||
// Get list of users shared with and display them
|
||||
displaySharedUsers($(this).data("users-path"))
|
||||
})
|
||||
|
||||
$("#shareRoomModal").on("show.bs.modal", function() {
|
||||
$(".selectpicker").selectpicker('val','')
|
||||
})
|
||||
|
||||
$(".bootstrap-select").on("click", function() {
|
||||
$(".bs-searchbox").siblings().hide()
|
||||
})
|
||||
|
||||
$(".bs-searchbox input").on("input", function() {
|
||||
if ($(".bs-searchbox input").val() == '' || $(".bs-searchbox input").val().length < 3) {
|
||||
$(".bs-searchbox").siblings().hide()
|
||||
} else {
|
||||
$(".bs-searchbox").siblings().show()
|
||||
}
|
||||
})
|
||||
|
||||
$(".remove-share-room").click(function() {
|
||||
$("#remove-shared-confirm").parent().attr("action", $(this).data("path"))
|
||||
})
|
||||
|
||||
// User selects an option from the Room Access dropdown
|
||||
$(".bootstrap-select").on("changed.bs.select", function(){
|
||||
// Get the uid of the selected user
|
||||
let uid = $(".selectpicker").selectpicker('val')
|
||||
|
||||
// If the value was changed to blank, ignore it
|
||||
if (uid == "") return
|
||||
|
||||
let currentListItems = $("#user-list li").toArray().map(user => $(user).data("uid"))
|
||||
|
||||
// Check to make sure that the user is not already there
|
||||
if (!currentListItems.includes(uid)) {
|
||||
// Create the faded list item and display it
|
||||
let option = $("option[value='" + uid + "']")
|
||||
|
||||
let listItem = document.createElement("li")
|
||||
listItem.setAttribute('class', 'list-group-item text-left not-saved add-access');
|
||||
listItem.setAttribute("data-uid", uid)
|
||||
|
||||
let spanItem = "<span class='avatar float-left mr-2'>" + option.text().charAt(0) + "</span> <span class='shared-user'>" +
|
||||
option.text() + " <span class='text-muted'>" + option.data("subtext") + "</span></span>" +
|
||||
"<span class='text-primary float-right shared-user cursor-pointer' onclick='removeSharedUser(this)'><i class='fas fa-times'></i></span>"
|
||||
|
||||
listItem.innerHTML = spanItem
|
||||
|
||||
$("#user-list").append(listItem)
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -88,9 +160,10 @@ function showCreateRoom(target) {
|
|||
|
||||
function showUpdateRoom(target) {
|
||||
var modal = $(target)
|
||||
var room_block_uid = modal.closest("#room-block").data("room-uid")
|
||||
$("#create-room-name").val(modal.closest("tbody").find("#room-name h4").text())
|
||||
$("#createRoomModal form").attr("action", room_block_uid + "/update_settings")
|
||||
var update_path = modal.closest("#room-block").data("path")
|
||||
var settings_path = modal.data("settings-path")
|
||||
$("#create-room-name").val(modal.closest("#room-block").find("#room-name-text").text())
|
||||
$("#createRoomModal form").attr("action", update_path)
|
||||
|
||||
//show all elements & their children with a update-only class
|
||||
$(".update-only").each(function() {
|
||||
|
@ -104,7 +177,7 @@ function showUpdateRoom(target) {
|
|||
if($(this).children().length > 0) { $(this).children().attr('style',"display:none !important") }
|
||||
})
|
||||
|
||||
updateCurrentSettings(modal.closest("#room-block").data("room-settings"))
|
||||
updateCurrentSettings(settings_path)
|
||||
|
||||
var accessCode = modal.closest("#room-block").data("room-access-code")
|
||||
|
||||
|
@ -123,12 +196,15 @@ function showDeleteRoom(target) {
|
|||
}
|
||||
|
||||
//Update the createRoomModal to show the correct current settings
|
||||
function updateCurrentSettings(settings){
|
||||
//set checkbox
|
||||
$("#room_mute_on_join").prop("checked", settings.muteOnStart)
|
||||
$("#room_require_moderator_approval").prop("checked", settings.requireModeratorApproval)
|
||||
$("#room_anyone_can_start").prop("checked", settings.anyoneCanStart)
|
||||
$("#room_all_join_moderator").prop("checked", settings.joinModerator)
|
||||
function updateCurrentSettings(settings_path){
|
||||
// Get current room settings and set checkbox
|
||||
$.get(settings_path, function(room_settings) {
|
||||
var settings = JSON.parse(room_settings)
|
||||
$("#room_mute_on_join").prop("checked", settings.muteOnStart)
|
||||
$("#room_require_moderator_approval").prop("checked", settings.requireModeratorApproval)
|
||||
$("#room_anyone_can_start").prop("checked", settings.anyoneCanStart)
|
||||
$("#room_all_join_moderator").prop("checked", settings.joinModerator)
|
||||
})
|
||||
}
|
||||
|
||||
function generateAccessCode(){
|
||||
|
@ -148,3 +224,44 @@ function ResetAccessCode(){
|
|||
$("#create-room-access-code").text(getLocalizedString("modal.create_room.access_code_placeholder"))
|
||||
$("#room_access_code").val(null)
|
||||
}
|
||||
|
||||
function saveAccessChanges() {
|
||||
let listItemsToAdd = $("#user-list li:not(.remove-shared)").toArray().map(user => $(user).data("uid"))
|
||||
|
||||
$.post($("#save-access").data("path"), {add: listItemsToAdd})
|
||||
}
|
||||
|
||||
// Get list of users shared with and display them
|
||||
function displaySharedUsers(path) {
|
||||
$.get(path, function(users) {
|
||||
// Create list element and add to user list
|
||||
var user_list_html = ""
|
||||
|
||||
users.forEach(function(user) {
|
||||
user_list_html += "<li class='list-group-item text-left' data-uid='" + user.uid + "'>"
|
||||
|
||||
if (user.image) {
|
||||
user_list_html += "<img id='user-image' class='avatar float-left mr-2' src='" + user.image + "'></img>"
|
||||
} else {
|
||||
user_list_html += "<span class='avatar float-left mr-2'>" + user.name.charAt(0) + "</span>"
|
||||
}
|
||||
user_list_html += "<span class='shared-user'>" + user.name + "<span class='text-muted ml-1'>" + user.uid + "</span></span>"
|
||||
user_list_html += "<span class='text-primary float-right shared-user cursor-pointer' onclick='removeSharedUser(this)'><i class='fas fa-times'></i></span>"
|
||||
user_list_html += "</li>"
|
||||
})
|
||||
|
||||
$("#user-list").html(user_list_html)
|
||||
});
|
||||
}
|
||||
|
||||
// Removes the user from the list of shared users
|
||||
function removeSharedUser(target) {
|
||||
let parentLI = target.closest("li")
|
||||
|
||||
if (parentLI.classList.contains("not-saved")) {
|
||||
parentLI.parentNode.removeChild(parentLI)
|
||||
} else {
|
||||
parentLI.removeChild(target)
|
||||
parentLI.classList.add("remove-shared")
|
||||
}
|
||||
}
|
|
@ -23,7 +23,8 @@ $(document).on('turbolinks:load', function(){
|
|||
(controller == "rooms" && action == "update") ||
|
||||
(controller == "rooms" && action == "join") ||
|
||||
(controller == "users" && action == "recordings") ||
|
||||
(controller == "admins" && action == "server_recordings")) {
|
||||
(controller == "admins" && action == "server_recordings") ||
|
||||
(controller == "admins" && action == "server_rooms")) {
|
||||
// Submit search if the user hits enter
|
||||
$("#search-input").keypress(function(key) {
|
||||
if (key.which == 13) {
|
||||
|
|
|
@ -52,15 +52,12 @@ $(document).on('turbolinks:load', function(){
|
|||
// Modify the ui for the tables
|
||||
var configure_order = function(header_elem){
|
||||
if(header_elem.data('order') === 'asc'){ // asc
|
||||
header_elem.text(header_elem.data("header") + " ↓");
|
||||
header_elem.data('order', 'desc');
|
||||
}
|
||||
else if(header_elem.data('order') === 'desc'){ // desc
|
||||
header_elem.text(header_elem.data("header"));
|
||||
header_elem.data('order', 'none');
|
||||
}
|
||||
else{ // none
|
||||
header_elem.text(header_elem.data("header") + " ↑");
|
||||
header_elem.data('order', 'asc');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,4 +88,12 @@
|
|||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
#merge-account-arrow {
|
||||
position: absolute;
|
||||
top: 47%;
|
||||
right: 47%;
|
||||
z-index: 999;
|
||||
background: white;
|
||||
}
|
|
@ -36,14 +36,16 @@
|
|||
@import "tabler-custom";
|
||||
@import "font-awesome-sprockets";
|
||||
@import "font-awesome";
|
||||
@import "monolith.min.scss";
|
||||
@import "bootstrap-select.min";
|
||||
|
||||
@import "utilities/variables";
|
||||
@import "admins";
|
||||
@import "main";
|
||||
@import "rooms";
|
||||
@import "sessions";
|
||||
@import "monolith.min.scss";
|
||||
@import "utilities/fonts";
|
||||
@import "users";
|
||||
|
||||
* {
|
||||
outline: none !important;
|
||||
|
|
|
@ -83,3 +83,20 @@
|
|||
margin-top: -6rem;
|
||||
font-size: 5rem;
|
||||
}
|
||||
|
||||
.bootstrap-select .dropdown-menu li.active small.text-muted{
|
||||
color: #9aa0ac !important
|
||||
}
|
||||
|
||||
.not-saved {
|
||||
color: grey;
|
||||
background: rgba(0, 40, 100, 0.12);
|
||||
}
|
||||
|
||||
.dropdown-menu.show {
|
||||
min-height: 0px !important;
|
||||
}
|
||||
|
||||
.remove-shared {
|
||||
text-decoration: line-through;
|
||||
}
|
|
@ -21,4 +21,12 @@
|
|||
|
||||
.user-role-tag{
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.shared-user {
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.bootstrap-select {
|
||||
border: 1px solid rgba(0, 40, 100, 0.12);
|
||||
}
|
|
@ -18,11 +18,6 @@
|
|||
|
||||
class WaitingChannel < ApplicationCable::Channel
|
||||
def subscribed
|
||||
Rails.logger.info "subscribed [#{params[:useruid]}:#{params[:roomuid]}]"
|
||||
stream_from "#{params[:roomuid]}_waiting_channel"
|
||||
end
|
||||
|
||||
def unsubscribed
|
||||
Rails.logger.info "unsubscribed [#{params[:useruid]}:#{params[:roomuid]}]"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -51,6 +51,7 @@ class AccountActivationsController < ApplicationController
|
|||
flash[:alert] = I18n.t("verify.already_verified")
|
||||
else
|
||||
# Resend
|
||||
@user.create_activation_token
|
||||
send_activation_email(@user)
|
||||
end
|
||||
|
||||
|
@ -60,14 +61,10 @@ class AccountActivationsController < ApplicationController
|
|||
private
|
||||
|
||||
def find_user
|
||||
@user = User.find_by!(email: params[:email], provider: @user_domain)
|
||||
@user = User.find_by!(activation_digest: User.digest(params[:token]), provider: @user_domain)
|
||||
end
|
||||
|
||||
def ensure_unauthenticated
|
||||
redirect_to current_user.main_room if current_user
|
||||
end
|
||||
|
||||
def email_params
|
||||
params.require(:email).permit(:email, :token)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -22,8 +22,9 @@ class AdminsController < ApplicationController
|
|||
include Emailer
|
||||
include Recorder
|
||||
include Rolify
|
||||
include Populator
|
||||
|
||||
manage_users = [:edit_user, :promote, :demote, :ban_user, :unban_user, :approve, :reset]
|
||||
manage_users = [:edit_user, :promote, :demote, :ban_user, :unban_user, :approve, :reset, :merge_user]
|
||||
manage_deleted_users = [:undelete]
|
||||
authorize_resource class: false
|
||||
before_action :find_user, only: manage_users
|
||||
|
@ -40,7 +41,9 @@ class AdminsController < ApplicationController
|
|||
@role = params[:role] ? Role.find_by(name: params[:role], provider: @user_domain) : nil
|
||||
@tab = params[:tab] || "active"
|
||||
|
||||
@pagy, @users = pagy(user_list)
|
||||
@user_list = merge_user_list
|
||||
|
||||
@pagy, @users = pagy(manage_users_list)
|
||||
end
|
||||
|
||||
# GET /admins/site_settings
|
||||
|
@ -49,11 +52,7 @@ class AdminsController < ApplicationController
|
|||
|
||||
# GET /admins/server_recordings
|
||||
def server_recordings
|
||||
server_rooms = if Rails.configuration.loadbalanced_configuration
|
||||
Room.includes(:owner).where(users: { provider: @user_domain }).pluck(:bbb_id)
|
||||
else
|
||||
Room.pluck(:bbb_id)
|
||||
end
|
||||
server_rooms = rooms_list_for_recordings
|
||||
|
||||
@search, @order_column, @order_direction, recs =
|
||||
all_recordings(server_rooms, params.permit(:search, :column, :direction), true, true)
|
||||
|
@ -61,24 +60,40 @@ class AdminsController < ApplicationController
|
|||
@pagy, @recordings = pagy_array(recs)
|
||||
end
|
||||
|
||||
# GET /admins/rooms
|
||||
def server_rooms
|
||||
@search = params[:search] || ""
|
||||
@order_column = params[:column] && params[:direction] != "none" ? params[:column] : "created_at"
|
||||
@order_direction = params[:direction] && params[:direction] != "none" ? params[:direction] : "DESC"
|
||||
|
||||
@running_room_bbb_ids = all_running_meetings[:meetings].pluck(:meetingID)
|
||||
|
||||
@user_list = shared_user_list if shared_access_allowed
|
||||
|
||||
@pagy, @rooms = pagy_array(server_rooms_list)
|
||||
end
|
||||
|
||||
# MANAGE USERS
|
||||
|
||||
# GET /admins/edit/:user_uid
|
||||
def edit_user
|
||||
session[:prev_url] = request.referer if request.referer.present?
|
||||
end
|
||||
|
||||
# POST /admins/ban/:user_uid
|
||||
def ban_user
|
||||
@user.roles = []
|
||||
@user.add_role :denied
|
||||
redirect_to admins_path, flash: { success: I18n.t("administrator.flash.banned") }
|
||||
|
||||
redirect_back fallback_location: admins_path, flash: { success: I18n.t("administrator.flash.banned") }
|
||||
end
|
||||
|
||||
# POST /admins/unban/:user_uid
|
||||
def unban_user
|
||||
@user.remove_role :denied
|
||||
@user.add_role :user
|
||||
redirect_to admins_path, flash: { success: I18n.t("administrator.flash.unbanned") }
|
||||
|
||||
redirect_back fallback_location: admins_path, flash: { success: I18n.t("administrator.flash.unbanned") }
|
||||
end
|
||||
|
||||
# POST /admins/approve/:user_uid
|
||||
|
@ -87,7 +102,7 @@ class AdminsController < ApplicationController
|
|||
|
||||
send_user_approved_email(@user)
|
||||
|
||||
redirect_to admins_path, flash: { success: I18n.t("administrator.flash.approved") }
|
||||
redirect_back fallback_location: admins_path, flash: { success: I18n.t("administrator.flash.approved") }
|
||||
end
|
||||
|
||||
# POST /admins/approve/:user_uid
|
||||
|
@ -96,7 +111,7 @@ class AdminsController < ApplicationController
|
|||
@user.undelete!
|
||||
@user.rooms.deleted.each(&:undelete!)
|
||||
|
||||
redirect_to admins_path, flash: { success: I18n.t("administrator.flash.restored") }
|
||||
redirect_back fallback_location: admins_path, flash: { success: I18n.t("administrator.flash.restored") }
|
||||
end
|
||||
|
||||
# POST /admins/invite
|
||||
|
@ -118,8 +133,54 @@ class AdminsController < ApplicationController
|
|||
|
||||
send_password_reset_email(@user)
|
||||
|
||||
redirect_to admins_path, flash: { success: I18n.t("administrator.flash.reset_password") }
|
||||
if session[:prev_url].present?
|
||||
redirect_path = session[:prev_url]
|
||||
session.delete(:prev_url)
|
||||
else
|
||||
redirect_path = admins_path
|
||||
end
|
||||
|
||||
redirect_to redirect_path, flash: { success: I18n.t("administrator.flash.reset_password") }
|
||||
end
|
||||
|
||||
# POST /admins/merge/:user_uid
|
||||
def merge_user
|
||||
begin
|
||||
# Get uid of user that will be merged into the other account
|
||||
uid_to_merge = params[:merge]
|
||||
logger.info "#{current_user.uid} is attempting to merge #{uid_to_merge} into #{@user.uid}"
|
||||
|
||||
# Check to make sure the 2 users are unique
|
||||
raise "Can not merge the user into themself" if uid_to_merge == @user.uid
|
||||
|
||||
# Find user to merge
|
||||
user_to_merge = User.find_by(uid: uid_to_merge)
|
||||
|
||||
# Move over user's rooms
|
||||
user_to_merge.rooms.each do |room|
|
||||
room.owner = @user
|
||||
|
||||
room.name = "(#{I18n.t('merged')}) #{room.name}"
|
||||
|
||||
room.save!
|
||||
end
|
||||
|
||||
# Reload user to update merge rooms
|
||||
user_to_merge.reload
|
||||
|
||||
# Delete merged user
|
||||
user_to_merge.destroy(true)
|
||||
rescue => e
|
||||
logger.info "Failed to merge #{uid_to_merge} into #{@user.uid}: #{e}"
|
||||
flash[:alert] = I18n.t("administrator.flash.merge_fail")
|
||||
else
|
||||
logger.info "#{current_user.uid} successfully merged #{uid_to_merge} into #{@user.uid}"
|
||||
flash[:success] = I18n.t("administrator.flash.merge_success")
|
||||
end
|
||||
|
||||
redirect_back fallback_location: admins_path
|
||||
end
|
||||
|
||||
# SITE SETTINGS
|
||||
|
||||
# POST /admins/update_settings
|
||||
|
@ -158,6 +219,13 @@ class AdminsController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
# POST /admins/clear_auth
|
||||
def clear_auth
|
||||
User.include_deleted.where(provider: @user_domain).update_all(social_uid: nil)
|
||||
|
||||
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
|
||||
end
|
||||
|
||||
# POST /admins/clear_cache
|
||||
def clear_cache
|
||||
Rails.cache.delete("#{@user_domain}/getUser")
|
||||
|
@ -166,6 +234,13 @@ class AdminsController < ApplicationController
|
|||
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
|
||||
end
|
||||
|
||||
# POST /admins/log_level
|
||||
def log_level
|
||||
Rails.logger.level = params[:value].to_i
|
||||
|
||||
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
|
||||
end
|
||||
|
||||
# ROLES
|
||||
|
||||
# GET /admins/roles
|
||||
|
@ -224,11 +299,11 @@ class AdminsController < ApplicationController
|
|||
private
|
||||
|
||||
def find_user
|
||||
@user = User.where(uid: params[:user_uid]).includes(:roles).first
|
||||
@user = User.find_by(uid: params[:user_uid])
|
||||
end
|
||||
|
||||
def find_deleted_user
|
||||
@user = User.deleted.where(uid: params[:user_uid]).includes(:roles).first
|
||||
@user = User.deleted.find_by(uid: params[:user_uid])
|
||||
end
|
||||
|
||||
# Verifies that admin is an administrator of the user in the action
|
||||
|
@ -237,37 +312,6 @@ class AdminsController < ApplicationController
|
|||
flash: { alert: I18n.t("administrator.flash.unauthorized") } unless current_user.admin_of?(@user)
|
||||
end
|
||||
|
||||
# Gets the list of users based on your configuration
|
||||
def user_list
|
||||
current_role = @role
|
||||
|
||||
initial_user = case @tab
|
||||
when "active"
|
||||
User.without_role(:pending).without_role(:denied)
|
||||
when "deleted"
|
||||
User.deleted
|
||||
else
|
||||
User
|
||||
end
|
||||
|
||||
current_role = Role.find_by(name: @tab, provider: @user_domain) if @tab == "pending" || @tab == "denied"
|
||||
|
||||
initial_list = if current_user.has_role? :super_admin
|
||||
initial_user.where.not(id: current_user.id)
|
||||
else
|
||||
initial_user.without_role(:super_admin).where.not(id: current_user.id)
|
||||
end
|
||||
|
||||
if Rails.configuration.loadbalanced_configuration
|
||||
initial_list.where(provider: @user_domain)
|
||||
.admins_search(@search, current_role)
|
||||
.admins_order(@order_column, @order_direction)
|
||||
else
|
||||
initial_list.admins_search(@search, current_role)
|
||||
.admins_order(@order_column, @order_direction)
|
||||
end
|
||||
end
|
||||
|
||||
# Creates the invite if it doesn't exist, or updates the updated_at time if it does
|
||||
def create_or_update_invite(email)
|
||||
invite = Invitation.find_by(email: email, provider: @user_domain)
|
||||
|
|
|
@ -29,7 +29,7 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
# Retrieves the current user.
|
||||
def current_user
|
||||
@current_user ||= User.where(id: session[:user_id]).includes(:roles).first
|
||||
@current_user ||= User.includes(:roles, :main_room).find_by(id: session[:user_id])
|
||||
|
||||
if Rails.configuration.loadbalanced_configuration
|
||||
if @current_user && !@current_user.has_role?(:super_admin) &&
|
||||
|
@ -67,7 +67,7 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
# Sets the settinfs variable
|
||||
def set_user_settings
|
||||
@settings = Setting.find_or_create_by(provider: @user_domain)
|
||||
@settings = Setting.includes(:features).find_or_create_by(provider: @user_domain)
|
||||
end
|
||||
|
||||
# Redirects the user to a Maintenance page if turned on
|
||||
|
@ -172,6 +172,12 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
helper_method :configured_providers
|
||||
|
||||
# Indicates whether users are allowed to share rooms
|
||||
def shared_access_allowed
|
||||
@settings.get_value("Shared Access") == "true"
|
||||
end
|
||||
helper_method :shared_access_allowed
|
||||
|
||||
# Parses the url for the user domain
|
||||
def parse_user_domain(hostname)
|
||||
return hostname.split('.').first if Rails.configuration.url_host.empty?
|
||||
|
@ -194,7 +200,23 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
# Manually deal with 401 errors
|
||||
rescue_from CanCan::AccessDenied do |_exception|
|
||||
render "errors/greenlight_error"
|
||||
if current_user
|
||||
render "errors/greenlight_error"
|
||||
else
|
||||
# Store the current url as a cookie to redirect to after sigining in
|
||||
cookies[:return_to] = request.url
|
||||
|
||||
# Get the correct signin path
|
||||
path = if allow_greenlight_accounts?
|
||||
signin_path
|
||||
elsif Rails.configuration.loadbalanced_configuration
|
||||
omniauth_login_url(:bn_launcher)
|
||||
else
|
||||
signin_path
|
||||
end
|
||||
|
||||
redirect_to path
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -214,6 +236,7 @@ class ApplicationController < ActionController::Base
|
|||
logger.error "Error in retrieve provider info: #{e}"
|
||||
# Use the default site settings
|
||||
@user_domain = "greenlight"
|
||||
@settings = Setting.find_or_create_by(provider: @user_domain)
|
||||
|
||||
if e.message.eql? "No user with that id exists"
|
||||
render "errors/greenlight_error", locals: { message: I18n.t("errors.not_found.user_not_found.message"),
|
||||
|
|
|
@ -68,6 +68,18 @@ module Authenticator
|
|||
session.delete(:user_id) if current_user
|
||||
end
|
||||
|
||||
# Check if the user is using local accounts
|
||||
def auth_changed_to_local?(user)
|
||||
Rails.configuration.loadbalanced_configuration && user.social_uid.present? && allow_greenlight_accounts?
|
||||
end
|
||||
|
||||
# Check if the user exists under the same email with no social uid and that social accounts are allowed
|
||||
def auth_changed_to_social?(email)
|
||||
Rails.configuration.loadbalanced_configuration &&
|
||||
User.exists?(email: email, provider: @user_domain, social_uid: nil) &&
|
||||
!allow_greenlight_accounts?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Migrates all of the twitter users rooms to the new account
|
||||
|
|
|
@ -29,6 +29,11 @@ module BbbServer
|
|||
bbb_server.is_meeting_running?(bbb_id)
|
||||
end
|
||||
|
||||
# Returns a list of all running meetings
|
||||
def all_running_meetings
|
||||
bbb_server.get_meetings
|
||||
end
|
||||
|
||||
def get_recordings(meeting_id)
|
||||
bbb_server.get_recordings(meetingID: meeting_id)
|
||||
end
|
||||
|
|
|
@ -101,7 +101,8 @@ module Emailer
|
|||
return unless Rails.configuration.enable_email_verification
|
||||
|
||||
admin_emails = admin_emails()
|
||||
UserMailer.approval_user_signup(user, admins_url, admin_emails, @settings).deliver_now unless admin_emails.empty?
|
||||
UserMailer.approval_user_signup(user, admins_url(tab: "pending"),
|
||||
admin_emails, @settings).deliver_now unless admin_emails.empty?
|
||||
rescue => e
|
||||
logger.error "Support: Error in email delivery: #{e}"
|
||||
flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
|
||||
|
@ -124,7 +125,7 @@ module Emailer
|
|||
|
||||
# Returns the link the user needs to click to verify their account
|
||||
def user_verification_link(user)
|
||||
edit_account_activation_url(token: user.activation_token, email: user.email)
|
||||
edit_account_activation_url(token: user.activation_token)
|
||||
end
|
||||
|
||||
def admin_emails
|
||||
|
@ -139,7 +140,7 @@ module Emailer
|
|||
end
|
||||
|
||||
def reset_link(user)
|
||||
edit_password_reset_url(user.reset_token, email: user.email)
|
||||
edit_password_reset_url(user.reset_token)
|
||||
end
|
||||
|
||||
def invitation_link(token)
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
# 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 Populator
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
# Returns a list of users that are in the same context of the current user
|
||||
def manage_users_list
|
||||
current_role = @role
|
||||
|
||||
initial_user = case @tab
|
||||
when "active"
|
||||
User.includes(:roles).without_role(:pending).without_role(:denied)
|
||||
when "deleted"
|
||||
User.includes(:roles).deleted
|
||||
else
|
||||
User.includes(:roles)
|
||||
end
|
||||
|
||||
current_role = Role.find_by(name: @tab, provider: @user_domain) if @tab == "pending" || @tab == "denied"
|
||||
|
||||
initial_list = if current_user.has_role? :super_admin
|
||||
initial_user.where.not(id: current_user.id)
|
||||
else
|
||||
initial_user.without_role(:super_admin).where.not(id: current_user.id)
|
||||
end
|
||||
|
||||
if Rails.configuration.loadbalanced_configuration
|
||||
initial_list.where(provider: @user_domain)
|
||||
.admins_search(@search, current_role)
|
||||
.admins_order(@order_column, @order_direction)
|
||||
else
|
||||
initial_list.admins_search(@search, current_role)
|
||||
.admins_order(@order_column, @order_direction)
|
||||
end
|
||||
end
|
||||
|
||||
# Returns a list of rooms that are in the same context of the current user
|
||||
def server_rooms_list
|
||||
if Rails.configuration.loadbalanced_configuration
|
||||
Room.includes(:owner).where(users: { provider: @user_domain })
|
||||
.admins_search(@search)
|
||||
.admins_order(@order_column, @order_direction)
|
||||
else
|
||||
Room.includes(:owner).all.admins_search(@search).admins_order(@order_column, @order_direction)
|
||||
end
|
||||
end
|
||||
|
||||
# Returns list of rooms needed to get the recordings on the server
|
||||
def rooms_list_for_recordings
|
||||
if Rails.configuration.loadbalanced_configuration
|
||||
Room.includes(:owner).where(users: { provider: @user_domain }).pluck(:bbb_id)
|
||||
else
|
||||
Room.pluck(:bbb_id)
|
||||
end
|
||||
end
|
||||
|
||||
# Returns a list of users that are in the same context of the current user
|
||||
def shared_user_list
|
||||
roles_can_appear = []
|
||||
Role.where(provider: @user_domain).each do |role|
|
||||
roles_can_appear << role.name if role.get_permission("can_appear_in_share_list") && role.priority >= 0
|
||||
end
|
||||
|
||||
initial_list = User.where.not(uid: current_user.uid)
|
||||
.without_role(:pending)
|
||||
.without_role(:denied)
|
||||
.with_highest_priority_role(roles_can_appear)
|
||||
|
||||
return initial_list unless Rails.configuration.loadbalanced_configuration
|
||||
initial_list.where(provider: @user_domain)
|
||||
end
|
||||
|
||||
# Returns a list of users that can merged into another user
|
||||
def merge_user_list
|
||||
initial_list = User.where.not(uid: current_user.uid).without_role(:super_admin)
|
||||
|
||||
return initial_list unless Rails.configuration.loadbalanced_configuration
|
||||
initial_list.where(provider: @user_domain)
|
||||
end
|
||||
end
|
|
@ -119,17 +119,32 @@ module Rolify
|
|||
return false if role.priority <= current_user_role.priority || role.provider != @user_domain
|
||||
end
|
||||
|
||||
# Update the roles priority including the user role
|
||||
top_priority = 0
|
||||
# Get the priority of the current user's role and start with 1 higher
|
||||
new_priority = [current_user_role.priority, 0].max + 1
|
||||
|
||||
role_to_update.each_with_index do |id, index|
|
||||
new_priority = index + [current_user_role.priority, 0].max + 1
|
||||
top_priority = new_priority
|
||||
Role.where(id: id).update_all(priority: new_priority)
|
||||
begin
|
||||
# Save the old priorities incase something fails
|
||||
old_priority = Role.where(id: role_to_update).select(:id, :priority).index_by(&:id)
|
||||
|
||||
# Set all the priorities to nil to avoid unique column issues
|
||||
Role.where(id: role_to_update).update_all(priority: nil)
|
||||
|
||||
# Starting at the starting priority, increase by 1 every time
|
||||
role_to_update.each_with_index do |id, index|
|
||||
Role.find(id).update_attribute(:priority, new_priority + index)
|
||||
end
|
||||
|
||||
true
|
||||
rescue => e
|
||||
# Reset to old prorities
|
||||
role_to_update.each_with_index do |id, _index|
|
||||
Role.find(id).update_attribute(:priority, old_priority[id.to_i].priority)
|
||||
end
|
||||
|
||||
logger.error "#{current_user} failed to update role priorities: #{e}"
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
user_role.priority = top_priority + 1
|
||||
user_role.save!
|
||||
end
|
||||
|
||||
# Update Permissions
|
||||
|
@ -141,7 +156,8 @@ module Rolify
|
|||
|
||||
role_params = params.require(:role).permit(:name)
|
||||
permission_params = params.require(:role).permit(:can_create_rooms, :send_promoted_email,
|
||||
:send_demoted_email, :can_edit_site_settings, :can_edit_roles, :can_manage_users, :colour)
|
||||
:send_demoted_email, :can_edit_site_settings, :can_edit_roles, :can_manage_users,
|
||||
:can_manage_rooms_recordings, :can_appear_in_share_list, :colour)
|
||||
|
||||
permission_params.transform_values! do |v|
|
||||
if v == "0"
|
||||
|
|
|
@ -56,6 +56,8 @@ class PasswordResetsController < ApplicationController
|
|||
# Password does not match password confirmation
|
||||
flash.now[:alert] = I18n.t("password_different_notice")
|
||||
elsif @user.update_attributes(user_params)
|
||||
# Clear the user's social uid if they are switching from a social to a local account
|
||||
@user.update_attribute(:social_uid, nil) if @user.social_uid.present?
|
||||
# Successfully reset password
|
||||
return redirect_to root_path, flash: { success: I18n.t("password_reset_success") }
|
||||
end
|
||||
|
@ -66,7 +68,7 @@ class PasswordResetsController < ApplicationController
|
|||
private
|
||||
|
||||
def find_user
|
||||
@user = User.find_by(email: params[:email])
|
||||
@user = User.find_by(reset_digest: User.digest(params[:id]), provider: @user_domain)
|
||||
end
|
||||
|
||||
def user_params
|
||||
|
|
|
@ -20,14 +20,18 @@ class RoomsController < ApplicationController
|
|||
include Pagy::Backend
|
||||
include Recorder
|
||||
include Joiner
|
||||
include Populator
|
||||
|
||||
before_action :validate_accepted_terms, unless: -> { !Rails.configuration.terms }
|
||||
before_action :validate_verified_email, except: [:show, :join],
|
||||
unless: -> { !Rails.configuration.enable_email_verification }
|
||||
before_action :find_room, except: [:create, :join_specific_room]
|
||||
before_action :verify_room_ownership, only: [:destroy, :start, :update_settings]
|
||||
before_action :verify_room_ownership_or_admin_or_shared, only: [:start, :shared_access]
|
||||
before_action :verify_room_ownership_or_admin, only: [:update_settings, :destroy]
|
||||
before_action :verify_room_ownership_or_shared, only: [:remove_shared_access]
|
||||
before_action :verify_room_owner_verified, only: [:show, :join],
|
||||
unless: -> { !Rails.configuration.enable_email_verification }
|
||||
before_action :verify_room_owner_valid, only: [:show, :join]
|
||||
before_action :verify_user_not_admin, only: [:show]
|
||||
|
||||
# POST /
|
||||
|
@ -60,14 +64,17 @@ class RoomsController < ApplicationController
|
|||
def show
|
||||
@anyone_can_start = JSON.parse(@room[:room_settings])["anyoneCanStart"]
|
||||
@room_running = room_running?(@room.bbb_id)
|
||||
@shared_room = room_shared_with_user
|
||||
|
||||
# If its the current user's room
|
||||
if current_user && @room.owned_by?(current_user)
|
||||
if current_user && (@room.owned_by?(current_user) || @shared_room)
|
||||
if current_user.highest_priority_role.get_permission("can_create_rooms")
|
||||
# User is allowed to have rooms
|
||||
@search, @order_column, @order_direction, recs =
|
||||
recordings(@room.bbb_id, params.permit(:search, :column, :direction), true)
|
||||
|
||||
@user_list = shared_user_list if shared_access_allowed
|
||||
|
||||
@pagy, @recordings = pagy_array(recs)
|
||||
else
|
||||
# Render view for users that cant create rooms
|
||||
|
@ -112,10 +119,21 @@ class RoomsController < ApplicationController
|
|||
|
||||
# DELETE /:room_uid
|
||||
def destroy
|
||||
# Don't delete the users home room.
|
||||
@room.destroy if @room.owned_by?(current_user) && @room != current_user.main_room
|
||||
begin
|
||||
# Don't delete the users home room.
|
||||
raise I18n.t("room.delete.home_room") if @room == @room.owner.main_room
|
||||
@room.destroy
|
||||
rescue => e
|
||||
flash[:alert] = I18n.t("room.delete.fail", error: e)
|
||||
else
|
||||
flash[:success] = I18n.t("room.delete.success")
|
||||
end
|
||||
|
||||
redirect_to current_user.main_room
|
||||
# Redirect to home room if the redirect_back location is the deleted room
|
||||
return redirect_to @current_user.main_room if request.referer == room_url(@room)
|
||||
|
||||
# Redirect to the location that the user deleted the room from
|
||||
redirect_back fallback_location: current_user.main_room
|
||||
end
|
||||
|
||||
# POST /room/join
|
||||
|
@ -162,7 +180,6 @@ class RoomsController < ApplicationController
|
|||
begin
|
||||
options = params[:room].nil? ? params : params[:room]
|
||||
raise "Room name can't be blank" if options[:name].blank?
|
||||
raise "Unauthorized Request" if !@room.owned_by?(current_user) || @room == current_user.main_room
|
||||
|
||||
# Update the rooms values
|
||||
room_settings_string = create_room_settings_string(options)
|
||||
|
@ -179,7 +196,64 @@ class RoomsController < ApplicationController
|
|||
flash[:alert] = I18n.t("room.update_settings_error")
|
||||
end
|
||||
|
||||
redirect_to room_path
|
||||
redirect_back fallback_location: room_path(@room)
|
||||
end
|
||||
|
||||
# POST /:room_uid/update_shared_access
|
||||
def shared_access
|
||||
begin
|
||||
current_list = @room.shared_users.pluck(:id)
|
||||
new_list = User.where(uid: params[:add]).pluck(:id)
|
||||
|
||||
# Get the list of users that used to be in the list but were removed
|
||||
users_to_remove = current_list - new_list
|
||||
# Get the list of users that are in the new list but not in the current list
|
||||
users_to_add = new_list - current_list
|
||||
|
||||
# Remove users that are removed
|
||||
SharedAccess.where(room_id: @room.id, user_id: users_to_remove).delete_all unless users_to_remove.empty?
|
||||
|
||||
# Add users that are added
|
||||
users_to_add.each do |id|
|
||||
SharedAccess.create(room_id: @room.id, user_id: id)
|
||||
end
|
||||
|
||||
flash[:success] = I18n.t("room.shared_access_success")
|
||||
rescue => e
|
||||
logger.error "Support: Error in updating room shared access: #{e}"
|
||||
flash[:alert] = I18n.t("room.shared_access_error")
|
||||
end
|
||||
|
||||
redirect_back fallback_location: room_path
|
||||
end
|
||||
|
||||
# POST /:room_uid/remove_shared_access
|
||||
def remove_shared_access
|
||||
begin
|
||||
SharedAccess.find_by!(room_id: @room.id, user_id: params[:user_id]).destroy
|
||||
flash[:success] = I18n.t("room.remove_shared_access_success")
|
||||
rescue => e
|
||||
logger.error "Support: Error in removing room shared access: #{e}"
|
||||
flash[:alert] = I18n.t("room.remove_shared_access_error")
|
||||
end
|
||||
|
||||
redirect_to current_user.main_room
|
||||
end
|
||||
|
||||
# GET /:room_uid/shared_users
|
||||
def shared_users
|
||||
# Respond with JSON object of users that have access to the room
|
||||
respond_to do |format|
|
||||
format.json { render body: @room.shared_users.to_json }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /:room_uid/room_settings
|
||||
def room_settings
|
||||
# Respond with JSON object of the room_settings
|
||||
respond_to do |format|
|
||||
format.json { render body: @room.room_settings.to_json }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /:room_uid/logout
|
||||
|
@ -219,12 +293,24 @@ class RoomsController < ApplicationController
|
|||
|
||||
# Find the room from the uid.
|
||||
def find_room
|
||||
@room = Room.find_by!(uid: params[:room_uid])
|
||||
@room = Room.includes(:owner).find_by!(uid: params[:room_uid])
|
||||
end
|
||||
|
||||
# Ensure the user is logged into the room they are accessing.
|
||||
def verify_room_ownership
|
||||
return redirect_to root_path unless @room.owned_by?(current_user)
|
||||
# Ensure the user either owns the room or is an admin of the room owner or the room is shared with him
|
||||
def verify_room_ownership_or_admin_or_shared
|
||||
return redirect_to root_path unless @room.owned_by?(current_user) ||
|
||||
room_shared_with_user ||
|
||||
current_user&.admin_of?(@room.owner)
|
||||
end
|
||||
|
||||
# Ensure the user either owns the room or is an admin of the room owner
|
||||
def verify_room_ownership_or_admin
|
||||
return redirect_to root_path if !@room.owned_by?(current_user) && !current_user&.admin_of?(@room.owner)
|
||||
end
|
||||
|
||||
# Ensure the user owns the room or is allowed to start it
|
||||
def verify_room_ownership_or_shared
|
||||
return redirect_to root_path unless @room.owned_by?(current_user) || room_shared_with_user
|
||||
end
|
||||
|
||||
def validate_accepted_terms
|
||||
|
@ -236,10 +322,12 @@ class RoomsController < ApplicationController
|
|||
end
|
||||
|
||||
def verify_room_owner_verified
|
||||
unless @room.owner.activated?
|
||||
flash[:alert] = t("room.unavailable")
|
||||
redirect_to root_path
|
||||
end
|
||||
redirect_to root_path, alert: t("room.unavailable") unless @room.owner.activated?
|
||||
end
|
||||
|
||||
# Check to make sure the room owner is not pending or banned
|
||||
def verify_room_owner_valid
|
||||
redirect_to root_path, alert: t("room.owner_banned") if @room.owner.has_role?(:pending) || @room.owner.has_role?(:denied)
|
||||
end
|
||||
|
||||
def verify_user_not_admin
|
||||
|
@ -250,6 +338,11 @@ class RoomsController < ApplicationController
|
|||
@settings.get_value("Room Authentication") == "true" && current_user.nil?
|
||||
end
|
||||
|
||||
# Checks if the room is shared with the user and room sharing is enabled
|
||||
def room_shared_with_user
|
||||
shared_access_allowed ? @room.shared_with?(current_user) : false
|
||||
end
|
||||
|
||||
def room_limit_exceeded
|
||||
limit = @settings.get_value("Room Limit").to_i
|
||||
|
||||
|
|
|
@ -74,6 +74,10 @@ class SessionsController < ApplicationController
|
|||
|
||||
# Check user with that email exists
|
||||
return redirect_to(signin_path, alert: I18n.t("invalid_credentials")) unless user
|
||||
|
||||
# Check if authenticators have switched
|
||||
return switch_account_to_local(user) if !is_super_admin && auth_changed_to_local?(user)
|
||||
|
||||
# Check correct password was entered
|
||||
return redirect_to(signin_path, alert: I18n.t("invalid_credentials")) unless user.try(:authenticate,
|
||||
session_params[:password])
|
||||
|
@ -84,7 +88,10 @@ class SessionsController < ApplicationController
|
|||
# Check that the user is a Greenlight account
|
||||
return redirect_to(root_path, alert: I18n.t("invalid_login_method")) unless user.greenlight_account?
|
||||
# Check that the user has verified their account
|
||||
return redirect_to(account_activation_path(email: user.email)) unless user.activated?
|
||||
unless user.activated?
|
||||
user.create_activation_token
|
||||
return redirect_to(account_activation_path(token: user.activation_token))
|
||||
end
|
||||
end
|
||||
|
||||
login(user)
|
||||
|
@ -199,6 +206,9 @@ class SessionsController < ApplicationController
|
|||
# If using invitation registration method, make sure user is invited
|
||||
return redirect_to root_path, flash: { alert: I18n.t("registration.invite.no_invite") } unless passes_invite_reqs
|
||||
|
||||
# Switch the user to a social account if they exist under the same email with no social uid
|
||||
switch_account_to_social if !@user_exists && auth_changed_to_social?(@auth['info']['email'])
|
||||
|
||||
user = User.from_omniauth(@auth)
|
||||
|
||||
logger.info "Support: Auth user #{user.email} is attempting to login."
|
||||
|
@ -225,4 +235,28 @@ class SessionsController < ApplicationController
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Send the user a password reset email to allow them to set their password
|
||||
def switch_account_to_local(user)
|
||||
logger.info "Switching social account to local account for #{user.uid}"
|
||||
|
||||
# Send the user a reset password email
|
||||
user.create_reset_digest
|
||||
send_password_reset_email(user)
|
||||
|
||||
# Overwrite the flash with a more descriptive message if successful
|
||||
flash[:success] = I18n.t("reset_password.auth_change") if flash[:success].present?
|
||||
|
||||
redirect_to signin_path
|
||||
end
|
||||
|
||||
# Set the user's social id to the new id being passed
|
||||
def switch_account_to_social
|
||||
user = User.find_by(email: @auth['info']['email'], provider: @user_domain, social_uid: nil)
|
||||
|
||||
logger.info "Switching account to social account for #{user.uid}"
|
||||
|
||||
# Set the user's social id to the one being returned from auth
|
||||
user.update_attribute(:social_uid, @auth['uid'])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,7 +26,7 @@ class ThemesController < ApplicationController
|
|||
lighten_color = @settings.get_value("Primary Color Lighten") || Rails.configuration.primary_color_lighten_default
|
||||
darken_color = @settings.get_value("Primary Color Darken") || Rails.configuration.primary_color_darken_default
|
||||
|
||||
file_name = Rails.root.join('app', 'assets', 'stylesheets', 'utilities', '_primary_themes.scss')
|
||||
file_name = Rails.root.join('lib', 'assets', '_primary_themes.scss')
|
||||
@file_contents = File.read(file_name)
|
||||
|
||||
# Include the variables and covert scss file to css
|
||||
|
|
|
@ -58,6 +58,8 @@ class UsersController < ApplicationController
|
|||
# Sign in automatically if email verification is disabled or if user is already verified.
|
||||
login(@user) && return if !Rails.configuration.enable_email_verification || @user.email_verified
|
||||
|
||||
@user.create_activation_token
|
||||
|
||||
send_activation_email(@user)
|
||||
|
||||
redirect_to root_path
|
||||
|
@ -80,7 +82,14 @@ class UsersController < ApplicationController
|
|||
# PATCH /u/:user_uid/edit
|
||||
def update
|
||||
profile = params[:setting] == "password" ? change_password_path(@user) : edit_user_path(@user)
|
||||
redirect_path = current_user.admin_of?(@user) ? admins_path : profile
|
||||
if session[:prev_url].present?
|
||||
path = session[:prev_url]
|
||||
session.delete(:prev_url)
|
||||
else
|
||||
path = admins_path
|
||||
end
|
||||
|
||||
redirect_path = current_user.admin_of?(@user) ? path : profile
|
||||
|
||||
if params[:setting] == "password"
|
||||
# Update the users password.
|
||||
|
@ -123,12 +132,13 @@ class UsersController < ApplicationController
|
|||
# DELETE /u/:user_uid
|
||||
def destroy
|
||||
# Include deleted users in the check
|
||||
admin_path = request.referer.present? ? request.referer : admins_path
|
||||
@user = User.include_deleted.find_by(uid: params[:user_uid])
|
||||
|
||||
logger.info "Support: #{current_user.email} is deleting #{@user.email}."
|
||||
|
||||
self_delete = current_user == @user
|
||||
redirect_url = self_delete ? root_path : admins_path
|
||||
redirect_url = self_delete ? root_path : admin_path
|
||||
|
||||
begin
|
||||
if current_user && (self_delete || current_user.admin_of?(@user))
|
||||
|
@ -183,7 +193,7 @@ class UsersController < ApplicationController
|
|||
private
|
||||
|
||||
def find_user
|
||||
@user = User.where(uid: params[:user_uid]).includes(:roles).first
|
||||
@user = User.find_by(uid: params[:user_uid])
|
||||
end
|
||||
|
||||
# Verify that GreenLight is configured to allow user signup.
|
||||
|
|
|
@ -37,6 +37,14 @@ module AdminsHelper
|
|||
end
|
||||
end
|
||||
|
||||
def shared_access_string
|
||||
if @settings.get_value("Shared Access") == "true"
|
||||
I18n.t("administrator.site_settings.authentication.enabled")
|
||||
else
|
||||
I18n.t("administrator.site_settings.authentication.disabled")
|
||||
end
|
||||
end
|
||||
|
||||
def recording_default_visibility_string
|
||||
if @settings.get_value("Default Recording Visibility") == "public"
|
||||
I18n.t("recording.visibility.public")
|
||||
|
@ -56,6 +64,23 @@ module AdminsHelper
|
|||
end
|
||||
end
|
||||
|
||||
def log_level_string
|
||||
case Rails.logger.level
|
||||
when 0
|
||||
t("administrator.site_settings.log_level.debug")
|
||||
when 1
|
||||
t("administrator.site_settings.log_level.info")
|
||||
when 2
|
||||
t("administrator.site_settings.log_level.warn")
|
||||
when 3
|
||||
t("administrator.site_settings.log_level.error")
|
||||
when 4
|
||||
t("administrator.site_settings.log_level.fatal")
|
||||
when 5
|
||||
t("administrator.site_settings.log_level.unknown")
|
||||
end
|
||||
end
|
||||
|
||||
def room_limit_number
|
||||
@settings.get_value("Room Limit").to_i
|
||||
end
|
||||
|
@ -63,4 +88,9 @@ module AdminsHelper
|
|||
def edit_disabled
|
||||
@edit_disabled ||= @selected_role.priority <= current_user.highest_priority_role.priority
|
||||
end
|
||||
|
||||
# Get the room status to display in the Server Rooms table
|
||||
def room_is_running(id)
|
||||
@running_room_bbb_ids.include?(id)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -57,7 +57,6 @@ module ApplicationHelper
|
|||
|
||||
# Returns the page that the logo redirects to when clicked on
|
||||
def home_page
|
||||
return root_path unless current_user
|
||||
return admins_path if current_user.has_role? :super_admin
|
||||
current_user.main_room
|
||||
end
|
||||
|
|
|
@ -24,18 +24,13 @@ module RecordingsHelper
|
|||
|
||||
# Helper for converting BigBlueButton dates into a nice length string.
|
||||
def recording_length(playbacks)
|
||||
# Stats format currently doesn't support length.
|
||||
valid_playbacks = playbacks.reject { |p| p[:type] == "statistics" }
|
||||
return "0 min" if valid_playbacks.empty?
|
||||
|
||||
len = valid_playbacks.first[:length]
|
||||
if len > 60
|
||||
"#{(len / 60).to_i} h #{len % 60} min"
|
||||
elsif len.zero?
|
||||
"< 1 min"
|
||||
else
|
||||
"#{len} min"
|
||||
# Looping through playbacks array and returning first non-zero length value
|
||||
playbacks.each do |playback|
|
||||
length = playback[:length]
|
||||
return recording_length_string(length) unless length.zero?
|
||||
end
|
||||
# Return '< 1 min' if length values are zero
|
||||
"< 1 min"
|
||||
end
|
||||
|
||||
# Prevents single images from erroring when not passed as an array.
|
||||
|
@ -51,4 +46,15 @@ module RecordingsHelper
|
|||
def recording_thumbnails?
|
||||
Rails.configuration.recording_thumbnails
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Returns length of the recording as a string
|
||||
def recording_length_string(len)
|
||||
if len > 60
|
||||
"#{(len / 60).to_i} h #{len % 60} min"
|
||||
else
|
||||
"#{len} min"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,7 +27,7 @@ class Ability
|
|||
else
|
||||
highest_role = user.highest_priority_role
|
||||
if highest_role.get_permission("can_edit_site_settings")
|
||||
can [:index, :site_settings, :server_recordings, :update_settings, :coloring, :registration_method], :admin
|
||||
can [:index, :site_settings, :update_settings, :coloring, :registration_method], :admin
|
||||
end
|
||||
|
||||
if highest_role.get_permission("can_edit_roles")
|
||||
|
@ -36,11 +36,13 @@ class Ability
|
|||
|
||||
if highest_role.get_permission("can_manage_users")
|
||||
can [:index, :roles, :edit_user, :promote, :demote, :ban_user, :unban_user,
|
||||
:approve, :invite, :reset, :undelete], :admin
|
||||
:approve, :invite, :reset, :undelete, :merge_user], :admin
|
||||
end
|
||||
|
||||
can [:index, :server_recordings, :server_rooms], :admin if highest_role.get_permission("can_manage_rooms_recordings")
|
||||
|
||||
if !highest_role.get_permission("can_edit_site_settings") && !highest_role.get_permission("can_edit_roles") &&
|
||||
!highest_role.get_permission("can_manage_users")
|
||||
!highest_role.get_permission("can_manage_users") && !highest_role.get_permission("can_manage_rooms_recordings")
|
||||
cannot :manage, AdminsController
|
||||
end
|
||||
end
|
||||
|
|
|
@ -48,6 +48,9 @@ module AuthValues
|
|||
case auth['provider']
|
||||
when :twitter
|
||||
auth['info']['image'].gsub("http", "https").gsub("_normal", "")
|
||||
when :ldap
|
||||
return auth['info']['image'] if auth['info']['image']&.starts_with?("http")
|
||||
""
|
||||
else
|
||||
auth['info']['image']
|
||||
end
|
||||
|
|
|
@ -20,7 +20,7 @@ class Role < ApplicationRecord
|
|||
has_and_belongs_to_many :users, join_table: :users_roles
|
||||
has_many :role_permissions
|
||||
|
||||
default_scope { order(:priority) }
|
||||
default_scope { includes(:role_permissions).order(:priority) }
|
||||
scope :by_priority, -> { order(:priority) }
|
||||
scope :editable_roles, ->(provider) { where(provider: provider).where.not(name: %w[super_admin denied pending]) }
|
||||
|
||||
|
@ -35,14 +35,14 @@ class Role < ApplicationRecord
|
|||
.update_all_role_permissions(can_create_rooms: true)
|
||||
Role.create(name: "admin", provider: provider, priority: 0, colour: "#f1c40f")
|
||||
.update_all_role_permissions(can_create_rooms: true, send_promoted_email: true,
|
||||
send_demoted_email: true, can_edit_site_settings: true,
|
||||
send_demoted_email: true, can_edit_site_settings: true, can_manage_rooms_recordings: true,
|
||||
can_edit_roles: true, can_manage_users: true)
|
||||
Role.create(name: "pending", provider: provider, priority: -1, colour: "#17a2b8").update_all_role_permissions
|
||||
Role.create(name: "denied", provider: provider, priority: -1, colour: "#343a40").update_all_role_permissions
|
||||
Role.create(name: "super_admin", provider: provider, priority: -2, colour: "#cd201f")
|
||||
Role.create(name: "denied", provider: provider, priority: -2, colour: "#343a40").update_all_role_permissions
|
||||
Role.create(name: "super_admin", provider: provider, priority: -3, colour: "#cd201f")
|
||||
.update_all_role_permissions(can_create_rooms: true,
|
||||
send_promoted_email: true, send_demoted_email: true, can_edit_site_settings: true,
|
||||
can_edit_roles: true, can_manage_users: true)
|
||||
can_edit_roles: true, can_manage_users: true, can_manage_rooms_recordings: true)
|
||||
end
|
||||
|
||||
def self.create_new_role(role_name, provider)
|
||||
|
@ -55,8 +55,8 @@ class Role < ApplicationRecord
|
|||
role.priority = user_role.priority
|
||||
user_role.priority += 1
|
||||
|
||||
role.save!
|
||||
user_role.save!
|
||||
role.save!
|
||||
|
||||
role
|
||||
end
|
||||
|
@ -68,10 +68,15 @@ class Role < ApplicationRecord
|
|||
update_permission("can_edit_site_settings", permissions[:can_edit_site_settings].to_s)
|
||||
update_permission("can_edit_roles", permissions[:can_edit_roles].to_s)
|
||||
update_permission("can_manage_users", permissions[:can_manage_users].to_s)
|
||||
update_permission("can_manage_rooms_recordings", permissions[:can_manage_rooms_recordings].to_s)
|
||||
update_permission("can_appear_in_share_list", permissions[:can_appear_in_share_list].to_s)
|
||||
end
|
||||
|
||||
# Updates the value of the permission and enables it
|
||||
def update_permission(name, value)
|
||||
# Dont update if it is not explicitly set to a value
|
||||
return unless value.present?
|
||||
|
||||
permission = role_permissions.find_or_create_by!(name: name)
|
||||
|
||||
permission.update_attributes(value: value, enabled: true)
|
||||
|
@ -79,18 +84,36 @@ class Role < ApplicationRecord
|
|||
|
||||
# Returns the value if enabled or the default if not enabled
|
||||
def get_permission(name, return_boolean = true)
|
||||
permission = role_permissions.find_or_create_by!(name: name)
|
||||
value = nil
|
||||
|
||||
value = if permission[:enabled]
|
||||
permission[:value]
|
||||
else
|
||||
"false"
|
||||
role_permissions.each do |permission|
|
||||
next if permission.name != name
|
||||
|
||||
value = if permission.enabled
|
||||
permission.value
|
||||
else
|
||||
default_value(name)
|
||||
end
|
||||
end
|
||||
|
||||
# Create the role_permissions since it doesn't exist
|
||||
role_permissions.create(name: name) if value.nil?
|
||||
|
||||
if return_boolean
|
||||
value == "true"
|
||||
else
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def default_value(name)
|
||||
case name
|
||||
when "can_appear_in_share_list"
|
||||
Rails.configuration.shared_access_default.to_s
|
||||
else
|
||||
"false"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,11 +26,46 @@ class Room < ApplicationRecord
|
|||
validates :name, presence: true
|
||||
|
||||
belongs_to :owner, class_name: 'User', foreign_key: :user_id
|
||||
has_many :shared_access
|
||||
|
||||
def self.admins_search(string)
|
||||
active_database = Rails.configuration.database_configuration[Rails.env]["adapter"]
|
||||
# Postgres requires created_at to be cast to a string
|
||||
created_at_query = if active_database == "postgresql"
|
||||
"created_at::text"
|
||||
else
|
||||
"created_at"
|
||||
end
|
||||
|
||||
search_query = "rooms.name LIKE :search OR rooms.uid LIKE :search OR users.email LIKE :search" \
|
||||
" OR users.#{created_at_query} LIKE :search"
|
||||
|
||||
search_param = "%#{string}%"
|
||||
|
||||
where(search_query, search: search_param)
|
||||
end
|
||||
|
||||
def self.admins_order(column, direction)
|
||||
# Include the owner of the table
|
||||
table = joins(:owner)
|
||||
|
||||
return table.order(Arel.sql("rooms.#{column} #{direction}")) if table.column_names.include?(column) || column == "users.name"
|
||||
|
||||
table
|
||||
end
|
||||
|
||||
# Determines if a user owns a room.
|
||||
def owned_by?(user)
|
||||
user_id == user&.id
|
||||
end
|
||||
|
||||
def shared_users
|
||||
User.where(id: shared_access.pluck(:user_id))
|
||||
end
|
||||
|
||||
def shared_with?(user)
|
||||
return false if user.nil?
|
||||
user.rooms.include?(self)
|
||||
shared_users.include?(user)
|
||||
end
|
||||
|
||||
# Determines the invite path for the room.
|
||||
|
|
|
@ -28,22 +28,36 @@ class Setting < ApplicationRecord
|
|||
|
||||
# Returns the value if enabled or the default if not enabled
|
||||
def get_value(name)
|
||||
feature = features.find_or_create_by!(name: name)
|
||||
if feature[:enabled]
|
||||
feature[:value]
|
||||
else
|
||||
case name
|
||||
when "Branding Image"
|
||||
Rails.configuration.branding_image_default
|
||||
when "Primary Color"
|
||||
Rails.configuration.primary_color_default
|
||||
when "Registration Method"
|
||||
Rails.configuration.registration_method_default
|
||||
when "Room Authentication"
|
||||
false
|
||||
when "Room Limit"
|
||||
Rails.configuration.number_of_rooms_default
|
||||
end
|
||||
# Return feature value if already exists
|
||||
features.each do |feature|
|
||||
next if feature.name != name
|
||||
|
||||
return feature.value if feature.enabled
|
||||
return default_value(name)
|
||||
end
|
||||
|
||||
# Create the feature since it doesn't exist
|
||||
features.create(name: name)
|
||||
default_value(name)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def default_value(name)
|
||||
# return default value
|
||||
case name
|
||||
when "Branding Image"
|
||||
Rails.configuration.branding_image_default
|
||||
when "Primary Color"
|
||||
Rails.configuration.primary_color_default
|
||||
when "Registration Method"
|
||||
Rails.configuration.registration_method_default
|
||||
when "Room Authentication"
|
||||
false
|
||||
when "Room Limit"
|
||||
Rails.configuration.number_of_rooms_default
|
||||
when "Shared Access"
|
||||
Rails.configuration.shared_access_default
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class SharedAccess < ApplicationRecord
|
||||
belongs_to :room
|
||||
end
|
|
@ -21,7 +21,7 @@ require 'bbb_api'
|
|||
class User < ApplicationRecord
|
||||
include Deleteable
|
||||
|
||||
attr_accessor :reset_token
|
||||
attr_accessor :reset_token, :activation_token
|
||||
after_create :setup_user
|
||||
|
||||
before_save { email.try(:downcase!) }
|
||||
|
@ -29,9 +29,10 @@ class User < ApplicationRecord
|
|||
before_destroy :destroy_rooms
|
||||
|
||||
has_many :rooms
|
||||
has_many :shared_access
|
||||
belongs_to :main_room, class_name: 'Room', foreign_key: :room_id, required: false
|
||||
|
||||
has_and_belongs_to_many :roles, -> { includes :role_permissions }, join_table: :users_roles
|
||||
has_and_belongs_to_many :roles, join_table: :users_roles
|
||||
|
||||
validates :name, length: { maximum: 256 }, presence: true
|
||||
validates :provider, presence: true
|
||||
|
@ -102,6 +103,11 @@ class User < ApplicationRecord
|
|||
order(Arel.sql("#{column} #{direction}"))
|
||||
end
|
||||
|
||||
# Returns a list of rooms ordered by last session
|
||||
def ordered_rooms
|
||||
[main_room] + rooms.where.not(id: main_room.id).order("last_session desc")
|
||||
end
|
||||
|
||||
# Activates an account and initialize a users main room
|
||||
def activate
|
||||
update_attributes(email_verified: true, activated_at: Time.zone.now)
|
||||
|
@ -121,7 +127,7 @@ class User < ApplicationRecord
|
|||
def authenticated?(attribute, token)
|
||||
digest = send("#{attribute}_digest")
|
||||
return false if digest.nil?
|
||||
BCrypt::Password.new(digest).is_password?(token)
|
||||
digest == Digest::SHA256.base64digest(token)
|
||||
end
|
||||
|
||||
# Return true if password reset link expires
|
||||
|
@ -129,10 +135,9 @@ class User < ApplicationRecord
|
|||
reset_sent_at < 2.hours.ago
|
||||
end
|
||||
|
||||
# Retrives a list of all a users rooms that are not the main room, sorted by last session date.
|
||||
def secondary_rooms
|
||||
room_list = rooms.where.not(uid: main_room.uid)
|
||||
room_list.where.not(last_session: nil).order("last_session desc") + room_list.where(last_session: nil)
|
||||
# Retrieves a list of rooms that are shared with the user
|
||||
def shared_rooms
|
||||
Room.where(id: shared_access.pluck(:room_id))
|
||||
end
|
||||
|
||||
def name_chunk
|
||||
|
@ -153,9 +158,9 @@ class User < ApplicationRecord
|
|||
social_uid.nil?
|
||||
end
|
||||
|
||||
def activation_token
|
||||
# Create the token.
|
||||
create_reset_activation_digest(User.new_token)
|
||||
def create_activation_token
|
||||
self.activation_token = User.new_token
|
||||
update_attributes(activation_digest: User.digest(activation_token))
|
||||
end
|
||||
|
||||
def admin_of?(user)
|
||||
|
@ -172,8 +177,7 @@ class User < ApplicationRecord
|
|||
end
|
||||
|
||||
def self.digest(string)
|
||||
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost
|
||||
BCrypt::Password.create(string, cost: cost)
|
||||
Digest::SHA256.base64digest(string)
|
||||
end
|
||||
|
||||
# Returns a random token.
|
||||
|
@ -183,7 +187,7 @@ class User < ApplicationRecord
|
|||
|
||||
# role functions
|
||||
def highest_priority_role
|
||||
roles.by_priority.first
|
||||
roles.min_by(&:priority)
|
||||
end
|
||||
|
||||
def add_role(role)
|
||||
|
@ -217,7 +221,11 @@ class User < ApplicationRecord
|
|||
# rubocop:disable Naming/PredicateName
|
||||
def has_role?(role)
|
||||
# rubocop:enable Naming/PredicateName
|
||||
roles.exists?(name: role)
|
||||
roles.each do |single_role|
|
||||
return true if single_role.name.eql? role.to_s
|
||||
end
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
def self.with_role(role)
|
||||
|
@ -228,19 +236,24 @@ class User < ApplicationRecord
|
|||
User.where.not(id: with_role(role).pluck(:id))
|
||||
end
|
||||
|
||||
def self.with_highest_priority_role(role)
|
||||
User.all_users_highest_priority_role.where(roles: { name: role })
|
||||
end
|
||||
|
||||
def self.all_users_with_roles
|
||||
User.joins("INNER JOIN users_roles ON users_roles.user_id = users.id INNER JOIN roles " \
|
||||
"ON roles.id = users_roles.role_id INNER JOIN role_permissions ON roles.id = role_permissions.role_id").distinct
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_reset_activation_digest(token)
|
||||
# Create the digest and persist it.
|
||||
update_attribute(:activation_digest, User.digest(token))
|
||||
token
|
||||
def self.all_users_highest_priority_role
|
||||
User.joins("INNER JOIN (SELECT user_id, min(roles.priority) as role_priority FROM users_roles " \
|
||||
"INNER JOIN roles ON users_roles.role_id = roles.id GROUP BY user_id) as a ON " \
|
||||
"a.user_id = users.id INNER JOIN roles ON roles.priority = a.role_priority " \
|
||||
" INNER JOIN role_permissions ON roles.id = role_permissions.role_id").distinct
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Destory a users rooms when they are removed.
|
||||
def destroy_rooms
|
||||
rooms.destroy_all
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<div class="card-body">
|
||||
<p><%= t("verify.not_verified") %></p>
|
||||
<div class="btn-list text-right pt-8">
|
||||
<%= button_to t("verify.resend"), resend_email_path, params: { email: params['email'], email_verified: false }, class: "btn btn-primary btn-space" %>
|
||||
<%= button_to t("verify.resend"), resend_email_path, params: { token: params['token'], email_verified: false }, class: "btn btn-primary btn-space", "data-disable": "" %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -21,17 +21,22 @@
|
|||
<span class="icon mr-3"><i class="fas fa-users"></i></span><%= t("administrator.users.title") %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if highest_role.get_permission("can_edit_site_settings") || highest_role.name == "super_admin" %>
|
||||
<%= link_to admin_recordings_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "server_recordings"}" do %>
|
||||
<span class="icon mr-4"><i class="fas fa-video"></i></i></span><%= t("administrator.recordings.title") %>
|
||||
<% if highest_role.get_permission("can_manage_rooms_recordings") || highest_role.name == "super_admin" %>
|
||||
<%= link_to admin_rooms_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "server_rooms"}" do %>
|
||||
<span class="icon mr-4"><i class="fas fa-binoculars"></i></span><%= t("administrator.rooms.title") %>
|
||||
<% end %>
|
||||
<%= link_to admin_recordings_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "server_recordings"}" do %>
|
||||
<span class="icon mr-4"><i class="fas fa-video"></i></span><%= t("administrator.recordings.title") %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if highest_role.get_permission("can_edit_site_settings") || highest_role.name == "super_admin" %>
|
||||
<%= link_to admin_site_settings_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "site_settings"}" do %>
|
||||
<span class="icon mr-4"><i class="fas fa-cogs"></i></span><%= t("administrator.site_settings.title") %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if highest_role.get_permission("can_edit_roles") || highest_role.name == "super_admin" %>
|
||||
<%= link_to admin_roles_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "roles"}" do %>
|
||||
<span class="icon mr-4"><i class="fas fa-user-tag"></i></i></span><%= t("administrator.roles.title") %>
|
||||
<span class="icon mr-4"><i class="fas fa-user-tag"></i></span><%= t("administrator.roles.title") %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
|
@ -53,14 +53,14 @@
|
|||
<%= f.check_box :can_create_rooms, checked: @selected_role.get_permission("can_create_rooms"), class: "custom-switch-input", disabled: edit_disabled || !current_role.get_permission("can_create_rooms") %>
|
||||
<span class="custom-switch-indicator float-right"></span>
|
||||
</label>
|
||||
<label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%="form-disable" if !current_role.get_permission("send_promoted_email") %>">
|
||||
<span class="ml-0 custom-switch-description"><%= t("administrator.roles.promote_email")%></span>
|
||||
<%= f.check_box :send_promoted_email, checked: @selected_role.get_permission("send_promoted_email"), class: "custom-switch-input", disabled: edit_disabled || !current_role.get_permission("send_promoted_email") %>
|
||||
<label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%="form-disable" if !current_role.get_permission("can_manage_users") %>">
|
||||
<span class="ml-0 custom-switch-description"><%= t("administrator.roles.manage_users")%></span>
|
||||
<%= f.check_box :can_manage_users, checked: @selected_role.get_permission("can_manage_users"), class: "custom-switch-input", disabled: edit_disabled || !current_role.get_permission("can_manage_users") %>
|
||||
<span class="custom-switch-indicator float-right"></span>
|
||||
</label>
|
||||
<label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%="form-disable" if !current_role.get_permission("send_demoted_email") %>">
|
||||
<span class="ml-0 custom-switch-description"><%= t("administrator.roles.demote_email")%></span>
|
||||
<%= f.check_box :send_demoted_email, checked: @selected_role.get_permission("send_demoted_email"), class: "custom-switch-input", disabled: edit_disabled || !current_role.get_permission("send_demoted_email") %>
|
||||
<label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%="form-disable" if !current_role.get_permission("can_manage_rooms_recordings") %>">
|
||||
<span class="ml-0 custom-switch-description"><%= t("administrator.roles.manage_rooms_recordings")%></span>
|
||||
<%= f.check_box :can_manage_rooms_recordings, checked: @selected_role.get_permission("can_manage_rooms_recordings"), class: "custom-switch-input", disabled: edit_disabled || !current_role.get_permission("can_manage_rooms_recordings") %>
|
||||
<span class="custom-switch-indicator float-right"></span>
|
||||
</label>
|
||||
<label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%="form-disable" if !current_role.get_permission("can_edit_site_settings") %>">
|
||||
|
@ -73,9 +73,19 @@
|
|||
<%= f.check_box :can_edit_roles, checked: @selected_role.get_permission("can_edit_roles"), class: "custom-switch-input", disabled: edit_disabled || !current_role.get_permission("can_edit_roles") %>
|
||||
<span class="custom-switch-indicator float-right"></span>
|
||||
</label>
|
||||
<label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%="form-disable" if !current_role.get_permission("can_manage_users") %>">
|
||||
<span class="ml-0 custom-switch-description"><%= t("administrator.roles.manage_users")%></span>
|
||||
<%= f.check_box :can_manage_users, checked: @selected_role.get_permission("can_manage_users"), class: "custom-switch-input", disabled: edit_disabled || !current_role.get_permission("can_manage_users") %>
|
||||
<label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%="form-disable" if !current_role.get_permission("can_appear_in_share_list") %>">
|
||||
<span class="ml-0 custom-switch-description"><%= t("administrator.roles.appear_in_share_list")%></span>
|
||||
<%= f.check_box :can_appear_in_share_list, checked: @selected_role.get_permission("can_appear_in_share_list"), class: "custom-switch-input", disabled: edit_disabled || !current_role.get_permission("can_appear_in_share_list") %>
|
||||
<span class="custom-switch-indicator float-right"></span>
|
||||
</label>
|
||||
<label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%="form-disable" if !current_role.get_permission("send_promoted_email") %>">
|
||||
<span class="ml-0 custom-switch-description"><%= t("administrator.roles.promote_email")%></span>
|
||||
<%= f.check_box :send_promoted_email, checked: @selected_role.get_permission("send_promoted_email"), class: "custom-switch-input", disabled: edit_disabled || !current_role.get_permission("send_promoted_email") %>
|
||||
<span class="custom-switch-indicator float-right"></span>
|
||||
</label>
|
||||
<label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%="form-disable" if !current_role.get_permission("send_demoted_email") %>">
|
||||
<span class="ml-0 custom-switch-description"><%= t("administrator.roles.demote_email")%></span>
|
||||
<%= f.check_box :send_demoted_email, checked: @selected_role.get_permission("send_demoted_email"), class: "custom-switch-input", disabled: edit_disabled || !current_role.get_permission("send_demoted_email") %>
|
||||
<span class="custom-switch-indicator float-right"></span>
|
||||
</label>
|
||||
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
<%
|
||||
# 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/>.
|
||||
%>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="table-responsive">
|
||||
<table id="rooms-table" class="table table-hover table-outline table-vcenter text-nowrap card-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-header="name" data-order="<%= @order_column == "name" ? @order_direction : "none" %>">
|
||||
<%= t("administrator.users.table.name") %>
|
||||
<% if @order_column == "name" && @order_direction == "desc" %>
|
||||
↓
|
||||
<% elsif @order_column == "name" && @order_direction == "asc" %>
|
||||
↑
|
||||
<% end %>
|
||||
</th>
|
||||
<th data-header="users.name" data-order="<%= @order_column == "users.name" ? @order_direction : "none" %>">
|
||||
<%= t("room.owner") %>
|
||||
<% if @order_column == "users.name" && @order_direction == "desc" %>
|
||||
↓
|
||||
<% elsif @order_column == "users.name" && @order_direction == "asc" %>
|
||||
↑
|
||||
<% end %>
|
||||
</th>
|
||||
<th data-header="uid" data-order="<%= @order_column == "uid" ? @order_direction : "none" %>">
|
||||
<%= t("administrator.rooms.table.id") %>
|
||||
<% if @order_column == "uid" && @order_direction == "desc" %>
|
||||
↓
|
||||
<% elsif @order_column == "uid" && @order_direction == "asc" %>
|
||||
↑
|
||||
<% end %>
|
||||
</th>
|
||||
<th>
|
||||
<%= t("administrator.rooms.table.status") %>
|
||||
</th>
|
||||
<th class="text-center"><i class="icon-settings"></i></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="rooms-table">
|
||||
<% @rooms.each do |room| %>
|
||||
<%= render "admins/components/server_room_row", room: room %>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<% if !@rooms.empty?%>
|
||||
<div class="float-right mr-4 mt-4">
|
||||
<%== pagy_bootstrap_nav(@pagy) %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -46,10 +46,10 @@
|
|||
<button class="btn btn-sm btn-secondary dropdown-toggle" data-toggle="dropdown"><i class="dropdown-icon fas fa-link px-2"></i> <%= t("recording.visibility.unlisted") %></button>
|
||||
<% end %>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
||||
<%= button_to update_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID], state: "public"), class: "dropdown-item" do %>
|
||||
<%= button_to update_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID], state: "public"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<i class="dropdown-icon fas fa-globe"></i> <%= t("recording.visibility.public") %>
|
||||
<% end %>
|
||||
<%= button_to update_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID], state: "unlisted"), class: "dropdown-item" do %>
|
||||
<%= button_to update_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID], state: "unlisted"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<i class="dropdown-icon fas fa-link"></i> <%= t("recording.visibility.unlisted") %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
@ -73,7 +73,7 @@
|
|||
<a class="dropdown-item email-link" data-pres-link="<%= recording_links %>"><i class="dropdown-icon far fa-envelope"></i> <%= t("recording.email") %></a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<% end %>
|
||||
<%= button_to delete_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID]), method: :delete, class: "dropdown-item" do %>
|
||||
<%= button_to delete_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID]), method: :delete, class: "dropdown-item", "data-disable": "" do %>
|
||||
<i class="dropdown-icon far fa-trash-alt"></i> <%= t("delete") %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
<%
|
||||
# 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/>.
|
||||
%>
|
||||
|
||||
<tr id="room-block" data-path="<%= update_settings_path(room) %>" data-room-settings=<%= room.room_settings %> data-room-access-code="<%= room.access_code %>">
|
||||
<td>
|
||||
<div id="room-title" class="form-inline edit_hover_class">
|
||||
<% if room.id == room.owner.room_id %>
|
||||
<i class="fas fa-home pr-1"></i>
|
||||
<% end %>
|
||||
<text id="room-name-text">
|
||||
<%= room.name %>
|
||||
</text>
|
||||
</div>
|
||||
<div class="small text-muted">
|
||||
<%= [t("administrator.users.table.created"), ": ", room.created_at].join %>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-left">
|
||||
<%= room.owner.name %>
|
||||
</td>
|
||||
<td class="text-left">
|
||||
<%= room.uid %>
|
||||
</td>
|
||||
<td class="text-left">
|
||||
<% running = room_is_running(room.bbb_id) %>
|
||||
<% if running %>
|
||||
<%= t("administrator.rooms.running") %>
|
||||
<% else %>
|
||||
<%= t("administrator.rooms.not_running") %>
|
||||
<% end %>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<div class="item-action dropdown">
|
||||
<a href="javascript:void(0)" data-toggle="dropdown" class="icon">
|
||||
<i class="fas fa-ellipsis-v px-4"></i>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right">
|
||||
<%= link_to room_path(room), class: "dropdown-item" do %>
|
||||
<i class="dropdown-icon far fa-eye"></i> <%= t("administrator.rooms.view") %>
|
||||
<% end %>
|
||||
<%= button_to start_room_path(room), class: "dropdown-item", "data-disable": "" do %>
|
||||
<i class="dropdown-icon fas fa-door-open"></i> <%= running ? t("room.join") : t("room.start") %>
|
||||
<% end %>
|
||||
<a href="" data-toggle="modal" data-target="#createRoomModal" class="update-room dropdown-item">
|
||||
<i class="dropdown-icon fas fa-cog"></i> <%= t("room.settings") %>
|
||||
</a>
|
||||
<% if shared_access_allowed %>
|
||||
<a href="" data-toggle="modal" data-target="#shareRoomModal" class="share-room dropdown-item" data-path="<%= room_shared_access_path(room) %>" data-users-path="<%= room_shared_users_path(room) %>">
|
||||
<i class="dropdown-icon fas fa-users"></i> <%= t("room.share") %>
|
||||
</a>
|
||||
<% end %>
|
||||
<% if room.id != room.owner.room_id %>
|
||||
<a href="" data-toggle="modal" data-target="#deleteRoomModal" data-path="<%= room_path(room) %>" data-name="<%= room.name %>" class="delete-room dropdown-item">
|
||||
<i class="dropdown-icon far fa-trash-alt"></i> <%= t("delete") %>
|
||||
</a>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
|
@ -64,13 +64,13 @@
|
|||
<%= registration_method_string %>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="registrationMethods">
|
||||
<%= button_to admin_change_registration_path(value: "open"), class: "dropdown-item" do %>
|
||||
<%= button_to admin_change_registration_path(value: "open"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.registration.methods.open") %>
|
||||
<% end %>
|
||||
<%= button_to admin_change_registration_path(value: "invite"), class: "dropdown-item" do %>
|
||||
<%= button_to admin_change_registration_path(value: "invite"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.registration.methods.invite") %>
|
||||
<% end %>
|
||||
<%= button_to admin_change_registration_path(value: "approval"), class: "dropdown-item" do %>
|
||||
<%= button_to admin_change_registration_path(value: "approval"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.registration.methods.approval") %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
@ -88,10 +88,10 @@
|
|||
<%= room_authentication_string %>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="room-auth">
|
||||
<%= button_to admin_update_settings_path(setting: "Room Authentication", value: "true"), class: "dropdown-item" do %>
|
||||
<%= button_to admin_update_settings_path(setting: "Room Authentication", value: "true"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.authentication.enabled") %>
|
||||
<% end %>
|
||||
<%= button_to admin_update_settings_path(setting: "Room Authentication", value: "false"), class: "dropdown-item" do %>
|
||||
<%= button_to admin_update_settings_path(setting: "Room Authentication", value: "false"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.authentication.disabled") %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
@ -99,7 +99,28 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-6 row">
|
||||
<div class="mb-6 row">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.shared_access.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.shared_access.info") %></label>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-primary dropdown-toggle" type="button" id="room-auth" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<%= shared_access_string %>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="room-auth">
|
||||
<%= button_to admin_update_settings_path(setting: "Shared Access", value: "true"), class: "dropdown-item" do %>
|
||||
<%= t("administrator.site_settings.authentication.enabled") %>
|
||||
<% end %>
|
||||
<%= button_to admin_update_settings_path(setting: "Shared Access", value: "false"), class: "dropdown-item" do %>
|
||||
<%= t("administrator.site_settings.authentication.disabled") %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-6 row">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.recording_visibility.title") %></label>
|
||||
|
@ -109,10 +130,10 @@
|
|||
<%= recording_default_visibility_string %>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="room-auth">
|
||||
<%= button_to admin_update_settings_path(setting: "Default Recording Visibility", value: "public"), class: "dropdown-item" do %>
|
||||
<%= button_to admin_update_settings_path(setting: "Default Recording Visibility", value: "public"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("recording.visibility.public") %>
|
||||
<% end %>
|
||||
<%= button_to admin_update_settings_path(setting: "Default Recording Visibility", value: "private"), class: "dropdown-item" do %>
|
||||
<%= button_to admin_update_settings_path(setting: "Default Recording Visibility", value: "private"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("recording.visibility.unlisted") %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
@ -128,25 +149,25 @@
|
|||
<div class="row gutters-xs">
|
||||
<div class="col-auto">
|
||||
<label class="colorinput">
|
||||
<%= button_to admin_update_settings_path(setting: "Room Limit", value: 1), class: "colorinput-input" do %><% end %>
|
||||
<%= button_to admin_update_settings_path(setting: "Room Limit", value: 1), class: "colorinput-input", "data-disable": "" do %><% end %>
|
||||
<span class="colorinput-color <%= room_limit_number == 1 ? "btn-primary" : "btn-outline-primary" %>">1</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label class="colorinput">
|
||||
<%= button_to admin_update_settings_path(setting: "Room Limit", value: 5), class: "colorinput-input" do %><% end %>
|
||||
<%= button_to admin_update_settings_path(setting: "Room Limit", value: 5), class: "colorinput-input", "data-disable": "" do %><% end %>
|
||||
<span class="colorinput-color <%= room_limit_number == 5 ? "btn-primary" : "btn-outline-primary" %>">5</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label class="colorinput">
|
||||
<%= button_to admin_update_settings_path(setting: "Room Limit", value: 10), class: "colorinput-input" do %><% end %>
|
||||
<%= button_to admin_update_settings_path(setting: "Room Limit", value: 10), class: "colorinput-input", "data-disable": "" do %><% end %>
|
||||
<span class="colorinput-color <%= room_limit_number == 10 ? "btn-primary" : "btn-outline-primary" %>">10</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label class="colorinput">
|
||||
<%= button_to admin_update_settings_path(setting: "Room Limit", value: 15), class: "colorinput-input" do %><% end %>
|
||||
<%= button_to admin_update_settings_path(setting: "Room Limit", value: 15), class: "colorinput-input", "data-disable": "" do %><% end %>
|
||||
<span class="colorinput-color <%= room_limit_number == 15 ? "btn-primary" : "btn-outline-primary" %>">15+</span>
|
||||
</label>
|
||||
</div>
|
||||
|
@ -155,12 +176,55 @@
|
|||
</div>
|
||||
</div>
|
||||
<% if current_user.has_role? :super_admin%>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="mb-6 form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.cache.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.cache.info") %></label>
|
||||
<%= button_to t("administrator.site_settings.cache.button"), admin_clear_cache_path, class: "btn btn-primary" %>
|
||||
<%= button_to t("administrator.site_settings.cache.button"), admin_clear_cache_path, class: "btn btn-primary", "data-disable": "" %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-4 row">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.clear_auth.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.clear_auth.info") %></label>
|
||||
<%= button_to t("administrator.site_settings.clear_auth.button"), admin_clear_auth_path, class: "btn btn-primary" %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-4 row">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.log_level.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.log_level.information") %></label>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-primary dropdown-toggle" type="button" id="room-auth" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<%= log_level_string %>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="room-auth">
|
||||
<%= button_to admin_log_level_path(value: 0), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.log_level.debug") %>
|
||||
<% end %>
|
||||
<%= button_to admin_log_level_path(value: 1), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.log_level.info") %>
|
||||
<% end %>
|
||||
<%= button_to admin_log_level_path(value: 2), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.log_level.warn") %>
|
||||
<% end %>
|
||||
<%= button_to admin_log_level_path(value: 3), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.log_level.error") %>
|
||||
<% end %>
|
||||
<%= button_to admin_log_level_path(value: 4), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.log_level.fatal") %>
|
||||
<% end %>
|
||||
<%= button_to admin_log_level_path(value: 5), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.log_level.unknown") %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -100,31 +100,34 @@
|
|||
</a>
|
||||
<div class="dropdown-menu dropdown-menu">
|
||||
<% if user.deleted? %>
|
||||
<%= button_to admin_undelete_path(user_uid: user.uid), class: "dropdown-item" do %>
|
||||
<%= button_to admin_undelete_path(user_uid: user.uid), class: "dropdown-item", "data-disable": "" do %>
|
||||
<i class="dropdown-icon fas fa-recycle"></i> <%= t("administrator.users.settings.undelete") %>
|
||||
<% end %>
|
||||
<button class="delete-user dropdown-item" data-path="<%= delete_user_path(user_uid: user.uid, permanent: "true") %>" data-toggle="modal" data-target="#deleteAccountModal">
|
||||
<i class="dropdown-icon fas fa-skull-crossbones"></i> <%= t("administrator.users.settings.perm_delete") %>
|
||||
</button>
|
||||
<% elsif roles.include?("denied") %>
|
||||
<%= button_to admin_unban_path(user_uid: user.uid), class: "dropdown-item" do %>
|
||||
<%= button_to admin_unban_path(user_uid: user.uid), class: "dropdown-item", "data-disable": "" do %>
|
||||
<i class="dropdown-icon fas fa-lock-open"></i> <%= t("administrator.users.settings.unban") %>
|
||||
<% end %>
|
||||
<button class= "delete-user dropdown-item" data-path="<%= delete_user_path(user_uid: user.uid) %>" data-delete="temp-delete" data-toggle="modal" data-target="#deleteAccountModal">
|
||||
<i class="dropdown-icon fas fa-user-minus"></i> <%= t("administrator.users.settings.delete") %>
|
||||
</button>
|
||||
<% elsif roles.include?("pending") %>
|
||||
<%= button_to admin_approve_path(user_uid: user.uid), class: "dropdown-item" do %>
|
||||
<%= button_to admin_approve_path(user_uid: user.uid), class: "dropdown-item", "data-disable": "" do %>
|
||||
<i class="dropdown-icon far fa-check-circle"></i> <%= t("administrator.users.settings.approve") %>
|
||||
<% end %>
|
||||
<%= button_to admin_ban_path(user_uid: user.uid), class: "dropdown-item" do %>
|
||||
<%= button_to admin_ban_path(user_uid: user.uid), class: "dropdown-item", "data-disable": "" do %>
|
||||
<i class="dropdown-icon far fa-times-circle"></i> <%= t("administrator.users.settings.decline") %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= link_to admin_edit_user_path(user_uid: user.uid), class: "dropdown-item" do %>
|
||||
<i class="dropdown-icon fas fa-user-edit"></i> <%= t("administrator.users.settings.edit") %>
|
||||
<% end %>
|
||||
<%= button_to admin_ban_path(user_uid: user.uid), class: "dropdown-item" do %>
|
||||
<button class= "merge-user dropdown-item" data-path="<%= merge_user_path(user_uid: user.uid) %>" data-info="<%= user.slice(:name, :email, :uid).to_json %>" data-toggle="modal" data-target="#mergeUserModal">
|
||||
<i class="dropdown-icon fas fa-user-friends"></i> <%= t("administrator.users.settings.merge") %>
|
||||
</button>
|
||||
<%= button_to admin_ban_path(user_uid: user.uid), class: "dropdown-item", "data-disable": "" do %>
|
||||
<i class="dropdown-icon fas fa-lock"></i> <%= t("administrator.users.settings.ban") %>
|
||||
<% end %>
|
||||
<button class= "delete-user dropdown-item" data-path="<%= delete_user_path(user_uid: user.uid) %>" data-delete="temp-delete" data-toggle="modal" data-target="#deleteAccountModal">
|
||||
|
@ -157,3 +160,4 @@
|
|||
|
||||
<%= render "shared/modals/invite_user_modal" %>
|
||||
<%= render "shared/modals/delete_account_modal", delete_location: relative_root %>
|
||||
<%= render "shared/modals/merge_user_modal" %>
|
|
@ -0,0 +1,33 @@
|
|||
<%
|
||||
# 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/>.
|
||||
%>
|
||||
|
||||
<div class="container pt-6">
|
||||
<%= render "shared/components/subtitle", subtitle: t("administrator.title"), search: false %>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-3 mb-4">
|
||||
<%= render "admins/components/menu_buttons" %>
|
||||
</div>
|
||||
<div id="server_recordings" class="col-lg-9">
|
||||
<%= render "admins/components/setting_view", setting_id: "rooms", setting_title: t("administrator.rooms.title"), search: true %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= render "shared/modals/delete_room_modal" %>
|
||||
<%= render "shared/modals/create_room_modal" %>
|
||||
<% if shared_access_allowed %>
|
||||
<%= render "shared/modals/share_room_modal" %>
|
||||
<% end %>
|
|
@ -13,7 +13,7 @@
|
|||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
%>
|
||||
|
||||
<div id="<%= if room == current_user.main_room then 'home_room_block' else 'room-block' end %>" data-room-uid="<%= room.uid %>" data-room-settings=<%= room.room_settings %> data-room-access-code="<%= room.access_code %>" class="card">
|
||||
<div id="room-block" data-path="<%= update_settings_path(room) %>" data-room-access-code="<%= room.access_code %>" class="card">
|
||||
<div class="card-body p-1">
|
||||
<table class="table table-hover table-vcenter text-wrap table-no-border">
|
||||
<tbody class="no-border-top">
|
||||
|
@ -28,11 +28,7 @@
|
|||
</td>
|
||||
<td>
|
||||
<div id="room-name">
|
||||
<% if room == current_user.main_room %>
|
||||
<h4 contenteditable="false" class="m-0 force-text-normal" ><%= t("home_room") %></h4>
|
||||
<% else %>
|
||||
<h4 contenteditable="false" class="m-0 force-text-normal" ><%= room.name %></h4>
|
||||
<% end %>
|
||||
<h4 id="room-name-text" contenteditable="false" class="m-0 force-text-normal" ><%= room.name %></h4>
|
||||
</div>
|
||||
<div id="room-name-editable" style="display: none">
|
||||
<input id="room-name-editable-input" class="form-control input-sm w-100 h-4" value="<%= room.name %>">
|
||||
|
@ -45,20 +41,27 @@
|
|||
<% end %>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<td class="text-right">
|
||||
<div class="item-action dropdown" data-display="static">
|
||||
<a href="javascript:void(0)" data-toggle="dropdown" data-display="static" class="icon <%= 'invisible' if room == current_user.main_room %>">
|
||||
<a href="javascript:void(0)" data-toggle="dropdown" data-display="static" class="icon">
|
||||
<i class="fas fa-ellipsis-v px-4"></i>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right dropdown-menu-md-left">
|
||||
<a href="" data-toggle="modal" data-target="#createRoomModal" class="update-room dropdown-item">
|
||||
<a href="" data-toggle="modal" data-target="#createRoomModal" class="update-room dropdown-item" data-settings-path="<%= room_settings_path(room) %>">
|
||||
<i class="dropdown-icon fas fa-cog"></i> <%= t("room.settings") %>
|
||||
</a>
|
||||
<a href="" data-toggle="modal" data-target="#deleteRoomModal" data-path="<%= room_path(room) %>" data-name="<%= room.name %>" class="delete-room dropdown-item">
|
||||
<i class="dropdown-icon far fa-trash-alt"></i> <%= t("delete") %>
|
||||
</a>
|
||||
<% if shared_access_allowed %>
|
||||
<a href="" data-toggle="modal" data-target="#shareRoomModal" class="share-room dropdown-item" data-path="<%= room_shared_access_path(room) %>" data-users-path="<%= room_shared_users_path(room) %>">
|
||||
<i class="dropdown-icon fas fa-users"></i> <%= t("room.share") %>
|
||||
</a>
|
||||
<% end %>
|
||||
<% unless room == current_user.main_room %>
|
||||
<a href="" data-toggle="modal" data-target="#deleteRoomModal" data-path="<%= room_path(room) %>" data-name="<%= room.name %>" class="delete-room dropdown-item">
|
||||
<i class="dropdown-icon far fa-trash-alt"></i> <%= t("delete") %>
|
||||
</a>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-8 col-sm-12 form-inline mb-5 align-top">
|
||||
<div class="col-lg-6 col-md-6 col-sm-12 form-inline mb-5 align-top">
|
||||
<% if @room.owner.image.blank? %>
|
||||
<span class="avatar"><%= @room.owner.name.first %></span>
|
||||
<% else %>
|
||||
|
@ -33,7 +33,7 @@
|
|||
<h5 class="font-weight-normal ml-4 mt-3"><%= @room.owner.name %> (<%= t("room.owner") %>)</h5>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-6 col-md-4 col-sm-12">
|
||||
<div class="col-lg-6 col-md-6 col-sm-12">
|
||||
<%= yield %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
<%
|
||||
# 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/>.
|
||||
%>
|
||||
|
||||
<div id="room-block" data-room-uid="<%= room.uid %>" data-room-settings=<%= room.room_settings %> data-room-access-code="<%= room.access_code %>" class="card">
|
||||
<div class="card-body p-1">
|
||||
<table class="table table-hover table-vcenter text-wrap table-no-border">
|
||||
<tbody class="no-border-top">
|
||||
<td>
|
||||
<span class="stamp stamp-md bg-primary">
|
||||
<i class="fas fa-share-alt"></i>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<div id="room-name">
|
||||
<h4 contenteditable="false" class="m-0 force-text-normal" ><%= room.name %></h4>
|
||||
</div>
|
||||
<div class="small text-muted text-break">
|
||||
<%= t("room.shared_by", email: room.owner.name) %>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<div class="item-action dropdown" data-display="static">
|
||||
<a href="javascript:void(0)" data-toggle="dropdown" data-display="static" class="icon">
|
||||
<i class="fas fa-ellipsis-v px-4"></i>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right dropdown-menu-md-left">
|
||||
<a href="" data-toggle="modal" data-target="#removeAccessModal" class="remove-share-room dropdown-item" data-path="<%= room_remove_shared_access_path(room) %>">
|
||||
<i class="dropdown-icon far fa-trash-alt"></i> <%= t("remove") %>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
|
@ -31,7 +31,7 @@
|
|||
<% end %>
|
||||
<% else %>
|
||||
<%= form_for room_path(@room), method: :post do |f| %>
|
||||
<div class="input-group join-input">
|
||||
<div class="input-group">
|
||||
<%= f.hidden_field(:search, :value => params[:search])%>
|
||||
<%= f.hidden_field(:column, :value => params[:column])%>
|
||||
<%= f.hidden_field(:direction, :value => params[:direction])%>
|
||||
|
@ -43,7 +43,11 @@
|
|||
readonly: !current_user.nil?,
|
||||
autofocus: true
|
||||
%>
|
||||
<%= f.submit (!@room_running && @anyone_can_start)? t("room.start") : t("room.join"), class: "btn btn-primary btn-sm col-sm-3 form-control join-form" %>
|
||||
<span class="input-group-append">
|
||||
<button type="submit" class="btn btn-primary btn-sm px-7 form-control join-form">
|
||||
<%= (!@room_running && @anyone_can_start) ? t("room.start") : t("room.join") %>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
<div class="col-lg-8 col-sm-12">
|
||||
<div id="room-title" class="display-3 form-inline <%= 'edit_hover_class' if current_user.main_room != @room %>" data-path="<%= update_settings_path(@room) %>">
|
||||
<% if current_user.main_room == @room %>
|
||||
<h1 contenteditable=false id="user-text" class="display-3 text-left mb-3 font-weight-400"><%= t("home_room") %></h1>
|
||||
<h1 contenteditable=false id="user-text" class="display-3 text-left mb-3 font-weight-400"><%= @room.name %></h1>
|
||||
<a class="disable-click"><i class="fas fa-home align-top home-indicator ml-2"></i></a>
|
||||
<% else %>
|
||||
<h1 contenteditable=false id="user-text" class="display-3 text-left mb-3 font-weight-400"><%= @room.name %></h1>
|
||||
|
@ -47,7 +47,7 @@
|
|||
<div class="col-lg-5 col-md-12">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<a href="#" id="copy" class="btn btn-primary btn-block mt-2">
|
||||
<a id="copy" class="btn btn-primary btn-block mt-2">
|
||||
<i class="fas fa-copy"></i>
|
||||
<%= t("copy") %>
|
||||
</a>
|
||||
|
@ -67,30 +67,34 @@
|
|||
</div>
|
||||
<div class="offset-lg-1 col-lg-3 col-sm-12 force-bottom mt-5">
|
||||
<% if @room_running %>
|
||||
<%= button_to t("room.join"), room_path(@room), class: "btn btn-primary btn-block px-7 start-button float-right" %>
|
||||
<%= button_to t("room.join"), room_path(@room), class: "btn btn-primary btn-block px-7 start-button float-right", "data-disable": "" %>
|
||||
<% else %>
|
||||
<% unless exceeds_limit %>
|
||||
<%= button_to t("room.start"), start_room_path(@room), class: "btn btn-primary btn-block px-7 start-button float-right" %>
|
||||
<%= button_to t("room.start"), start_room_path(@room), class: "btn btn-primary btn-block px-7 start-button float-right", "data-disable": "" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="room_block_container" class="row pt-7 pb-5">
|
||||
<% if current_user.rooms.length > 1 %>
|
||||
<% current_user.ordered_rooms.each do |room| %>
|
||||
<div class="col-lg-4 col-md-6 col-sm-12">
|
||||
<%= link_to current_user.main_room do %>
|
||||
<%= render "rooms/components/room_block", room: current_user.main_room %>
|
||||
<%= link_to room do %>
|
||||
<%= render "rooms/components/room_block", room: room %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% current_user.secondary_rooms.each do |room| %>
|
||||
<% end %>
|
||||
|
||||
<% if shared_access_allowed %>
|
||||
<% current_user.shared_rooms.each do |room| %>
|
||||
<div class="col-lg-4 col-md-6 col-sm-12">
|
||||
<%= link_to room do %>
|
||||
<%= render "rooms/components/room_block", room: room %>
|
||||
<%= render "rooms/components/shared_room_block", room: room %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% unless room_limit_exceeded %>
|
||||
<%= render "rooms/components/create_room_block"%>
|
||||
<% end %>
|
||||
|
@ -98,8 +102,13 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<%= render "shared/sessions", recordings: @recordings, pagy: @pagy, only_public: false, user_recordings: false, title: t("room.recordings")%>
|
||||
<%= render "shared/sessions", recordings: @recordings, pagy: @pagy, only_public: false, shared_room: @shared_room, user_recordings: false, title: t("room.recordings")%>
|
||||
|
||||
<%= render "shared/modals/delete_room_modal" %>
|
||||
|
||||
<%= render "shared/modals/create_room_modal" %>
|
||||
|
||||
<% if shared_access_allowed %>
|
||||
<%= render "shared/modals/share_room_modal" %>
|
||||
<%= render "shared/modals/remove_access_modal" %>
|
||||
<% end %>
|
|
@ -63,6 +63,10 @@
|
|||
<%= link_to admins_path, class: "dropdown-item" do %>
|
||||
<i class="dropdown-icon fas fa-user-tie mr-3"></i><%= t("header.dropdown.account_settings") %>
|
||||
<% end %>
|
||||
<% elsif highest_role.get_permission("can_manage_rooms_recordings")%>
|
||||
<%= link_to admin_rooms_path, class: "dropdown-item" do %>
|
||||
<i class="dropdown-icon fas fa-user-tie mr-3"></i><%= t("header.dropdown.account_settings") %>
|
||||
<% end %>
|
||||
<% elsif highest_role.get_permission("can_edit_site_settings") %>
|
||||
<%= link_to admin_site_settings_path, class: "dropdown-item" do %>
|
||||
<i class="dropdown-icon fas fa-user-tie mr-3"></i><%= t("header.dropdown.account_settings") %>
|
||||
|
|
|
@ -94,7 +94,7 @@
|
|||
<% failed_recordings = 0 %>
|
||||
<% recordings.each do |recording| %>
|
||||
<% begin %>
|
||||
<% if only_public %>
|
||||
<% if only_public || (defined?(shared_room) && shared_room) %>
|
||||
<%= render "shared/components/public_recording_row", recording: recording %>
|
||||
<% else %>
|
||||
<%= render "shared/components/recording_row", recording: recording %>
|
||||
|
|
|
@ -53,10 +53,10 @@
|
|||
<button class="btn btn-sm btn-secondary dropdown-toggle" data-toggle="dropdown"><i class="dropdown-icon fas fa-link px-2"></i> <%= t("recording.visibility.unlisted") %></button>
|
||||
<% end %>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
||||
<%= button_to update_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID], state: "public"), class: "dropdown-item" do %>
|
||||
<%= button_to update_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID], state: "public"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<i class="dropdown-icon fas fa-globe"></i> <%= t("recording.visibility.public") %>
|
||||
<% end %>
|
||||
<%= button_to update_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID], state: "unlisted"), class: "dropdown-item" do %>
|
||||
<%= button_to update_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID], state: "unlisted"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<i class="dropdown-icon fas fa-link"></i> <%= t("recording.visibility.unlisted") %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
@ -80,7 +80,7 @@
|
|||
<a class="dropdown-item email-link" data-pres-link="<%= recording_links %>"><i class="dropdown-icon far fa-envelope"></i> <%= t("recording.email") %></a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<% end %>
|
||||
<%= button_to delete_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID]), method: :delete, class: "dropdown-item" do %>
|
||||
<%= button_to delete_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID]), method: :delete, class: "dropdown-item", "data-disable": "" do %>
|
||||
<i class="dropdown-icon far fa-trash-alt"></i> <%= t("delete") %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
<%= t("modal.delete_account.keep") %>
|
||||
</button>
|
||||
|
||||
<%= button_to delete_location, method: :delete, id: "delete-confirm", class: "btn btn-danger my-1 btn-del-room", disabled:"" do %>
|
||||
<%= button_to delete_location, method: :delete, id: "delete-confirm", class: "btn btn-danger my-1 btn-del-room", disabled:"", "data-disable": "" do %>
|
||||
<%= t("modal.delete_account.delete") %>
|
||||
<% end %>
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
<%= t("modal.delete_room.keep") %>
|
||||
</button>
|
||||
|
||||
<%= button_to "/", method: :delete, id: "delete-confirm", class: "btn btn-danger my-1 btn-del-room" do %>
|
||||
<%= button_to "/", method: :delete, id: "delete-confirm", class: "btn btn-danger my-1 btn-del-room", "data-disable": "" do %>
|
||||
<%= t("modal.delete_room.delete") %>
|
||||
<% end %>
|
||||
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
<%
|
||||
# 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/>.
|
||||
%>
|
||||
|
||||
<div class="modal fade" id="mergeUserModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||
<div class="modal-content text-center">
|
||||
<div class="modal-body">
|
||||
<div class="card-body p-6">
|
||||
<div class="card-title">
|
||||
<h3><%= t("modal.merge_user.title") %></h3>
|
||||
</div>
|
||||
<select class="selectpicker" title="<%= t("modal.share_access.select") %>" data-live-search="true" data-virtual-scroll="true" >
|
||||
<% @user_list.each do |user| %>
|
||||
<option value="<%= { uid: user.uid, email: user.email, name: user.name }.to_json %>" data-subtext="<%= user.email %>" ><%= user.name %></option>
|
||||
<% end %>
|
||||
</select>
|
||||
<div class="mt-5 text-left row">
|
||||
<div class="list-group-item col-6 text-center">
|
||||
<label class="form-label text-primary"><%= t("modal.merge_user.from") %></label>
|
||||
<div id="merge-from"></div>
|
||||
</div>
|
||||
<i id="merge-account-arrow" class="fas fa-2x fa-arrow-circle-right text-primary"></i>
|
||||
<div class="list-group-item col-6 text-center">
|
||||
<label class="form-label text-primary"><%= t("modal.merge_user.to") %></label>
|
||||
<div id="merge-to"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
<button id="merge-save-access" class="btn btn-primary btn-block" onclick="mergeUsers()" ><%= t("modal.merge_user.save") %></button>
|
||||
<button class="btn btn-secondary text-primary btn-block" onclick="$('#mergeUserModal').modal('hide')"><%= t("modal.merge_user.cancel") %></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<p><%= t("modal.merge_user.footer") %></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,39 @@
|
|||
<%
|
||||
# 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/>.
|
||||
%>
|
||||
|
||||
<div class="modal fade" id="removeAccessModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||
<div class="modal-content text-center">
|
||||
<div class="modal-body">
|
||||
<div class="card-body p-6">
|
||||
<div class="card-title">
|
||||
<h3><%= t("modal.remove_shared.title")%></h3>
|
||||
</div>
|
||||
|
||||
<%= button_to "/", method: :delete, id: "remove-shared-confirm", class: "btn btn-danger my-1 btn-del-room" do %>
|
||||
<%= hidden_field_tag :user_id, current_user.id %>
|
||||
<%= t("modal.remove_shared.delete") %>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<p id="delete-footer">
|
||||
<%= t("modal.remove_shared.warning").html_safe %>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,45 @@
|
|||
<%
|
||||
# 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/>.
|
||||
%>
|
||||
|
||||
<div class="modal fade" id="shareRoomModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||
<div class="modal-content text-center">
|
||||
<div class="modal-body">
|
||||
<div class="card-body p-6">
|
||||
<div class="card-title">
|
||||
<h3><%= t("modal.share_access.title") %></h3>
|
||||
</div>
|
||||
<select class="selectpicker" title="<%= t("modal.share_access.select") %>" data-live-search="true" data-virtual-scroll="true" >
|
||||
<% @user_list.each do |user| %>
|
||||
<option value="<%= user.uid %>" data-subtext="<%= user.uid %>" ><%= user.name %></option>
|
||||
<% end %>
|
||||
</select>
|
||||
<div class="mt-5 text-left">
|
||||
<label class="form-label"><%= t("modal.share_access.list") %></label>
|
||||
<ul id="user-list" class="list-group">
|
||||
</ul>
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
<button id="save-access" class="btn btn-primary btn-block" onclick="saveAccessChanges()" ><%= t("modal.share_access.save") %></button>
|
||||
<button class="btn btn-secondary text-primary btn-block" onclick="$('#shareRoomModal').modal('hide')"><%= t("modal.share_access.cancel_changes") %></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<p><%= t("modal.share_access.footer") %></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -25,7 +25,7 @@
|
|||
</div>
|
||||
<% if Rails.configuration.terms && current_user && !current_user.accepted_terms %>
|
||||
<div class="btn-list text-right pt-8">
|
||||
<%= button_to t("terms.accept_existing"), terms_path, params: { accept: true }, class: "btn btn-primary btn-space" %>
|
||||
<%= button_to t("terms.accept_existing"), terms_path, params: { accept: true }, class: "btn btn-primary btn-space", "data-disable": "" %>
|
||||
</div>
|
||||
<% end %>
|
||||
</form>
|
||||
|
|
|
@ -153,13 +153,10 @@ module Greenlight
|
|||
# Default limit on number of rooms users can create
|
||||
config.number_of_rooms_default = 15
|
||||
|
||||
# Allow users to share rooms by default
|
||||
config.shared_access_default = "true"
|
||||
|
||||
# Default admin password
|
||||
config.admin_password_default = ENV['ADMIN_PASSWORD'] || 'administrator'
|
||||
|
||||
config.action_cable.log_tags = [
|
||||
->(request) { request.session['user_id'] || "no-account" },
|
||||
:action_cable,
|
||||
->(request) { request.uuid }
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -110,7 +110,9 @@ Rails.application.configure do
|
|||
# Use Lograge for logging
|
||||
config.lograge.enabled = true
|
||||
|
||||
config.lograge.ignore_actions = ["HealthCheckController#all", "ThemesController#index"]
|
||||
config.lograge.ignore_actions = ["HealthCheckController#all", "ThemesController#index",
|
||||
"ApplicationCable::Connection#connect", "WaitingChannel#subscribe",
|
||||
"ApplicationCable::Connection#disconnect", "WaitingChannel#unsubscribe"]
|
||||
|
||||
config.lograge.custom_options = lambda do |event|
|
||||
# capture some specific timing values you are interested in
|
||||
|
|
|
@ -13,4 +13,8 @@ Rails.application.config.assets.version = '1.0'
|
|||
# Precompile additional assets.
|
||||
# application.js, application.css, and all non-JS/CSS in the app/assets
|
||||
# folder are already added.
|
||||
Rails.application.config.assets.precompile += %w(pickr.min.js monolith.min.scss)
|
||||
Rails.application.config.assets.precompile += %w(_primary_theme.scss
|
||||
pickr.min.js
|
||||
monolith.min.scss
|
||||
bootstrap-select.min.js
|
||||
bootstrap-select.min.css)
|
||||
|
|
|
@ -46,12 +46,25 @@ en:
|
|||
info: Clears the stored provider cache which forces a new request for the updated info
|
||||
title: Clear Provider Cache
|
||||
button: Clear Cache
|
||||
clear_auth:
|
||||
info: Clears the current authenticator for users allowing them to sign back in using a different authentication method
|
||||
title: Clear Current Authenticator
|
||||
button: Clear Auth
|
||||
color:
|
||||
info: Changing the Regular Color will change both Lighten and Darken. Lighten and Darken can then be changed individually
|
||||
title: Primary Color
|
||||
regular: Regular
|
||||
lighten: Lighten
|
||||
darken: Darken
|
||||
log_level:
|
||||
title: Log Level
|
||||
information: Change the Log Level for the entire deployment
|
||||
debug: Debug
|
||||
info: Info
|
||||
warn: Warn
|
||||
error: Error
|
||||
fatal: Fatal
|
||||
unknown: Unknown
|
||||
recording_visibility:
|
||||
info: Set the default recording visbility for new recordings
|
||||
title: Recording Default Visibility
|
||||
|
@ -66,6 +79,9 @@ en:
|
|||
rooms:
|
||||
info: Limits the number of rooms that a user can have (including Home Room). This setting does not apply to administrators.
|
||||
title: Number of Rooms per User
|
||||
shared_access:
|
||||
info: Setting to disabled will remove the button from the Room options dropdown, preventing users from sharing rooms
|
||||
title: Allow Users to Share Rooms
|
||||
subtitle: Customize Greenlight
|
||||
title: Site Settings
|
||||
flash:
|
||||
|
@ -77,6 +93,8 @@ en:
|
|||
demoted: User has been successfully demoted
|
||||
invite: Invite successfully sent to %{email}
|
||||
invite_email_verification: Emails must be enabled in order to use this method. Please contact your system administrator.
|
||||
merge_fail: There was an issue merging the user accounts. Please check the users selected and try again
|
||||
merge_success: User accounts merged successfully
|
||||
perm_deleted: User has been permanently deleted
|
||||
promoted: User has been successfully promoted
|
||||
registration_method_updated: Registration method successfully updated
|
||||
|
@ -88,11 +106,13 @@ en:
|
|||
title: Server Recordings
|
||||
no_recordings: This server has no recordings.
|
||||
roles:
|
||||
appear_in_share_list: Include users with this role in the dropdown for sharing rooms
|
||||
can_create_rooms: Can create rooms
|
||||
delete: Delete the role
|
||||
invalid_create: There was a problem creating a new role. Please check the role values and try again
|
||||
invalid_order: There was a problem updating the priority of the role. Please check the values and try again
|
||||
invalid_update: There was a problem updating the permissions of the role. Please check the values and try again
|
||||
manage_rooms_recordings: Allow users with this role to manage server rooms and recordings
|
||||
name: Role Name
|
||||
new_role: Create a new role
|
||||
role_has_users: This role is assigned to %{user_count} accounts. Please remove all accounts from this role before deleting it.
|
||||
|
@ -106,6 +126,14 @@ en:
|
|||
colour:
|
||||
title: Role Colour
|
||||
info: Set the colour that will be associated with the role
|
||||
rooms:
|
||||
title: Server Rooms
|
||||
table:
|
||||
id: ID
|
||||
not_running: Not Running
|
||||
running: Running
|
||||
status: Status
|
||||
view: View
|
||||
title: Organization Settings
|
||||
users:
|
||||
invite: Invite User
|
||||
|
@ -228,6 +256,8 @@ en:
|
|||
body: 'To view the recording, follow the link below:'
|
||||
autogenerated: 'This e-mail is auto-generated by BigBlueButton.'
|
||||
footer: 'BigBlueButton is an open source web conferencing system. For more information on BigBlueButton, see https://bigbluebutton.org/.'
|
||||
search:
|
||||
start: Start searching...
|
||||
landing:
|
||||
about: "%{href} is a simple front-end for your BigBlueButton open-source web conferencing server. You can create your own rooms to host sessions, or join others using a short and convenient link."
|
||||
welcome: Welcome to BigBlueButton.
|
||||
|
@ -291,6 +321,7 @@ en:
|
|||
maintenance:
|
||||
window_alert: Maintenance window scheduled for %{date}
|
||||
max_concurrent: The maximum number of concurrent sessions allowed has been reached!
|
||||
merged: Merged
|
||||
modal:
|
||||
create_role:
|
||||
create: Create a new Role
|
||||
|
@ -329,6 +360,10 @@ en:
|
|||
with: Sign in with %{provider}
|
||||
forgot_password: Forgot Password?
|
||||
rename_recording:
|
||||
remove_shared:
|
||||
title: Are you sure you want to remove this room from your room list?
|
||||
delete: I'm sure, remove this room.
|
||||
warning: You will <b>not</b> be able to access this room anymore.
|
||||
room_settings:
|
||||
title: Room Settings
|
||||
update: Update Room
|
||||
|
@ -340,6 +375,20 @@ en:
|
|||
footer_text: Adjustment to your room can be done at anytime.
|
||||
rename_room:
|
||||
name_placeholder: Enter a new room name...
|
||||
share_access:
|
||||
footer: Sharing a room with a user allows them to start the room and view the room's recordings
|
||||
list: Shared With
|
||||
title: Share Room Access
|
||||
save: Save Changes
|
||||
cancel_changes: Cancel Changes
|
||||
select: Select User
|
||||
merge_user:
|
||||
cancel: Cancel
|
||||
from: Account to be Merged
|
||||
title: Merge User Accounts
|
||||
to: Primary Account
|
||||
save: Merge
|
||||
footer: The rooms of the account to be merged will be transfered over to the Primary Account's room list and then the account will be deleted.
|
||||
name_update_success: Room name successfully changed!
|
||||
no_user_email_exists: There is no existing user with the email specified. Please make sure you typed it correctly.
|
||||
omniauth_error: An error occured while authenticating with omniauth. Please try again or contact an administrator!
|
||||
|
@ -400,12 +449,14 @@ en:
|
|||
invite:
|
||||
fail: Your token is either invalid or has expired. If you believe this is a mistake, please contact your administrator.
|
||||
no_invite: You do not have an invitation to join. Please contact your administrator to receive one.
|
||||
remove: Remove
|
||||
rename: Rename
|
||||
reset_password:
|
||||
subtitle: Reset Password
|
||||
password: New Password
|
||||
confirm: New Password Confirmation
|
||||
update: Update Password
|
||||
auth_change: The authentication method has changed. Please check your email to set your password.
|
||||
roles:
|
||||
active: Active
|
||||
admin: Admin
|
||||
|
@ -418,6 +469,10 @@ en:
|
|||
create_room: Create a Room
|
||||
create_room_error: There was an error creating the room
|
||||
create_room_success: Room created successfully
|
||||
delete:
|
||||
home_room: Can't delete user's Home Room
|
||||
success: Room deleted successfully
|
||||
fail: Failed to delete room (%{error})
|
||||
enter_the_access_code: Enter the room's access code
|
||||
invalid_provider: You have entered an invalid url. Please check the url and try again.
|
||||
invited: You have been invited to join
|
||||
|
@ -426,6 +481,7 @@ en:
|
|||
last_session: Last session on %{session}
|
||||
login: Enter
|
||||
owner: Owner
|
||||
owner_banned: This room is currently unavailable
|
||||
no_room:
|
||||
description: Enter the room url or the room id for the room you want to join.
|
||||
edit_profile: Edit User Profile
|
||||
|
@ -441,6 +497,12 @@ en:
|
|||
room_limit_exceeded: You have exceeded the number of rooms allowed. Please delete %{difference} room(s) to access this room.
|
||||
sessions: Sessions
|
||||
settings: Room Settings
|
||||
share: Manage Access
|
||||
shared_by: Shared by %{email}
|
||||
remove_shared_access_success: Successfully removed shared room from your room list
|
||||
remove_shared_access_error: There was an error removing the shared room from your list
|
||||
shared_access_success: Room shared successfully
|
||||
shared_access_error: There was an error sharing the room
|
||||
start: Start
|
||||
unavailable: This room is currently unavailable due to the owner's email not being verified.
|
||||
update_settings_error: There was an error updating the room settings
|
||||
|
|
|
@ -38,6 +38,7 @@ Rails.application.routes.draw do
|
|||
|
||||
scope '/admins' do
|
||||
# Panel Tabs
|
||||
get '/rooms', to: 'admins#server_rooms', as: :admin_rooms
|
||||
get '/recordings', to: 'admins#server_recordings', as: :admin_recordings
|
||||
get '/site_settings', to: 'admins#site_settings', as: :admin_site_settings
|
||||
get '/roles', to: 'admins#roles', as: :admin_roles
|
||||
|
@ -49,11 +50,14 @@ Rails.application.routes.draw do
|
|||
post '/approve/:user_uid', to: 'admins#approve', as: :admin_approve
|
||||
get '/reset', to: 'admins#reset', as: :admin_reset
|
||||
post '/undelete', to: 'admins#undelete', as: :admin_undelete
|
||||
post '/merge/:user_uid', to: 'admins#merge_user', as: :merge_user
|
||||
# Site Settings
|
||||
post '/update_settings', to: 'admins#update_settings', as: :admin_update_settings
|
||||
post '/registration_method', to: 'admins#registration_method', as: :admin_change_registration
|
||||
post '/coloring', to: 'admins#coloring', as: :admin_coloring
|
||||
post '/clear_cache', to: 'admins#clear_cache', as: :admin_clear_cache
|
||||
post '/clear_auth', to: 'admins#clear_auth', as: :admin_clear_auth
|
||||
post '/log_level', to: 'admins#log_level', as: :admin_log_level
|
||||
# Roles
|
||||
post '/role', to: 'admins#new_role', as: :admin_new_role
|
||||
patch 'roles/order', to: 'admins#change_role_order', as: :admin_roles_order
|
||||
|
@ -109,7 +113,11 @@ Rails.application.routes.draw do
|
|||
scope '/:room_uid' do
|
||||
post '/', to: 'rooms#join'
|
||||
patch '/', to: 'rooms#update', as: :update_room
|
||||
get '/room_settings', to: 'rooms#room_settings'
|
||||
post '/update_settings', to: 'rooms#update_settings'
|
||||
post '/update_shared_access', to: 'rooms#shared_access', as: :room_shared_access
|
||||
delete '/remove_shared_access', to: 'rooms#remove_shared_access', as: :room_remove_shared_access
|
||||
get '/shared_users', to: 'rooms#shared_users', as: :room_shared_users
|
||||
post '/start', to: 'rooms#start', as: :start_room
|
||||
get '/logout', to: 'rooms#logout', as: :logout_room
|
||||
post '/login', to: 'rooms#login', as: :login_room
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MigrationProduct < ActiveRecord::Base
|
||||
self.table_name = :roles
|
||||
end
|
||||
|
||||
class SubMigrationProduct < ActiveRecord::Base
|
||||
self.table_name = :role_permissions
|
||||
end
|
||||
|
||||
class AddManageRoomRecordingsToPermissions < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
reversible do |dir|
|
||||
dir.up do
|
||||
MigrationProduct.all.each do |role|
|
||||
SubMigrationProduct.create(role_id: role.id, name: "can_manage_rooms_recordings",
|
||||
value: SubMigrationProduct.find_by(role_id: role.id, name: "can_manage_users").value, enabled: true)
|
||||
end
|
||||
end
|
||||
|
||||
dir.down do
|
||||
MigrationProduct.all.each do |role|
|
||||
SubMigrationProduct.find_by(role_id: role.id, name: "can_manage_rooms_recordings").destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CreateSharedAccesses < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :shared_accesses do |t|
|
||||
t.belongs_to :room, foreign_key: true
|
||||
t.references :user, foreign_key: true
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,27 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MigrationProduct < ActiveRecord::Base
|
||||
self.table_name = :roles
|
||||
end
|
||||
|
||||
class ChangeRolePriorityToUnique < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
reversible do |dir|
|
||||
dir.up do
|
||||
MigrationProduct.where("priority < 0").where.not(name: "pending").each do |role|
|
||||
role.decrement!(:priority)
|
||||
end
|
||||
|
||||
add_index MigrationProduct, [:priority, :provider], unique: true
|
||||
end
|
||||
|
||||
dir.down do
|
||||
remove_index MigrationProduct, [:priority, :provider]
|
||||
|
||||
MigrationProduct.where("priority < 0").where.not(name: "pending").each do |role|
|
||||
role.increment!(:priority)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
12
db/schema.rb
12
db/schema.rb
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2019_08_28_153347) do
|
||||
ActiveRecord::Schema.define(version: 2020_01_30_144841) do
|
||||
|
||||
create_table "features", force: :cascade do |t|
|
||||
t.integer "setting_id"
|
||||
|
@ -58,6 +58,7 @@ ActiveRecord::Schema.define(version: 2019_08_28_153347) do
|
|||
t.datetime "updated_at", null: false
|
||||
t.index ["name", "provider"], name: "index_roles_on_name_and_provider", unique: true
|
||||
t.index ["name"], name: "index_roles_on_name"
|
||||
t.index ["priority", "provider"], name: "index_roles_on_priority_and_provider", unique: true
|
||||
end
|
||||
|
||||
create_table "rooms", force: :cascade do |t|
|
||||
|
@ -90,6 +91,15 @@ ActiveRecord::Schema.define(version: 2019_08_28_153347) do
|
|||
t.index ["provider"], name: "index_settings_on_provider"
|
||||
end
|
||||
|
||||
create_table "shared_accesses", force: :cascade do |t|
|
||||
t.integer "room_id"
|
||||
t.integer "user_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["room_id"], name: "index_shared_accesses_on_room_id"
|
||||
t.index ["user_id"], name: "index_shared_accesses_on_user_id"
|
||||
end
|
||||
|
||||
create_table "users", force: :cascade do |t|
|
||||
t.integer "room_id"
|
||||
t.string "provider"
|
||||
|
|
|
@ -18,19 +18,18 @@ services:
|
|||
volumes:
|
||||
- ./log:/usr/src/app/log
|
||||
# When using sqlite3 as the database
|
||||
- ./db/production:/usr/src/app/db/production
|
||||
# - ./db/production:/usr/src/app/db/production
|
||||
# When using postgresql as the database
|
||||
# links:
|
||||
# - db
|
||||
# db:
|
||||
# image: postgres:9.5
|
||||
# restart: on-failure
|
||||
# ports:
|
||||
# - 127.0.0.1:5432:5432
|
||||
# volumes:
|
||||
# - ./db/production:/var/lib/postgresql/data
|
||||
# environment:
|
||||
# - PGHOST=postgres
|
||||
# - PGDATABASE=postgres
|
||||
# - PGUSER=postgres
|
||||
# - PGPASSWORD=password
|
||||
links:
|
||||
- db
|
||||
db:
|
||||
image: postgres:9.5
|
||||
restart: on-failure
|
||||
ports:
|
||||
- 127.0.0.1:5432:5432
|
||||
volumes:
|
||||
- ./db/production:/var/lib/postgresql/data
|
||||
environment:
|
||||
- POSTGRES_DB=postgres
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=password
|
||||
|
|
|
@ -91,7 +91,8 @@ a {
|
|||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
&:active {
|
||||
&:active, &.active {
|
||||
color: $primary-color !important;
|
||||
background-color: $primary-color-lighten !important;
|
||||
}
|
||||
}
|
10
sample.env
10
sample.env
|
@ -215,11 +215,11 @@ REPORT_ISSUE_URL=https://github.com/bigbluebutton/greenlight/issues/new
|
|||
#
|
||||
# For deployments based on the docker-compose script also included, the HOST should be set with the Docker container id.
|
||||
#
|
||||
# DB_ADAPTER=postgresql
|
||||
# DB_HOST=db
|
||||
# DB_NAME=greenlight_production
|
||||
# DB_USERNAME=postgres
|
||||
# DB_PASSWORD=password
|
||||
DB_ADAPTER=postgresql
|
||||
DB_HOST=db
|
||||
DB_NAME=greenlight_production
|
||||
DB_USERNAME=postgres
|
||||
DB_PASSWORD=password
|
||||
|
||||
# Specify the default registration to be used by Greenlight until an administrator sets the
|
||||
# registration method
|
||||
|
|
|
@ -27,7 +27,7 @@ describe AccountActivationsController, type: :controller do
|
|||
user = create(:user, provider: "greenlight")
|
||||
@request.session[:user_id] = user.id
|
||||
|
||||
get :show, params: { email: user.email }
|
||||
get :show, params: { uid: user.uid }
|
||||
|
||||
expect(response).to redirect_to(user.main_room)
|
||||
end
|
||||
|
@ -35,7 +35,8 @@ describe AccountActivationsController, type: :controller do
|
|||
it "renders the verify view if the user is not signed in and is not verified" do
|
||||
user = create(:user, email_verified: false, provider: "greenlight")
|
||||
|
||||
get :show, params: { email: user.email }
|
||||
user.create_activation_token
|
||||
get :show, params: { token: user.activation_token }
|
||||
|
||||
expect(response).to render_template(:show)
|
||||
end
|
||||
|
@ -45,7 +46,8 @@ describe AccountActivationsController, type: :controller do
|
|||
it "activates a user if they have the correct activation token" do
|
||||
@user = create(:user, email_verified: false, provider: "greenlight")
|
||||
|
||||
get :edit, params: { email: @user.email, token: @user.activation_token }
|
||||
@user.create_activation_token
|
||||
get :edit, params: { token: @user.activation_token }
|
||||
@user.reload
|
||||
|
||||
expect(@user.email_verified).to eq(true)
|
||||
|
@ -53,22 +55,17 @@ describe AccountActivationsController, type: :controller do
|
|||
expect(response).to redirect_to(signin_path)
|
||||
end
|
||||
|
||||
it "does not activate a user if they have the correct activation token" do
|
||||
it "should not find user when given fake activation token" do
|
||||
@user = create(:user, email_verified: false, provider: "greenlight")
|
||||
|
||||
get :edit, params: { email: @user.email, token: "fake_token" }
|
||||
@user.reload
|
||||
|
||||
expect(@user.email_verified).to eq(false)
|
||||
expect(flash[:alert]).to be_present
|
||||
expect(response).to redirect_to(root_path)
|
||||
expect { get :edit, params: { token: "fake_token" } }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
|
||||
it "does not allow the user to click the verify link again" do
|
||||
@user = create(:user, provider: "greenlight")
|
||||
|
||||
get :edit, params: { email: @user.email, token: @user.activation_token }
|
||||
|
||||
@user.create_activation_token
|
||||
get :edit, params: { token: @user.activation_token }
|
||||
expect(flash[:alert]).to be_present
|
||||
expect(response).to redirect_to(root_path)
|
||||
end
|
||||
|
@ -78,7 +75,8 @@ describe AccountActivationsController, type: :controller do
|
|||
|
||||
@user.add_role :pending
|
||||
|
||||
get :edit, params: { email: @user.email, token: @user.activation_token }
|
||||
@user.create_activation_token
|
||||
get :edit, params: { token: @user.activation_token }
|
||||
|
||||
expect(flash[:success]).to be_present
|
||||
expect(response).to redirect_to(root_path)
|
||||
|
@ -89,7 +87,8 @@ describe AccountActivationsController, type: :controller do
|
|||
it "resends the email to the current user if the resend button is clicked" do
|
||||
user = create(:user, email_verified: false, provider: "greenlight")
|
||||
|
||||
expect { get :resend, params: { email: user.email } }.to change { ActionMailer::Base.deliveries.count }.by(1)
|
||||
user.create_activation_token
|
||||
expect { get :resend, params: { token: user.activation_token } }.to change { ActionMailer::Base.deliveries.count }.by(1)
|
||||
expect(flash[:success]).to be_present
|
||||
expect(response).to redirect_to(root_path)
|
||||
end
|
||||
|
@ -97,7 +96,8 @@ describe AccountActivationsController, type: :controller do
|
|||
it "redirects a verified user to the root path" do
|
||||
user = create(:user, provider: "greenlight")
|
||||
|
||||
get :resend, params: { email: user.email }
|
||||
user.create_activation_token
|
||||
get :resend, params: { token: user.activation_token }
|
||||
|
||||
expect(flash[:alert]).to be_present
|
||||
expect(response).to redirect_to(root_path)
|
||||
|
|
|
@ -67,6 +67,8 @@ describe AdminsController, type: :controller do
|
|||
|
||||
post :ban_user, params: { user_uid: @user.uid }
|
||||
|
||||
@user.reload
|
||||
|
||||
expect(@user.has_role?(:denied)).to eq(true)
|
||||
expect(flash[:success]).to be_present
|
||||
expect(response).to redirect_to(admins_path)
|
||||
|
@ -82,6 +84,8 @@ describe AdminsController, type: :controller do
|
|||
|
||||
post :unban_user, params: { user_uid: @user.uid }
|
||||
|
||||
@user.reload
|
||||
|
||||
expect(@user.has_role?(:denied)).to eq(false)
|
||||
expect(flash[:success]).to be_present
|
||||
expect(response).to redirect_to(admins_path)
|
||||
|
@ -153,6 +157,8 @@ describe AdminsController, type: :controller do
|
|||
|
||||
post :approve, params: { user_uid: @user.uid }
|
||||
|
||||
@user.reload
|
||||
|
||||
expect(@user.has_role?(:pending)).to eq(false)
|
||||
expect(flash[:success]).to be_present
|
||||
expect(response).to redirect_to(admins_path)
|
||||
|
@ -197,6 +203,42 @@ describe AdminsController, type: :controller do
|
|||
expect(response).to redirect_to(admins_path)
|
||||
end
|
||||
end
|
||||
|
||||
context "POST #merge_user" do
|
||||
it "merges the users room to the primary account and deletes the old user" do
|
||||
@request.session[:user_id] = @admin.id
|
||||
|
||||
@user2 = create(:user)
|
||||
room1 = create(:room, owner: @user2)
|
||||
room2 = create(:room, owner: @user2)
|
||||
room3 = @user2.main_room
|
||||
|
||||
post :merge_user, params: { user_uid: @user.uid, merge: @user2.uid }
|
||||
|
||||
room1.reload
|
||||
room2.reload
|
||||
room3.reload
|
||||
|
||||
expect(User.exists?(uid: @user2.uid)).to be false
|
||||
expect(room1.name).to start_with("(Merged)")
|
||||
expect(room2.name).to start_with("(Merged)")
|
||||
expect(room3.name).to start_with("(Merged)")
|
||||
expect(room1.owner).to eq(@user)
|
||||
expect(room2.owner).to eq(@user)
|
||||
expect(room3.owner).to eq(@user)
|
||||
expect(flash[:success]).to be_present
|
||||
expect(response).to redirect_to(admins_path)
|
||||
end
|
||||
|
||||
it "does not merge if trying to merge the same user into themself" do
|
||||
@request.session[:user_id] = @admin.id
|
||||
|
||||
post :merge_user, params: { user_uid: @user.uid, merge: @user.uid }
|
||||
|
||||
expect(flash[:alert]).to be_present
|
||||
expect(response).to redirect_to(admins_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "User Design" do
|
||||
|
@ -344,6 +386,66 @@ describe AdminsController, type: :controller do
|
|||
expect(response).to redirect_to(admin_site_settings_path)
|
||||
end
|
||||
end
|
||||
|
||||
context "POST #shared_access" do
|
||||
it "changes the shared access setting" do
|
||||
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
|
||||
allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true)
|
||||
|
||||
@request.session[:user_id] = @admin.id
|
||||
|
||||
post :update_settings, params: { setting: "Shared Access", value: "false" }
|
||||
|
||||
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Shared Access")
|
||||
|
||||
expect(feature[:value]).to eq("false")
|
||||
expect(response).to redirect_to(admin_site_settings_path)
|
||||
end
|
||||
end
|
||||
|
||||
context "POST #clear_auth" do
|
||||
it "clears all users social uids if clear auth button is clicked" do
|
||||
allow_any_instance_of(ApplicationController).to receive(:set_user_domain).and_return("provider1")
|
||||
controller.instance_variable_set(:@user_domain, "provider1")
|
||||
|
||||
@request.session[:user_id] = @admin.id
|
||||
|
||||
@admin.add_role :super_admin
|
||||
@admin.update_attribute(:provider, "greenlight")
|
||||
@user2 = create(:user, provider: "provider1")
|
||||
@user3 = create(:user, provider: "provider1")
|
||||
|
||||
@user.update_attribute(:social_uid, Faker::Internet.password)
|
||||
@user2.update_attribute(:social_uid, Faker::Internet.password)
|
||||
@user3.update_attribute(:social_uid, Faker::Internet.password)
|
||||
|
||||
expect(@user.social_uid).not_to be(nil)
|
||||
expect(@user2.social_uid).not_to be(nil)
|
||||
expect(@user3.social_uid).not_to be(nil)
|
||||
|
||||
post :clear_auth
|
||||
|
||||
@user.reload
|
||||
@user2.reload
|
||||
@user3.reload
|
||||
|
||||
expect(@user.social_uid).to be(nil)
|
||||
expect(@user2.social_uid).to be(nil)
|
||||
expect(@user3.social_uid).to be(nil)
|
||||
end
|
||||
end
|
||||
|
||||
context "POST #log_level" do
|
||||
it "changes the log level" do
|
||||
@request.session[:user_id] = @admin.id
|
||||
|
||||
@admin.add_role :super_admin
|
||||
|
||||
expect(Rails.logger.level).to eq(0)
|
||||
post :log_level, params: { value: 2 }
|
||||
expect(Rails.logger.level).to eq(2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Roles" do
|
||||
|
@ -413,6 +515,7 @@ describe AdminsController, type: :controller do
|
|||
context "PATCH #change_role_order" do
|
||||
before do
|
||||
Role.create_default_roles("provider1")
|
||||
@user.roles.delete(Role.find_by(name: "user", provider: "greenlight"))
|
||||
end
|
||||
|
||||
it "should fail if user attempts to change the order of the admin or user roles" do
|
||||
|
@ -428,35 +531,9 @@ describe AdminsController, type: :controller do
|
|||
end
|
||||
|
||||
it "should fail if a user attempts to edit a role with a higher priority than their own" do
|
||||
Role.create(name: "test1", priority: 1, provider: "greenlight")
|
||||
new_role2 = Role.create(name: "test2", priority: 2, provider: "greenlight")
|
||||
new_role3 = Role.create_new_role("test3", "provider1")
|
||||
new_role2 = Role.create_new_role("test2", "provider1")
|
||||
new_role2.update_permission("can_edit_roles", "true")
|
||||
new_role3 = Role.create(name: "test3", priority: 3, provider: "greenlight")
|
||||
user_role = Role.find_by(name: "user", provider: "greenlight")
|
||||
|
||||
user_role.priority = 4
|
||||
user_role.save!
|
||||
|
||||
@user.roles << new_role2
|
||||
@user.save!
|
||||
|
||||
@request.session[:user_id] = @user.id
|
||||
|
||||
patch :change_role_order, params: { role: [new_role3.id, new_role2.id] }
|
||||
|
||||
expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_order"))
|
||||
expect(response).to redirect_to admin_roles_path
|
||||
end
|
||||
|
||||
it "should fail if a user attempts to edit a role with a higher priority than their own" do
|
||||
Role.create(name: "test1", priority: 1, provider: "greenlight")
|
||||
new_role2 = Role.create(name: "test2", priority: 2, provider: "greenlight")
|
||||
new_role2.update_permission("can_edit_roles", "true")
|
||||
new_role3 = Role.create(name: "test3", priority: 3, provider: "greenlight")
|
||||
user_role = Role.find_by(name: "user", provider: "greenlight")
|
||||
|
||||
user_role.priority = 4
|
||||
user_role.save!
|
||||
|
||||
@user.roles << new_role2
|
||||
@user.save!
|
||||
|
@ -470,10 +547,11 @@ describe AdminsController, type: :controller do
|
|||
end
|
||||
|
||||
it "should update the role order" do
|
||||
user_role = Role.find_by(name: "user", provider: "provider1")
|
||||
user_role.update_attribute(:priority, 4)
|
||||
new_role1 = Role.create(name: "test1", priority: 1, provider: "provider1")
|
||||
new_role2 = Role.create(name: "test2", priority: 2, provider: "provider1")
|
||||
new_role3 = Role.create(name: "test3", priority: 3, provider: "provider1")
|
||||
user_role = Role.find_by(name: "user", provider: "provider1")
|
||||
|
||||
@request.session[:user_id] = @admin.id
|
||||
|
||||
|
@ -494,16 +572,15 @@ describe AdminsController, type: :controller do
|
|||
context 'POST #update_role' do
|
||||
before do
|
||||
Role.create_default_roles("provider1")
|
||||
@user.roles.delete(Role.find_by(name: "user", provider: "greenlight"))
|
||||
end
|
||||
|
||||
it "should fail to update a role with a lower priority than the user" do
|
||||
user_role = Role.find_by(name: "user", provider: "provider1")
|
||||
user_role.update_attribute(:priority, 3)
|
||||
new_role1 = Role.create(name: "test1", priority: 1, provider: "provider1")
|
||||
new_role2 = Role.create(name: "test2", priority: 2, provider: "provider1")
|
||||
new_role2.update_permission("can_edit_roles", "true")
|
||||
user_role = Role.find_by(name: "user", provider: "greenlight")
|
||||
|
||||
user_role.priority = 3
|
||||
user_role.save!
|
||||
|
||||
@user.roles << new_role2
|
||||
@user.save!
|
||||
|
@ -517,7 +594,7 @@ describe AdminsController, type: :controller do
|
|||
end
|
||||
|
||||
it "should fail to update if there is a duplicate name" do
|
||||
new_role = Role.create(name: "test2", priority: 1, provider: "provider1")
|
||||
new_role = Role.create(name: "test2", priority: 2, provider: "provider1")
|
||||
new_role.update_permission("can_edit_roles", "true")
|
||||
|
||||
@request.session[:user_id] = @admin.id
|
||||
|
@ -529,7 +606,7 @@ describe AdminsController, type: :controller do
|
|||
end
|
||||
|
||||
it "should update role permisions" do
|
||||
new_role = Role.create(name: "test2", priority: 1, provider: "provider1")
|
||||
new_role = Role.create(name: "test2", priority: 2, provider: "provider1")
|
||||
new_role.update_permission("can_edit_roles", "true")
|
||||
|
||||
@request.session[:user_id] = @admin.id
|
||||
|
@ -574,7 +651,7 @@ describe AdminsController, type: :controller do
|
|||
end
|
||||
|
||||
it "should successfully delete the role" do
|
||||
new_role = Role.create(name: "test2", priority: 1, provider: "provider1")
|
||||
new_role = Role.create(name: "test2", priority: 2, provider: "provider1")
|
||||
new_role.update_permission("can_edit_roles", "true")
|
||||
|
||||
@request.session[:user_id] = @admin.id
|
||||
|
|
|
@ -115,19 +115,15 @@ describe PasswordResetsController, type: :controller do
|
|||
end
|
||||
|
||||
it "updates attributes if the password update is a success" do
|
||||
user = create(:user)
|
||||
token = "reset_token"
|
||||
|
||||
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost
|
||||
user.reset_digest = BCrypt::Password.create(token, cost: cost)
|
||||
user = create(:user, provider: "greenlight")
|
||||
user.create_reset_digest
|
||||
old_digest = user.password_digest
|
||||
|
||||
allow(controller).to receive(:valid_user).and_return(nil)
|
||||
allow(controller).to receive(:check_expiration).and_return(nil)
|
||||
controller.instance_variable_set(:@user, user)
|
||||
|
||||
params = {
|
||||
id: token,
|
||||
email: user.email,
|
||||
id: user.reset_token,
|
||||
user: {
|
||||
password: :password,
|
||||
password_confirmation: :password,
|
||||
|
@ -135,6 +131,10 @@ describe PasswordResetsController, type: :controller do
|
|||
}
|
||||
|
||||
patch :update, params: params
|
||||
|
||||
user.reload
|
||||
|
||||
expect(old_digest.eql?(user.password_digest)).to be false
|
||||
expect(response).to redirect_to(root_path)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -137,6 +137,24 @@ describe RoomsController, type: :controller do
|
|||
expect(flash[:alert]).to be_present
|
||||
expect(response).to redirect_to(root_path)
|
||||
end
|
||||
|
||||
it "redirects to root if owner is pending" do
|
||||
@request.session[:user_id] = @owner.id
|
||||
@owner.add_role :pending
|
||||
|
||||
get :show, params: { room_uid: @owner.main_room, search: :none }
|
||||
|
||||
expect(response).to redirect_to(root_path)
|
||||
end
|
||||
|
||||
it "redirects to root if owner is banned" do
|
||||
@request.session[:user_id] = @owner.id
|
||||
@owner.add_role :denied
|
||||
|
||||
get :show, params: { room_uid: @owner.main_room, search: :none }
|
||||
|
||||
expect(response).to redirect_to(root_path)
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST #create" do
|
||||
|
@ -155,13 +173,27 @@ describe RoomsController, type: :controller do
|
|||
|
||||
post :create, params: { room: room_params }
|
||||
|
||||
r = @owner.secondary_rooms.last
|
||||
r = @owner.rooms.last
|
||||
expect(r.name).to eql(name)
|
||||
expect(r.owner).to eql(@owner)
|
||||
expect(r.room_settings).to eql(json_room_settings)
|
||||
expect(response).to redirect_to(r)
|
||||
end
|
||||
|
||||
it "should respond with JSON object of the room_settings" do
|
||||
@request.session[:user_id] = @owner.id
|
||||
|
||||
@owner.main_room.update_attribute(:room_settings, { "muteOnStart": true, "requireModeratorApproval": true,
|
||||
"anyoneCanStart": true, "joinModerator": true }.to_json)
|
||||
|
||||
json_room_settings = "{\"muteOnStart\":true,\"requireModeratorApproval\":true," \
|
||||
"\"anyoneCanStart\":true,\"joinModerator\":true}"
|
||||
|
||||
get :room_settings, params: { room_uid: @owner.main_room }, format: :json
|
||||
|
||||
expect(JSON.parse(response.body)).to eql(json_room_settings)
|
||||
end
|
||||
|
||||
it "should redirect to root if not logged in" do
|
||||
expect do
|
||||
name = Faker::Games::Pokemon.name
|
||||
|
@ -214,7 +246,6 @@ describe RoomsController, type: :controller do
|
|||
|
||||
it "should use join name if user is not logged in and meeting running" do
|
||||
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:is_meeting_running?).and_return(true)
|
||||
|
||||
post :join, params: { room_uid: @room, join_name: "Join Name" }
|
||||
|
||||
expect(response).to redirect_to(join_path(@owner.main_room, "Join Name", {}))
|
||||
|
@ -310,6 +341,24 @@ describe RoomsController, type: :controller do
|
|||
expect(flash[:alert]).to be_present
|
||||
expect(response).to redirect_to(root_path)
|
||||
end
|
||||
|
||||
it "redirects to root if owner is pending" do
|
||||
@request.session[:user_id] = @owner.id
|
||||
@owner.add_role :pending
|
||||
|
||||
post :join, params: { room_uid: @room }
|
||||
|
||||
expect(response).to redirect_to(root_path)
|
||||
end
|
||||
|
||||
it "redirects to root if owner is banned" do
|
||||
@request.session[:user_id] = @owner.id
|
||||
@owner.add_role :denied
|
||||
|
||||
post :join, params: { room_uid: @room }
|
||||
|
||||
expect(response).to redirect_to(root_path)
|
||||
end
|
||||
end
|
||||
|
||||
describe "DELETE #destroy" do
|
||||
|
@ -342,6 +391,45 @@ describe RoomsController, type: :controller do
|
|||
delete :destroy, params: { room_uid: @user.main_room }
|
||||
end.to change { Room.count }.by(0)
|
||||
end
|
||||
|
||||
it "allows admin to delete room" do
|
||||
@admin = create(:user)
|
||||
@admin.add_role :admin
|
||||
@request.session[:user_id] = @admin.id
|
||||
|
||||
expect do
|
||||
delete :destroy, params: { room_uid: @secondary_room }
|
||||
end.to change { Room.count }.by(-1)
|
||||
|
||||
expect(response).to redirect_to(@admin.main_room)
|
||||
end
|
||||
|
||||
it "does not allow admin to delete a users home room" do
|
||||
@admin = create(:user)
|
||||
@admin.add_role :admin
|
||||
@request.session[:user_id] = @admin.id
|
||||
|
||||
expect do
|
||||
delete :destroy, params: { room_uid: @user.main_room }
|
||||
end.to change { Room.count }.by(0)
|
||||
|
||||
expect(flash[:alert]).to be_present
|
||||
expect(response).to redirect_to(@admin.main_room)
|
||||
end
|
||||
|
||||
it "does not allow an admin from a different context to delete room" do
|
||||
allow_any_instance_of(User).to receive(:admin_of?).and_return(false)
|
||||
|
||||
@admin = create(:user)
|
||||
@admin.add_role :admin
|
||||
@request.session[:user_id] = @admin.id
|
||||
|
||||
expect do
|
||||
delete :destroy, params: { room_uid: @secondary_room }
|
||||
end.to change { Room.count }.by(0)
|
||||
|
||||
expect(response).to redirect_to(root_path)
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST #start" do
|
||||
|
@ -374,6 +462,27 @@ describe RoomsController, type: :controller do
|
|||
|
||||
expect(response).to redirect_to(root_path)
|
||||
end
|
||||
|
||||
it "redirects to join path if admin" do
|
||||
@admin = create(:user)
|
||||
@admin.add_role :admin
|
||||
@request.session[:user_id] = @admin.id
|
||||
|
||||
post :start, params: { room_uid: @user.main_room }
|
||||
|
||||
expect(response).to redirect_to(join_path(@user.main_room, @admin.name, { user_is_moderator: true }, @admin.uid))
|
||||
end
|
||||
|
||||
it "redirects to root path if not admin of current user" do
|
||||
allow_any_instance_of(User).to receive(:admin_of?).and_return(false)
|
||||
@admin = create(:user)
|
||||
@admin.add_role :admin
|
||||
@request.session[:user_id] = @admin.id
|
||||
|
||||
post :start, params: { room_uid: @user.main_room }
|
||||
|
||||
expect(response).to redirect_to(root_path)
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST #update_settings" do
|
||||
|
@ -413,6 +522,35 @@ describe RoomsController, type: :controller do
|
|||
|
||||
expect(response).to redirect_to(@secondary_room)
|
||||
end
|
||||
|
||||
it "allows admin to update room settings" do
|
||||
@admin = create(:user)
|
||||
@admin.add_role :admin
|
||||
@request.session[:user_id] = @admin.id
|
||||
|
||||
room_params = { "mute_on_join": "1", "name": @secondary_room.name }
|
||||
formatted_room_params = "{\"muteOnStart\":true,\"requireModeratorApproval\":false," \
|
||||
"\"anyoneCanStart\":false,\"joinModerator\":false}" # JSON string format
|
||||
|
||||
expect { post :update_settings, params: { room_uid: @secondary_room.uid, room: room_params } }
|
||||
.to change { @secondary_room.reload.room_settings }
|
||||
.from(@secondary_room.room_settings).to(formatted_room_params)
|
||||
expect(response).to redirect_to(@secondary_room)
|
||||
end
|
||||
|
||||
it "does not allow admins from a different context to update room settings" do
|
||||
allow_any_instance_of(User).to receive(:admin_of?).and_return(false)
|
||||
@admin = create(:user)
|
||||
@admin.add_role :admin
|
||||
@request.session[:user_id] = @admin.id
|
||||
|
||||
room_params = { "mute_on_join": "1", "name": @secondary_room.name }
|
||||
|
||||
expect { post :update_settings, params: { room_uid: @secondary_room.uid, room: room_params } }
|
||||
.not_to change { @secondary_room.reload.room_settings }
|
||||
|
||||
expect(response).to redirect_to(root_path)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET #logout" do
|
||||
|
@ -480,4 +618,122 @@ describe RoomsController, type: :controller do
|
|||
expect(response).to redirect_to room_path(@user1.main_room)
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST #shared_access" do
|
||||
before do
|
||||
@user = create(:user)
|
||||
@room = create(:room, owner: @user)
|
||||
@user1 = create(:user)
|
||||
allow(Rails.configuration).to receive(:shared_access_default).and_return("true")
|
||||
end
|
||||
|
||||
it "shares a room with another user" do
|
||||
@request.session[:user_id] = @user.id
|
||||
|
||||
post :shared_access, params: { room_uid: @room.uid, add: [@user1.uid] }
|
||||
|
||||
expect(SharedAccess.exists?(room_id: @room.id, user_id: @user1.id)).to be true
|
||||
expect(flash[:success]).to be_present
|
||||
expect(response).to redirect_to room_path(@room)
|
||||
end
|
||||
|
||||
it "allows a user to view a shared room and start it" do
|
||||
@request.session[:user_id] = @user.id
|
||||
post :shared_access, params: { room_uid: @room.uid, add: [@user1.uid] }
|
||||
|
||||
allow(controller).to receive(:current_user).and_return(@user1)
|
||||
get :show, params: { room_uid: @room.uid }
|
||||
expect(response).to render_template(:show)
|
||||
end
|
||||
|
||||
it "unshares a room from the user if they are removed from the list" do
|
||||
SharedAccess.create(room_id: @room.id, user_id: @user1.id)
|
||||
expect(SharedAccess.exists?(room_id: @room.id, user_id: @user1.id)).to be true
|
||||
|
||||
@request.session[:user_id] = @user.id
|
||||
post :shared_access, params: { room_uid: @room.uid, add: [] }
|
||||
|
||||
expect(SharedAccess.exists?(room_id: @room.id, user_id: @user1.id)).to be false
|
||||
expect(flash[:success]).to be_present
|
||||
expect(response).to redirect_to room_path(@room)
|
||||
end
|
||||
|
||||
it "doesn't allow a user to share a room they don't own" do
|
||||
@request.session[:user_id] = @user1.id
|
||||
|
||||
post :shared_access, params: { room_uid: @room.uid, add: [@user1.uid] }
|
||||
|
||||
expect(SharedAccess.exists?(room_id: @room.id, user_id: @user1.id)).to be false
|
||||
expect(response).to redirect_to root_path
|
||||
end
|
||||
|
||||
it "disables shared room functionality if the site setting is disabled" do
|
||||
allow_any_instance_of(Setting).to receive(:get_value).and_return("false")
|
||||
|
||||
@request.session[:user_id] = @user.id
|
||||
post :shared_access, params: { room_uid: @room.uid, add: [@user1.uid] }
|
||||
expect(SharedAccess.exists?(room_id: @room.id, user_id: @user1.id)).to be true
|
||||
|
||||
allow(controller).to receive(:current_user).and_return(@user1)
|
||||
get :show, params: { room_uid: @room.uid }
|
||||
expect(response).to render_template(:join)
|
||||
end
|
||||
|
||||
it "allows admins to update room access" do
|
||||
@admin = create(:user)
|
||||
@admin.add_role :admin
|
||||
@request.session[:user_id] = @admin.id
|
||||
|
||||
post :shared_access, params: { room_uid: @room.uid, add: [@user1.uid] }
|
||||
|
||||
expect(SharedAccess.exists?(room_id: @room.id, user_id: @user1.id)).to be true
|
||||
expect(flash[:success]).to be_present
|
||||
expect(response).to redirect_to room_path(@room)
|
||||
end
|
||||
|
||||
it "redirects to root path if not admin of current user" do
|
||||
allow_any_instance_of(User).to receive(:admin_of?).and_return(false)
|
||||
@admin = create(:user)
|
||||
@admin.add_role :admin
|
||||
@request.session[:user_id] = @admin.id
|
||||
|
||||
post :shared_access, params: { room_uid: @room.uid, add: [] }
|
||||
|
||||
expect(response).to redirect_to(root_path)
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST #remove_shared_access" do
|
||||
before do
|
||||
@user = create(:user)
|
||||
@room = create(:room, owner: @user)
|
||||
@user1 = create(:user)
|
||||
allow(Rails.configuration).to receive(:shared_access_default).and_return("true")
|
||||
end
|
||||
|
||||
it "unshares a room from the user if they click the remove button" do
|
||||
SharedAccess.create(room_id: @room.id, user_id: @user1.id)
|
||||
expect(SharedAccess.exists?(room_id: @room.id, user_id: @user1.id)).to be true
|
||||
|
||||
@request.session[:user_id] = @user1.id
|
||||
post :remove_shared_access, params: { room_uid: @room.uid, user_id: @user1.id }
|
||||
|
||||
expect(SharedAccess.exists?(room_id: @room.id, user_id: @user1.id)).to be false
|
||||
expect(flash[:success]).to be_present
|
||||
expect(response).to redirect_to @user1.main_room
|
||||
end
|
||||
|
||||
it "doesn't allow some random user to change share access" do
|
||||
@user2 = create(:user)
|
||||
|
||||
SharedAccess.create(room_id: @room.id, user_id: @user1.id)
|
||||
expect(SharedAccess.exists?(room_id: @room.id, user_id: @user1.id)).to be true
|
||||
|
||||
@request.session[:user_id] = @user2.id
|
||||
post :remove_shared_access, params: { room_uid: @room.uid, user_id: @user1.id }
|
||||
|
||||
expect(SharedAccess.exists?(room_id: @room.id, user_id: @user1.id)).to be true
|
||||
expect(response).to redirect_to root_path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -88,7 +88,11 @@ describe SessionsController, type: :controller do
|
|||
end
|
||||
|
||||
describe "POST #create" do
|
||||
before { allow(Rails.configuration).to receive(:enable_email_verification).and_return(true) }
|
||||
before do
|
||||
allow(Rails.configuration).to receive(:enable_email_verification).and_return(true)
|
||||
allow_any_instance_of(SessionsController).to receive(:auth_changed_to_local?).and_return(false)
|
||||
end
|
||||
|
||||
before(:each) do
|
||||
@user1 = create(:user, provider: 'greenlight', password: 'example', password_confirmation: 'example')
|
||||
@user2 = create(:user, password: 'example', password_confirmation: "example")
|
||||
|
@ -139,7 +143,8 @@ describe SessionsController, type: :controller do
|
|||
}
|
||||
|
||||
expect(@request.session[:user_id]).to be_nil
|
||||
expect(response).to redirect_to(account_activation_path(email: @user3.email))
|
||||
# Expect to redirect to activation path since token is not known here
|
||||
expect(response.location.start_with?(account_activation_url(token: ""))).to be true
|
||||
end
|
||||
|
||||
it "should not login user if account is deleted" do
|
||||
|
@ -251,6 +256,22 @@ describe SessionsController, type: :controller do
|
|||
expect(@user1.rooms.find { |r| r.name == "Old Home Room" }).to_not be_nil
|
||||
expect(@user1.rooms.find { |r| r.name == "Test" }).to_not be_nil
|
||||
end
|
||||
|
||||
it "sends the user a reset password email if the authentication method is changing to local" do
|
||||
allow_any_instance_of(SessionsController).to receive(:auth_changed_to_local?).and_return(true)
|
||||
email = Faker::Internet.email
|
||||
|
||||
create(:user, email: email, provider: "greenlight", social_uid: "google-user")
|
||||
|
||||
expect {
|
||||
post :create, params: {
|
||||
session: {
|
||||
email: email,
|
||||
password: 'example',
|
||||
},
|
||||
}
|
||||
}.to change { ActionMailer::Base.deliveries.count }.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET/POST #omniauth" do
|
||||
|
@ -428,6 +449,66 @@ describe SessionsController, type: :controller do
|
|||
|
||||
expect(response).to redirect_to(root_path)
|
||||
end
|
||||
|
||||
it "switches a social account to a different social account if the authentication method changed" do
|
||||
request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:bn_launcher]
|
||||
get :omniauth, params: { provider: 'bn_launcher' }
|
||||
|
||||
u = User.find_by(social_uid: "bn-launcher-user")
|
||||
u.social_uid = nil
|
||||
users_old_uid = u.uid
|
||||
u.save!
|
||||
|
||||
new_user = OmniAuth::AuthHash.new(
|
||||
provider: "bn_launcher",
|
||||
uid: "bn-launcher-user-new",
|
||||
info: {
|
||||
email: "user@google.com",
|
||||
name: "Office User",
|
||||
nickname: "googleuser",
|
||||
image: "touch.png",
|
||||
customer: 'customer1',
|
||||
}
|
||||
)
|
||||
|
||||
allow_any_instance_of(SessionsController).to receive(:auth_changed_to_social?).and_return(true)
|
||||
allow_any_instance_of(ApplicationController).to receive(:set_user_domain).and_return("customer1")
|
||||
controller.instance_variable_set(:@user_domain, "customer1")
|
||||
|
||||
request.env["omniauth.auth"] = new_user
|
||||
get :omniauth, params: { provider: 'bn_launcher' }
|
||||
|
||||
new_u = User.find_by(social_uid: "bn-launcher-user-new")
|
||||
expect(users_old_uid).to eq(new_u.uid)
|
||||
end
|
||||
|
||||
it "switches a local account to a different social account if the authentication method changed" do
|
||||
email = Faker::Internet.email
|
||||
user = create(:user, email: email, provider: "customer1")
|
||||
users_old_uid = user.uid
|
||||
|
||||
new_user = OmniAuth::AuthHash.new(
|
||||
provider: "bn_launcher",
|
||||
uid: "bn-launcher-user-new",
|
||||
info: {
|
||||
email: email,
|
||||
name: "Office User",
|
||||
nickname: "googleuser",
|
||||
image: "touch.png",
|
||||
customer: 'customer1',
|
||||
}
|
||||
)
|
||||
|
||||
allow_any_instance_of(SessionsController).to receive(:auth_changed_to_social?).and_return(true)
|
||||
allow_any_instance_of(ApplicationController).to receive(:set_user_domain).and_return("customer1")
|
||||
controller.instance_variable_set(:@user_domain, "customer1")
|
||||
|
||||
request.env["omniauth.auth"] = new_user
|
||||
get :omniauth, params: { provider: 'bn_launcher' }
|
||||
|
||||
new_u = User.find_by(social_uid: "bn-launcher-user-new")
|
||||
expect(users_old_uid).to eq(new_u.uid)
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST #ldap" do
|
||||
|
@ -452,6 +533,51 @@ describe SessionsController, type: :controller do
|
|||
expect(@request.session[:user_id]).to eql(u.id)
|
||||
end
|
||||
|
||||
it "should defaults the users image to blank if actual image is provided" do
|
||||
entry = Net::LDAP::Entry.new("cn=Test User,ou=people,dc=planetexpress,dc=com")
|
||||
entry[:cn] = "Test User"
|
||||
entry[:givenName] = "Test"
|
||||
entry[:sn] = "User"
|
||||
entry[:mail] = "test@example.com"
|
||||
entry[:jpegPhoto] = "\FF\F8" # Pretend image
|
||||
allow_any_instance_of(Net::LDAP).to receive(:bind_as).and_return([entry])
|
||||
|
||||
post :ldap, params: {
|
||||
session: {
|
||||
user: "test",
|
||||
password: 'password',
|
||||
},
|
||||
}
|
||||
|
||||
u = User.last
|
||||
expect(u.provider).to eql("ldap")
|
||||
expect(u.image).to eql("")
|
||||
expect(@request.session[:user_id]).to eql(u.id)
|
||||
end
|
||||
|
||||
it "uses the users image if a url is provided" do
|
||||
image = Faker::Internet.url
|
||||
entry = Net::LDAP::Entry.new("cn=Test User,ou=people,dc=planetexpress,dc=com")
|
||||
entry[:cn] = "Test User"
|
||||
entry[:givenName] = "Test"
|
||||
entry[:sn] = "User"
|
||||
entry[:mail] = "test@example.com"
|
||||
entry[:jpegPhoto] = image
|
||||
allow_any_instance_of(Net::LDAP).to receive(:bind_as).and_return([entry])
|
||||
|
||||
post :ldap, params: {
|
||||
session: {
|
||||
user: "test",
|
||||
password: 'password',
|
||||
},
|
||||
}
|
||||
|
||||
u = User.last
|
||||
expect(u.provider).to eql("ldap")
|
||||
expect(u.image).to eql(image)
|
||||
expect(@request.session[:user_id]).to eql(u.id)
|
||||
end
|
||||
|
||||
it "should redirect to signin on invalid credentials" do
|
||||
allow_any_instance_of(Net::LDAP).to receive(:bind_as).and_return(false)
|
||||
|
||||
|
|
|
@ -312,7 +312,7 @@ describe UsersController, type: :controller do
|
|||
|
||||
user_role.save!
|
||||
|
||||
tmp_role = Role.create(name: "test", priority: -2, provider: "greenlight")
|
||||
tmp_role = Role.create(name: "test", priority: -4, provider: "greenlight")
|
||||
|
||||
params = random_valid_user_params
|
||||
patch :update, params: params.merge!(user_uid: user, user: { role_ids: tmp_role.id.to_s })
|
||||
|
@ -354,14 +354,16 @@ describe UsersController, type: :controller do
|
|||
|
||||
@request.session[:user_id] = admin.id
|
||||
|
||||
tmp_role1 = Role.create(name: "test1", priority: 1, provider: "greenlight")
|
||||
tmp_role1 = Role.create(name: "test1", priority: 2, provider: "greenlight")
|
||||
tmp_role1.update_permission("send_promoted_email", "true")
|
||||
tmp_role2 = Role.create(name: "test2", priority: 2, provider: "greenlight")
|
||||
tmp_role2 = Role.create(name: "test2", priority: 3, provider: "greenlight")
|
||||
|
||||
params = random_valid_user_params
|
||||
params = params.merge!(user_uid: user, user: { role_ids: "#{tmp_role1.id} #{tmp_role2.id}" })
|
||||
|
||||
expect { patch :update, params: params }.to change { ActionMailer::Base.deliveries.count }.by(1)
|
||||
|
||||
user.reload
|
||||
expect(user.roles.count).to eq(2)
|
||||
expect(user.highest_priority_role.name).to eq("test1")
|
||||
expect(response).to redirect_to(admins_path)
|
||||
|
@ -375,7 +377,7 @@ describe UsersController, type: :controller do
|
|||
|
||||
admin.add_role :admin
|
||||
|
||||
tmp_role1 = Role.create(name: "test1", priority: 1, provider: "greenlight")
|
||||
tmp_role1 = Role.create(name: "test1", priority: 2, provider: "greenlight")
|
||||
tmp_role1.update_permission("send_demoted_email", "true")
|
||||
user.roles << tmp_role1
|
||||
user.save!
|
||||
|
|
|
@ -112,6 +112,28 @@ describe User, type: :model do
|
|||
end
|
||||
end
|
||||
|
||||
context '#ordered_rooms' do
|
||||
it 'correctly orders the users rooms' do
|
||||
user = create(:user)
|
||||
room1 = create(:room, owner: user)
|
||||
room2 = create(:room, owner: user)
|
||||
room3 = create(:room, owner: user)
|
||||
room4 = create(:room, owner: user)
|
||||
|
||||
room4.update_attributes(sessions: 1, last_session: "2020-02-24 19:52:57")
|
||||
room3.update_attributes(sessions: 1, last_session: "2020-01-25 19:52:57")
|
||||
room2.update_attributes(sessions: 1, last_session: "2019-09-05 19:52:57")
|
||||
room1.update_attributes(sessions: 1, last_session: "2015-02-24 19:52:57")
|
||||
|
||||
rooms = user.ordered_rooms
|
||||
expect(rooms[0]).to eq(user.main_room)
|
||||
expect(rooms[1]).to eq(room4)
|
||||
expect(rooms[2]).to eq(room3)
|
||||
expect(rooms[3]).to eq(room2)
|
||||
expect(rooms[4]).to eq(room1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'password reset' do
|
||||
it 'creates token and respective reset digest' do
|
||||
user = create(:user)
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue