Merge v2.6-alpha (#1672)

* GRN2-xx: Switch the relation between users and roles to make queries cleaner and faster (#1299)

* First steps

* Fixes in account creation flow

* Fixed most testcases

* more test fixes

* Fixed more test cases

* Passing tests and rubocop

* Added rake task to remove rooms

* Adding translation (#1510)

* Update _account.html.erb

* Update en.yml

* Fix "for" attribute for label elements (#1488)

Co-authored-by: Ahmad Farhat <ahmad.af.farhat@gmail.com>

* Fix some issues reported by LGTM (#1478)

* Declare local JavaScript variables (reported by LGTM)

Signed-off-by: Stefan Weil <sw@weilnetz.de>

* Remove unused local JavaScript variable (reported by LGTM)

Signed-off-by: Stefan Weil <sw@weilnetz.de>

* Puma Worker Configuration (#1332)

We noticed that the current default settings perform very poorly under
load. We managed to literally take down Greenlight during a larger event
when people where accessing the landing page for rooms and when doing
some tests, I was more or less able to DoS Greenlight on my own.

This patch adds a default worker configuration which significantly
improves the situation. The small, 4 core machine I was testing on could
handle about thrice the amount of requests.

While the new default configuration should be reasonably well suited for
most deployments, this patch further allows users to easily configure
the worker pool on their own in the environment file.

* Made name and email readonly for no greenlight accounts (#1534)

* Fixed hardcoded string (#1532)

* fixed spelling error that was bugging me :) - sep a rat e (#1535)

Co-authored-by: Dave Lane <dave@oerfoundation.org>

* Improve Server Rooms View (#1524)

* Order rooms by status

* Cleaned up order function

* Now displays Started/Created/Ended

* Added participant count to rooms list

* Fix rake task user:create so that users can be created when terms are present (#1565)

* Changed user create task to always accept terms

* clean up

* More secure room ID (#1451)

* Legal and privpolicy link (#1421)

* add customizable Links to Imprint and Privacy Policy

* fix copy&paste error in spec

* replace "imprint" with "legal" since that is the correct term

* remove german translation of new strings, transifex will take care of them later

* GRN2-295:Refactored update profile and update password (#1591)

* Refactored update profile and update password

* Relowered rubocop settings

* Fixed email sending when not supposed to (#1592)

* Design changes for small screens  (#1580)

* now rap for pagination

* Update _subtitle.html.erb

* Update _rooms.html.erb

* Update _recordings.html.erb

* Update _rooms.html.erb

* Update _users.html.erb

* Update cant_create_rooms.html.erb

* Update room.js

* Update edit.html.erb

* Update new.html.erb

* Update cant_create_rooms.html.erb

* Update _sessions.html.erb

* Update _account.html.erb

* Make Greenlight work with Ruby 2.7 (#1560)

Greenlight's failure to start up with Ruby 2.7 seems to be caused by [an
issue in bootsnap](https://github.com/Shopify/bootsnap/issues/258).
Updating that library makes Greenlight work again.

However, there are still a lot of deprecation warnings. But that's
something to deal with separately.

This fixes #1558

* use email input for sign in (#1199)

* use email input for sign in

* use email input for registration

* use email input for invitation

* use email input for account settings

Co-authored-by: Ahmad Farhat <ahmad.af.farhat@gmail.com>

* Fix Gemfile (#1593)

* Fixed invalid token for password reset (#1632)

* HELP_URL env variable now works as expected (#1636)

* #1372 Fix for long Text in Table + Remove invalid HTML Tag (#1403)

* removed invalid HTML Tag

* removed invalid HTML Tag

* Update _public_recording_row.html.erb

* Update _recording_row.html.erb

* Update _server_recording_row.html.erb

form-inline replaced by own css

* Update _server_room_row.html.erb

* Update _public_recording_row.html.erb

* Update _recording_row.html.erb

* Update _public_recording_row.html.erb

* Update _recordings.html.erb

* Update _rooms.html.erb

* Update main.scss

fix for long text

* Update main.scss

* Update _public_recording_row.html.erb

* Added more validation on profile image (#1644)

* Users who can't create rooms but have shared rooms now have a different view (#1649)

* Revert "Puma Worker Configuration (#1332)" (#1667)

This reverts commit 78ed8d74601b613af3fd96ccf75a6bada24deddd.

* Removed html safe from all flash messages (#1668)

* Remove hardcoded guest=true if require mod approval is set (#1669)

* Change random generation for room uid (#1670)

* GRN2-290: Update gems and update to Rails 5.2.4.3 (#1671)

* Update gems and update to Rails 5.2.4.3

* remove gemfile error

Co-authored-by: MrKeksi <mrkeksi@users.noreply.github.com>
Co-authored-by: Florian Weber <fnwbr@users.noreply.github.com>
Co-authored-by: Stefan Weil <sw@weilnetz.de>
Co-authored-by: Lars Kiesow <lkiesow@uos.de>
Co-authored-by: Dave Lane <dave@lane.net.nz>
Co-authored-by: Dave Lane <dave@oerfoundation.org>
Co-authored-by: Henning <hng@users.noreply.github.com>
Co-authored-by: Marcel Waldvogel <marcel@waldvogel.family>
Co-authored-by: Christian Marg <marg@rz.tu-clausthal.de>
Co-authored-by: Klaus <klaus@jsxc.org>
This commit is contained in:
Ahmad Farhat 2020-05-26 17:37:23 -04:00 committed by GitHub
parent 7411eba8e0
commit 51824ad84b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
76 changed files with 903 additions and 735 deletions

View File

@ -73,11 +73,11 @@ Style/RescueStandardError:
Enabled: false
# Align the elements of a hash literal if they span more than one line.
Layout/AlignHash:
Layout/HashAlignment:
Enabled: false
# Align the parameters of a method definition if they span more than one line.
Layout/AlignParameters:
Layout/ParameterAlignment:
Enabled: false
# Align ends corresponding to defs correctly.
@ -93,7 +93,7 @@ Layout/EmptyLineAfterGuardClause:
Enabled: false
# Align the arguments of a method call if they span more than one line.
Layout/AlignArguments:
Layout/ArgumentAlignment:
Enabled: false
#
@ -120,7 +120,7 @@ Metrics/ClassLength:
Enabled: false
# Limit lines to 80 characters.
Metrics/LineLength:
Layout/LineLength:
Max: 130
# Avoid methods longer than 10 lines of code.
@ -141,5 +141,39 @@ Metrics/CyclomaticComplexity:
Max: 17
# Checks for method parameter names that contain capital letters, end in numbers, or do not meet a minimal length.
Naming/UncommunicativeMethodParamName:
Naming/MethodParameterName:
Enabled: false
Lint/LiteralInInterpolation:
Enabled: false
Layout/EmptyLinesAroundAttributeAccessor:
Enabled: true
Layout/SpaceAroundMethodCallOperator:
Enabled: true
Lint/DeprecatedOpenSSLConstant:
Enabled: true
Lint/RaiseException:
Enabled: true
Lint/StructNewOverride:
Enabled: true
Style/ExponentialNotation:
Enabled: true
Style/HashEachMethods:
Enabled: true
Style/HashTransformKeys:
Enabled: true
Style/HashTransformValues:
Enabled: true
Style/SlicingWithRange:
Enabled: true

View File

@ -8,7 +8,7 @@ git_source(:github) do |repo_name|
end
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.2.3'
gem 'rails', '~> 5.2.4.3'
# Use Puma as the app server
gem 'puma', '~> 3.12'
@ -44,6 +44,8 @@ gem 'bcrypt', '~> 3.1.7'
# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.1.0', require: false
gem 'sprockets', '< 4.0.0'
# Authentication.
gem 'omniauth'
gem 'omniauth-twitter'

View File

@ -9,54 +9,54 @@ GIT
GEM
remote: https://rubygems.org/
specs:
action-cable-testing (0.5.0)
action-cable-testing (0.6.1)
actioncable (>= 5.0)
actioncable (5.2.3)
actionpack (= 5.2.3)
actioncable (5.2.4.3)
actionpack (= 5.2.4.3)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailer (5.2.3)
actionpack (= 5.2.3)
actionview (= 5.2.3)
activejob (= 5.2.3)
actionmailer (5.2.4.3)
actionpack (= 5.2.4.3)
actionview (= 5.2.4.3)
activejob (= 5.2.4.3)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
actionpack (5.2.3)
actionview (= 5.2.3)
activesupport (= 5.2.3)
rack (~> 2.0)
actionpack (5.2.4.3)
actionview (= 5.2.4.3)
activesupport (= 5.2.4.3)
rack (~> 2.0, >= 2.0.8)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (5.2.3)
activesupport (= 5.2.3)
actionview (5.2.4.3)
activesupport (= 5.2.4.3)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.3)
activejob (5.2.3)
activesupport (= 5.2.3)
activejob (5.2.4.3)
activesupport (= 5.2.4.3)
globalid (>= 0.3.6)
activemodel (5.2.3)
activesupport (= 5.2.3)
activerecord (5.2.3)
activemodel (= 5.2.3)
activesupport (= 5.2.3)
activemodel (5.2.4.3)
activesupport (= 5.2.4.3)
activerecord (5.2.4.3)
activemodel (= 5.2.4.3)
activesupport (= 5.2.4.3)
arel (>= 9.0)
activestorage (5.2.3)
actionpack (= 5.2.3)
activerecord (= 5.2.3)
activestorage (5.2.4.3)
actionpack (= 5.2.4.3)
activerecord (= 5.2.4.3)
marcel (~> 0.3.1)
activesupport (5.2.3)
activesupport (5.2.4.3)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
arel (9.0.0)
ast (2.4.0)
autoprefixer-rails (9.6.1)
autoprefixer-rails (9.7.6)
execjs
bcrypt (3.1.13)
bigbluebutton-api-ruby (1.7.0)
@ -64,14 +64,14 @@ GEM
bindex (0.8.1)
bn-ldap-authentication (0.1.2)
net-ldap (~> 0)
bootsnap (1.4.4)
bootsnap (1.4.6)
msgpack (~> 1.0)
bootstrap (4.3.1)
autoprefixer-rails (>= 9.1.0)
popper_js (>= 1.14.3, < 2)
sassc-rails (>= 2.0.0)
builder (3.2.3)
byebug (11.0.1)
builder (3.2.4)
byebug (11.1.3)
cancancan (2.3.0)
coffee-rails (4.2.2)
coffee-script (>= 2.2.0)
@ -80,7 +80,7 @@ GEM
coffee-script-source
execjs
coffee-script-source (1.12.2)
concurrent-ruby (1.1.5)
concurrent-ruby (1.1.6)
coveralls (0.8.23)
json (>= 1.8, < 3)
simplecov (~> 0.16.1)
@ -89,46 +89,45 @@ GEM
tins (~> 1.6)
crack (0.4.3)
safe_yaml (~> 1.0.0)
crass (1.0.5)
crass (1.0.6)
diff-lcs (1.3)
docile (1.3.2)
dotenv (2.7.4)
dotenv-rails (2.7.4)
dotenv (= 2.7.4)
dotenv (2.7.5)
dotenv-rails (2.7.5)
dotenv (= 2.7.5)
railties (>= 3.2, < 6.1)
erubi (1.8.0)
erubi (1.9.0)
execjs (2.7.0)
factory_bot (5.0.2)
factory_bot (5.2.0)
activesupport (>= 4.2.0)
factory_bot_rails (5.0.2)
factory_bot (~> 5.0.2)
factory_bot_rails (5.2.0)
factory_bot (~> 5.2.0)
railties (>= 4.2.0)
faker (1.9.6)
i18n (>= 0.7)
faraday (0.15.4)
faker (2.11.0)
i18n (>= 1.6, < 2)
faraday (1.0.1)
multipart-post (>= 1.2, < 3)
ffi (1.11.1)
ffi (1.12.2)
font-awesome-sass (5.9.0)
sassc (>= 1.11)
globalid (0.4.2)
activesupport (>= 4.2.0)
hashdiff (0.4.0)
hashie (3.6.0)
hashdiff (1.0.1)
hashie (4.1.0)
hiredis (0.6.3)
http_accept_language (2.1.1)
i18n (1.6.0)
i18n (1.8.2)
concurrent-ruby (~> 1.0)
i18n-language-mapping (0.1.1)
jaro_winkler (1.5.3)
jbuilder (2.9.1)
activesupport (>= 4.2.0)
i18n-language-mapping (0.1.2)
jbuilder (2.10.0)
activesupport (>= 5.0.0)
jquery-rails (4.3.5)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
jquery-ui-rails (6.0.1)
railties (>= 3.2.16)
json (2.2.0)
json (2.3.0)
jwt (2.2.1)
listen (3.0.8)
rb-fsevent (~> 0.9, >= 0.9.4)
@ -138,35 +137,35 @@ GEM
activesupport (>= 4)
railties (>= 4)
request_store (~> 1.0)
loofah (2.3.1)
loofah (2.5.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.1)
mini_mime (>= 0.1.1)
marcel (0.3.3)
mimemagic (~> 0.3.2)
method_source (0.9.2)
mimemagic (0.3.3)
method_source (1.0.0)
mimemagic (0.3.5)
mini_mime (1.0.2)
mini_portile2 (2.4.0)
minitest (5.11.3)
msgpack (1.3.0)
multi_json (1.13.1)
minitest (5.14.1)
msgpack (1.3.3)
multi_json (1.14.1)
multi_xml (0.6.0)
multipart-post (2.1.1)
net-ldap (0.16.1)
nio4r (2.4.0)
net-ldap (0.16.2)
nio4r (2.5.2)
nokogiri (1.10.9)
mini_portile2 (~> 2.4.0)
oauth (0.5.4)
oauth2 (1.4.1)
faraday (>= 0.8, < 0.16.0)
oauth2 (1.4.4)
faraday (>= 0.8, < 2.0)
jwt (>= 1.0, < 3.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 3)
omniauth (1.9.0)
hashie (>= 3.4.6, < 3.7.0)
omniauth (1.9.1)
hashie (>= 3.4.6)
rack (>= 1.6.2, < 3)
omniauth-bn-launcher (0.1.3)
omniauth (~> 1.3, >= 1.3.2)
@ -187,29 +186,29 @@ GEM
omniauth-twitter (1.4.0)
omniauth-oauth (~> 1.1)
rack
pagy (3.3.2)
parallel (1.17.0)
parser (2.6.3.0)
pagy (3.8.1)
parallel (1.19.1)
parser (2.7.1.3)
ast (~> 2.4.0)
pg (0.21.0)
popper_js (1.14.5)
public_suffix (3.1.1)
puma (3.12.4)
popper_js (1.16.0)
public_suffix (4.0.5)
puma (3.12.6)
rack (2.2.2)
rack-test (1.1.0)
rack (>= 1.0, < 3)
rails (5.2.3)
actioncable (= 5.2.3)
actionmailer (= 5.2.3)
actionpack (= 5.2.3)
actionview (= 5.2.3)
activejob (= 5.2.3)
activemodel (= 5.2.3)
activerecord (= 5.2.3)
activestorage (= 5.2.3)
activesupport (= 5.2.3)
rails (5.2.4.3)
actioncable (= 5.2.4.3)
actionmailer (= 5.2.4.3)
actionpack (= 5.2.4.3)
actionview (= 5.2.4.3)
activejob (= 5.2.4.3)
activemodel (= 5.2.4.3)
activerecord (= 5.2.4.3)
activestorage (= 5.2.4.3)
activesupport (= 5.2.4.3)
bundler (>= 1.3.0)
railties (= 5.2.3)
railties (= 5.2.4.3)
sprockets-rails (>= 2.0.0)
rails-controller-testing (1.0.4)
actionpack (>= 5.0.1.x)
@ -218,64 +217,67 @@ GEM
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.0.4)
loofah (~> 2.2, >= 2.2.2)
railties (5.2.3)
actionpack (= 5.2.3)
activesupport (= 5.2.3)
rails-html-sanitizer (1.3.0)
loofah (~> 2.3)
railties (5.2.4.3)
actionpack (= 5.2.4.3)
activesupport (= 5.2.4.3)
method_source
rake (>= 0.8.7)
thor (>= 0.19.0, < 2.0)
rainbow (3.0.0)
rake (13.0.1)
random_password (0.1.1)
rb-fsevent (0.10.3)
rb-inotify (0.10.0)
rb-fsevent (0.10.4)
rb-inotify (0.10.1)
ffi (~> 1.0)
recaptcha (5.0.0)
recaptcha (5.5.0)
json
redcarpet (3.4.0)
redis (4.1.2)
redcarpet (3.5.0)
redis (4.1.4)
remote_syslog_logger (1.0.4)
syslog_protocol
request_store (1.4.1)
request_store (1.5.0)
rack (>= 1.4)
rspec-core (3.8.2)
rspec-support (~> 3.8.0)
rspec-expectations (3.8.4)
rexml (3.2.4)
rspec-core (3.9.2)
rspec-support (~> 3.9.3)
rspec-expectations (3.9.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0)
rspec-mocks (3.8.1)
rspec-support (~> 3.9.0)
rspec-mocks (3.9.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0)
rspec-rails (3.8.2)
rspec-support (~> 3.9.0)
rspec-rails (3.9.1)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
rspec-core (~> 3.8.0)
rspec-expectations (~> 3.8.0)
rspec-mocks (~> 3.8.0)
rspec-support (~> 3.8.0)
rspec-support (3.8.2)
rubocop (0.72.0)
jaro_winkler (~> 1.5.1)
rspec-core (~> 3.9.0)
rspec-expectations (~> 3.9.0)
rspec-mocks (~> 3.9.0)
rspec-support (~> 3.9.0)
rspec-support (3.9.3)
rubocop (0.84.0)
parallel (~> 1.10)
parser (>= 2.6)
parser (>= 2.7.0.1)
rainbow (>= 2.2.2, < 4.0)
rexml
rubocop-ast (>= 0.0.3)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 1.7)
unicode-display_width (>= 1.4.0, < 2.0)
rubocop-ast (0.0.3)
parser (>= 2.7.0.1)
ruby-progressbar (1.10.1)
safe_yaml (1.0.5)
sassc (2.0.1)
sassc (2.3.0)
ffi (~> 1.9)
rake
sassc-rails (2.1.2)
railties (>= 4.0.0)
sassc (>= 2.0)
sprockets (> 3.0)
sprockets-rails
tilt
sequel (5.29.0)
sequel (5.32.0)
shoulda-matchers (3.1.3)
activesupport (>= 4.0.0)
simplecov (0.16.1)
@ -295,33 +297,35 @@ GEM
activesupport (>= 4.0)
sprockets (>= 3.0.0)
sqlite3 (1.3.13)
sync (0.5.0)
syslog_protocol (0.9.2)
term-ansicolor (1.7.1)
tins (~> 1.0)
thor (0.20.3)
thor (1.0.1)
thread_safe (0.3.6)
tilt (2.0.9)
tins (1.21.0)
turbolinks (5.2.0)
tilt (2.0.10)
tins (1.25.0)
sync
turbolinks (5.2.1)
turbolinks-source (~> 5.2)
turbolinks-source (5.2.0)
tzinfo (1.2.5)
tzinfo (1.2.7)
thread_safe (~> 0.1)
tzinfo-data (1.2019.3)
tzinfo-data (1.2020.1)
tzinfo (>= 1.0.0)
uglifier (4.1.20)
uglifier (4.2.0)
execjs (>= 0.3.0, < 3)
unicode-display_width (1.6.0)
unicode-display_width (1.7.0)
web-console (3.7.0)
actionview (>= 5.0)
activemodel (>= 5.0)
bindex (>= 0.4.0)
railties (>= 5.0)
webmock (3.6.0)
webmock (3.8.3)
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
websocket-driver (0.7.1)
websocket-driver (0.7.2)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.4)
xml-simple (1.1.5)
@ -361,7 +365,7 @@ DEPENDENCIES
pagy
pg (~> 0.18)
puma (~> 3.12)
rails (~> 5.2.3)
rails (~> 5.2.4.3)
rails-controller-testing
random_password
recaptcha
@ -375,6 +379,7 @@ DEPENDENCIES
shoulda-matchers (~> 3.1)
spring
spring-watcher-listen (~> 2.0.0)
sprockets (< 4.0.0)
sqlite3 (~> 1.3.6)
tabler-rubygem!
turbolinks (~> 5)

View File

@ -80,7 +80,7 @@ $(document).on('turbolinks:load', function(){
// Get the uid of the selected user
let user = $(".selectpicker").selectpicker('val')
if (user != "") {
userInfo = JSON.parse(user)
let 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>")
}
})
@ -95,7 +95,7 @@ $(document).on('turbolinks:load', function(){
})
// Updates the colour picker to the correct colour
role_colour = $("#role-colorinput-regular").data("colour")
let role_colour = $("#role-colorinput-regular").data("colour")
$("#role-colorinput-regular").css("background-color", role_colour);
$("#role-colorinput-regular").css("border-color", role_colour);
@ -122,6 +122,18 @@ function changeBrandingImage(path) {
$.post(path, {value: url})
}
// Change the Legal URL to the one provided
function changeLegalURL(path) {
var url = $("#legal-url").val()
$.post(path, {value: url})
}
// Change the Privacy Policy URL to the one provided
function changePrivacyPolicyURL(path) {
var url = $("#privpolicy-url").val()
$.post(path, {value: url})
}
function mergeUsers() {
let userToMerge = $("#from-uid").text()
$.post($("#merge-save-access").data("path"), {merge: userToMerge})

View File

@ -44,11 +44,6 @@ $(document).on('turbolinks:load', function(){
}
});
// Forces the wrapper to take the entire screen height if the user can't create rooms
if ($("#cant-create-room-wrapper").length){
$(".wrapper").css('height', '100%').css('height', '-=130px');
}
// Display and update all fields related to creating a room in the createRoomModal
$("#create-room-block").click(function(){
showCreateRoom(this)
@ -138,7 +133,6 @@ $(document).on('turbolinks:load', function(){
});
function showCreateRoom(target) {
var modal = $(target)
$("#create-room-name").val("")
$("#create-room-access-code").text(getLocalizedString("modal.create_room.access_code_placeholder"))
$("#room_access_code").val(null)

View File

@ -18,61 +18,19 @@ $(document).on('turbolinks:load', function(){
var controller = $("body").data('controller');
var action = $("body").data('action');
if ((controller == "admins" && action == "edit_user") || (controller == "users" && action == "edit")) {
// Clear the role when the user clicks the x
$(".clear-role").click(clearRole)
// When the user selects an item in the dropdown add the role to the user
$("#role-select-dropdown").change(function(data){
var dropdown = $("#role-select-dropdown");
var select_role_id = dropdown.val();
if(select_role_id){
// Disable the role in the dropdown
var selected_role = dropdown.find('[value=\"' + select_role_id + '\"]');
selected_role.prop("disabled", true)
// Add the role tag
var tag_container = $("#role-tag-container");
tag_container.append("<span id=\"user-role-tag_" + select_role_id + "\" style=\"background-color:" + selected_role.data("colour") + ";\" class=\"tag user-role-tag\">" +
selected_role.text() + "<a data-role-id=\"" + select_role_id + "\" class=\"tag-addon clear-role\"><i data-role-id=\"" + select_role_id + "\" class=\"fas fa-times\"></i></a></span>");
// Update the role ids input that gets submited on user update
var role_ids = $("#user_role_ids").val()
role_ids += " " + select_role_id
$("#user_role_ids").val(role_ids)
// Add the clear role function to the tag
$("#user-role-tag_" + select_role_id).click(clearRole);
// Reset the dropdown
dropdown.val(null)
// Hack to make it play nice with turbolinks
if ($("#role-dropdown:visible").length == 0){
$(window).trigger('load.bs.select.data-api')
}
// Check to see if the role dropdown was set up
if ($("#role-dropdown").length != 0){
$("#role-dropdown").selectpicker('val', $("#user_role_id").val())
}
// Update hidden field with new value
$("#role-dropdown").on("changed.bs.select", function(){
$("#user_role_id").val($("#role-dropdown").selectpicker('val'))
})
}
})
// This function removes the specfied role from a user
function clearRole(data){
// Get the role id
var role_id = $(data.target).data("role-id");
var role_tag = $("#user-role-tag_" + role_id);
// Remove the role tag
$(role_tag).remove()
// Update the role ids input
var role_ids = $("#user_role_ids").val()
var parsed_ids = role_ids.split(' ')
var index = parsed_ids.indexOf(role_id.toString());
if (index > -1) {
parsed_ids.splice(index, 1);
}
$("#user_role_ids").val(parsed_ids.join(' '))
// Enable the role in the role select dropdown
var selected_role = $("#role-select-dropdown").find('[value=\"' + role_id + '\"]');
selected_role.prop("disabled", false)
}

View File

@ -158,3 +158,10 @@
.signin-button {
font-size: 16px;
}
.table-responsive tbody td:first-child > *:first-child {
max-height: 3em;
overflow: hidden;
max-width: 200px;
display: flex;
}

View File

@ -63,10 +63,16 @@ class AdminsController < ApplicationController
# GET /admins/rooms
def server_rooms
@search = params[:search] || ""
@order_column = params[:column] && params[:direction] != "none" ? params[:column] : "created_at"
@order_column = params[:column] && params[:direction] != "none" ? params[:column] : "status"
@order_direction = params[:direction] && params[:direction] != "none" ? params[:direction] : "DESC"
@running_room_bbb_ids = all_running_meetings[:meetings].pluck(:meetingID)
meetings = all_running_meetings[:meetings]
@running_room_bbb_ids = meetings.pluck(:meetingID)
@participants_count = {}
meetings.each do |meet|
@participants_count[meet[:meetingID]] = meet[:participantCount]
end
@user_list = shared_user_list if shared_access_allowed
@ -86,23 +92,21 @@ class AdminsController < ApplicationController
# POST /admins/ban/:user_uid
def ban_user
@user.roles = []
@user.add_role :denied
@user.set_role :denied
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
@user.set_role :user
redirect_back fallback_location: admins_path, flash: { success: I18n.t("administrator.flash.unbanned") }
end
# POST /admins/approve/:user_uid
def approve
@user.remove_role :pending
@user.set_role :user
send_user_approved_email(@user)
@ -298,7 +302,7 @@ class AdminsController < ApplicationController
flash[:alert] = I18n.t("administrator.roles.role_has_users", user_count: role.users.count)
return redirect_to admin_roles_path(selected_role: role.id)
elsif Role::RESERVED_ROLE_NAMES.include?(role) || role.provider != @user_domain ||
role.priority <= current_user.highest_priority_role.priority
role.priority <= current_user.role.priority
return redirect_to admin_roles_path(selected_role: role.id)
else
role.role_permissions.delete_all

View File

@ -27,7 +27,7 @@ class ApplicationController < ActionController::Base
# Retrieves the current user.
def current_user
@current_user ||= User.includes(:roles, :main_room).find_by(id: session[:user_id])
@current_user ||= User.includes(:role, :main_room).find_by(id: session[:user_id])
if Rails.configuration.loadbalanced_configuration
if @current_user && !@current_user.has_role?(:super_admin) &&
@ -119,7 +119,7 @@ class ApplicationController < ActionController::Base
current_user&.greenlight_account? && current_user&.authenticate(Rails.configuration.admin_password_default)
flash.now[:alert] = I18n.t("default_admin",
edit_link: edit_user_path(user_uid: current_user.uid) + "?setting=password").html_safe
edit_link: change_password_path(user_uid: current_user.uid)).html_safe
end
end

View File

@ -46,8 +46,10 @@ module Authenticator
internal_error_url, not_found_url]
url = if cookies[:return_to] && !dont_redirect_to.include?(cookies[:return_to])
cookies[:return_to]
else
elsif user.role.get_permission("can_create_rooms")
user.main_room
else
cant_create_rooms_path
end
# Delete the cookie if it exists

View File

@ -54,7 +54,6 @@ module BbbServer
join_opts = {}
join_opts[:userID] = uid if uid
join_opts[:join_via_html5] = true
join_opts[:guest] = true if options[:require_moderator_approval] && !options[:user_is_moderator]
bbb_server.join_meeting_url(room.bbb_id, name, password, join_opts)
end

View File

@ -99,7 +99,6 @@ module Emailer
def send_approval_user_signup_email(user)
begin
return unless Rails.configuration.enable_email_verification
admin_emails = admin_emails()
UserMailer.approval_user_signup(user, admins_url(tab: "pending"),
admin_emails, @settings).deliver_now unless admin_emails.empty?
@ -129,12 +128,12 @@ module Emailer
end
def admin_emails
admins = User.all_users_with_roles.where(roles: { role_permissions: { name: "can_manage_users", value: "true" } })
roles = Role.where(provider: @user_domain, role_permissions: { name: "can_manage_users", value: "true" })
.pluck(:name)
if Rails.configuration.loadbalanced_configuration
admins = admins.without_role(:super_admin)
.where(provider: @user_domain)
end
admins = User.with_role(roles - ["super_admin"])
admins = admins.where(provider: @user_domain) if Rails.configuration.loadbalanced_configuration
admins.collect(&:email).join(",")
end

View File

@ -25,29 +25,22 @@ module Populator
initial_user = case @tab
when "active"
User.includes(:roles).without_role(:pending).without_role(:denied)
User.without_role([:pending, :denied])
when "deleted"
User.includes(:roles).deleted
User.deleted
else
User.includes(:roles)
User.all
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
initial_list = initial_user.without_role(:super_admin) unless current_user.has_role? :super_admin
if Rails.configuration.loadbalanced_configuration
initial_list.where(provider: @user_domain)
initial_list = initial_list.where(provider: @user_domain) if Rails.configuration.loadbalanced_configuration
initial_list.where.not(id: current_user.id)
.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
@ -55,9 +48,9 @@ module Populator
if Rails.configuration.loadbalanced_configuration
Room.includes(:owner).where(users: { provider: @user_domain })
.admins_search(@search)
.admins_order(@order_column, @order_direction)
.admins_order(@order_column, @order_direction, @running_room_bbb_ids)
else
Room.includes(:owner).all.admins_search(@search).admins_order(@order_column, @order_direction)
Room.includes(:owner).admins_search(@search).admins_order(@order_column, @order_direction, @running_room_bbb_ids)
end
end
@ -77,10 +70,7 @@ module Populator
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)
initial_list = User.where.not(uid: current_user.uid).with_role(roles_can_appear)
return initial_list unless Rails.configuration.loadbalanced_configuration
initial_list.where(provider: @user_domain)
@ -88,7 +78,7 @@ module Populator
# 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)
initial_list = User.without_role(:super_admin).where.not(uid: current_user.uid)
return initial_list unless Rails.configuration.loadbalanced_configuration
initial_list.where(provider: @user_domain)

View File

@ -46,60 +46,23 @@ module Rolify
end
# Updates a user's roles
def update_roles(roles)
# Check that the user can manage users
return true unless current_user.highest_priority_role.get_permission("can_manage_users")
def update_roles(role_id)
return true if role_id.blank?
# Check to make sure user can edit roles
return false unless current_user.role.get_permission("can_manage_users")
new_roles = roles.split(' ').map(&:to_i)
old_roles = @user.roles.pluck(:id).uniq
return true if @user.role_id == role_id.to_i
added_role_ids = new_roles - old_roles
removed_role_ids = old_roles - new_roles
new_role = Role.find_by(id: role_id, provider: @user_domain)
# Return false if new role doesn't exist
return false if new_role.nil?
added_roles = []
removed_roles = []
current_user_role = current_user.highest_priority_role
# Check that the user has the permissions to add all the new roles
added_role_ids.each do |id|
role = Role.find(id)
# Admins are able to add the admin role to other users. All other roles may only
# add roles with a higher priority
if (role.priority > current_user_role.priority || current_user_role.name == "admin") &&
role.provider == @user_domain
added_roles << role
else
return false
end
end
# Check that the user has the permissions to remove all the deleted roles
removed_role_ids.each do |id|
role = Role.find(id)
# Admins are able to remove the admin role from other users. All other roles may only
# remove roles with a higher priority
if (role.priority > current_user_role.priority || current_user_role.name == "admin") &&
role.provider == @user_domain
removed_roles << role
else
return false
end
end
return false if new_role.priority < current_user.role.priority
# Send promoted/demoted emails
added_roles.each { |role| send_user_promoted_email(@user, role) if role.get_permission("send_promoted_email") }
removed_roles.each { |role| send_user_demoted_email(@user, role) if role.get_permission("send_demoted_email") }
send_user_promoted_email(@user, new_role) if new_role.get_permission("send_promoted_email")
# Update the roles
@user.roles.delete(removed_roles)
@user.roles << added_roles
# Make sure each user always has at least the user role
@user.roles = [Role.find_by(name: "user", provider: @user_domain)] if @user.roles.count.zero?
@user.save!
@user.update_attribute(:role_id, role_id)
end
# Updates a roles priority
@ -107,7 +70,7 @@ module Rolify
user_role = Role.find_by(name: "user", provider: @user_domain)
admin_role = Role.find_by(name: "admin", provider: @user_domain)
current_user_role = current_user.highest_priority_role
current_user_role = current_user.role
# Users aren't allowed to update the priority of the admin or user roles
return false if role_to_update.include?(user_role.id.to_s) || role_to_update.include?(admin_role.id.to_s)
@ -149,7 +112,7 @@ module Rolify
# Update Permissions
def update_permissions(role)
current_user_role = current_user.highest_priority_role
current_user_role = current_user.role
# Checks that it is valid for the provider to update the role
return false if role.priority <= current_user_role.priority || role.provider != @user_domain

View File

@ -67,6 +67,8 @@ class PasswordResetsController < ApplicationController
def find_user
@user = User.find_by(reset_digest: User.hash_token(params[:id]), provider: @user_domain)
return redirect_to new_password_reset_url, alert: I18n.t("reset_password.invalid_token") unless @user
end
def user_params

View File

@ -57,8 +57,6 @@ class RecordingsController < ApplicationController
# Ensure the user is logged into the room they are accessing.
def verify_room_ownership
if !@room.owned_by?(current_user) && !current_user&.highest_priority_role&.get_permission("can_manage_rooms_recordings")
redirect_to root_path
end
redirect_to root_path if !@room.owned_by?(current_user) && !current_user&.role&.get_permission("can_manage_rooms_recordings")
end
end

View File

@ -25,7 +25,7 @@ class RoomsController < ApplicationController
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 :find_room, except: [:create, :join_specific_room, :cant_create_rooms]
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]
@ -69,7 +69,6 @@ class RoomsController < ApplicationController
# If its the current user's room
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)
@ -77,11 +76,6 @@ class RoomsController < ApplicationController
@user_list = shared_user_list if shared_access_allowed
@pagy, @recordings = pagy_array(recs)
else
# Render view for users that cant create rooms
@recent_rooms = Room.where(id: cookies.encrypted["#{current_user.uid}_recently_joined_rooms"])
render :cant_create_rooms
end
else
return redirect_to root_path, flash: { alert: I18n.t("room.invalid_provider") } if incorrect_user_domain
@ -89,6 +83,19 @@ class RoomsController < ApplicationController
end
end
# GET /rooms
def cant_create_rooms
shared_rooms = current_user.shared_rooms
if current_user.shared_rooms.empty?
# Render view for users that cant create rooms
@recent_rooms = Room.where(id: cookies.encrypted["#{current_user.uid}_recently_joined_rooms"])
render :cant_create_rooms
else
redirect_to shared_rooms[0]
end
end
# POST /:room_uid
def join
return redirect_to root_path,

View File

@ -39,7 +39,7 @@ class SessionsController < ApplicationController
"#{Rails.configuration.relative_url_root}/auth/#{@providers.first}"
end
return redirect_to provider_path
redirect_to provider_path
end
end
@ -94,7 +94,7 @@ class SessionsController < ApplicationController
login(user)
end
# GET /users/logout
# POST /users/logout
def destroy
logout
redirect_to root_path
@ -218,7 +218,7 @@ class SessionsController < ApplicationController
# Add pending role if approval method and is a new user
if approval_registration && !@user_exists
user.add_role :pending
user.set_role :pending
# Inform admins that a user signed up if emails are turned on
send_approval_user_signup_email(user)
@ -228,6 +228,8 @@ class SessionsController < ApplicationController
send_invite_user_signup_email(user) if invite_registration && !@user_exists
user.set_role :user unless @user_exists
login(user)
if @auth['provider'] == "twitter"

View File

@ -24,7 +24,7 @@ class UsersController < ApplicationController
include Recorder
include Rolify
before_action :find_user, only: [:edit, :change_password, :delete_account, :update]
before_action :find_user, only: [:edit, :change_password, :delete_account, :update, :update_password]
before_action :ensure_unauthenticated_except_twitter, only: [:create]
before_action :check_user_signup_allowed, only: [:create]
before_action :check_admin_of, only: [:edit, :change_password, :delete_account]
@ -47,7 +47,7 @@ class UsersController < ApplicationController
# Set user to pending and redirect if Approval Registration is set
if approval_registration
@user.add_role :pending
@user.set_role :pending
return redirect_to root_path,
flash: { success: I18n.t("registration.approval.signup") } unless Rails.configuration.enable_email_verification
@ -56,7 +56,11 @@ class UsersController < ApplicationController
send_registration_email
# 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
if !Rails.configuration.enable_email_verification || @user.email_verified
@user.set_role :user
login(@user) && return
end
send_activation_email(@user, @user.create_activation_token)
@ -77,9 +81,8 @@ class UsersController < ApplicationController
def delete_account
end
# PATCH /u/:user_uid/edit
# POST /u/:user_uid/edit
def update
profile = params[:setting] == "password" ? change_password_path(@user) : edit_user_path(@user)
if session[:prev_url].present?
path = session[:prev_url]
session.delete(:prev_url)
@ -87,11 +90,31 @@ class UsersController < ApplicationController
path = admins_path
end
redirect_path = current_user.admin_of?(@user, "can_manage_users") ? path : profile
redirect_path = current_user.admin_of?(@user, "can_manage_users") ? path : edit_user_path(@user)
if params[:setting] == "password"
unless @user.greenlight_account?
params[:user][:name] = @user.name
params[:user][:email] = @user.email
end
if @user.update_attributes(user_params)
@user.update_attributes(email_verified: false) if user_params[:email] != @user.email
user_locale(@user)
if update_roles(params[:user][:role_id])
return redirect_to redirect_path, flash: { success: I18n.t("info_update_success") }
else
flash[:alert] = I18n.t("administrator.roles.invalid_assignment")
end
end
render :edit
end
# POST /u/:user_uid/change_password
def update_password
# Update the users password.
if @user.authenticate(user_params[:password])
# Verify that the new passwords match.
if user_params[:new_password] == user_params[:password_confirmation]
@ -106,25 +129,11 @@ class UsersController < ApplicationController
end
# Notify the user that their account has been updated.
return redirect_to redirect_path,
return redirect_to change_password_path,
flash: { success: I18n.t("info_update_success") } if @user.errors.empty? && @user.save
# redirect_to change_password_path
render :change_password
else
if @user.update_attributes(user_params)
@user.update_attributes(email_verified: false) if user_params[:email] != @user.email
user_locale(@user)
if update_roles(params[:user][:role_ids])
return redirect_to redirect_path, flash: { success: I18n.t("info_update_success") }
else
flash[:alert] = I18n.t("administrator.roles.invalid_assignment")
end
end
render :edit
end
end
# DELETE /u/:user_uid

View File

@ -31,6 +31,11 @@ module AdminsHelper
@running_room_bbb_ids.include?(id)
end
# Returns a more friendly/readable date time object
def friendly_time(date)
I18n.l date, format: "%B %d, %Y %H:%M UTC"
end
# Site Settings
def admin_invite_registration
@ -110,6 +115,6 @@ module AdminsHelper
# Roles
def edit_disabled
@edit_disabled ||= @selected_role.priority <= current_user.highest_priority_role.priority
@edit_disabled ||= @selected_role.priority <= current_user.role.priority
end
end

View File

@ -58,7 +58,16 @@ module ApplicationHelper
# Returns the page that the logo redirects to when clicked on
def home_page
return admins_path if current_user.has_role? :super_admin
current_user.main_room
return current_user.main_room if current_user.role.get_permission("can_create_rooms")
cant_create_rooms_path
end
# Returns 'active' if the current page is the users home page (used to style header)
def active_home
home_actions = %w[show cant_create_rooms]
return "active" if params[:controller] == "admins" && params[:action] == "index" && current_user.has_role?(:super_admin)
return "active" if params[:controller] == "rooms" && home_actions.include?(params[:action])
""
end
# Returns the action method of the current page
@ -97,10 +106,22 @@ module ApplicationHelper
"https://www.googletagmanager.com/gtag/js?id=#{ENV['GOOGLE_ANALYTICS_TRACKING_ID']}"
end
# Checks to make sure the image url returns 200 and is of type image
def valid_url?(input)
uri = URI.parse(input)
!uri.host.nil?
rescue URI::InvalidURIError
url = URI.parse(input)
# Don't allow reference to own site
return false if url.host == request.host
# Make a GET request and validate content type
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = (url.scheme == "https")
http.start do |web|
response = web.head(url.request_uri)
return response.code == "200" && response['Content-Type'].start_with?('image')
end
rescue
false
end
end

View File

@ -22,6 +22,16 @@ module ThemingHelper
@settings.get_value("Branding Image") || Rails.configuration.branding_image_default
end
# Returns the legal URL based on user's provider
def legal_url
@settings.get_value("Legal URL") || ""
end
# Returns the logo based on user's provider
def privpolicy_url
@settings.get_value("Privacy Policy URL") || ""
end
# Returns the primary color based on user's provider
def user_color
@settings.get_value("Primary Color") || Rails.configuration.primary_color_default

View File

@ -26,7 +26,7 @@ module UsersHelper
end
def disabled_roles(user)
current_user_role = current_user.highest_priority_role
current_user_role = current_user.role
# Admins are able to remove the admin role from other admins
# For all other roles they can only add/remove roles with a higher priority
@ -38,7 +38,7 @@ module UsersHelper
.pluck(:id)
end
user.roles.by_priority.pluck(:id) | disallowed_roles
[user.role.id] + disallowed_roles
end
# Returns language selection options for user edit
@ -52,6 +52,11 @@ module UsersHelper
language_opts.sort
end
# Returns a list of roles that the user can have
def role_options
Role.editable_roles(@user_domain).where("priority >= ?", current_user.role.priority)
end
# Parses markdown for rendering.
def markdown(text)
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML,

View File

@ -25,7 +25,7 @@ class Ability
elsif user.has_role? :super_admin
can :manage, :all
else
highest_role = user.highest_priority_role
highest_role = user.role
if highest_role.get_permission("can_edit_site_settings")
can [:site_settings, :room_configuration, :update_settings,
:update_room_configuration, :coloring, :registration_method], :admin

View File

@ -63,7 +63,7 @@ module AuthValues
role_provider = auth['provider'] == "bn_launcher" ? auth['info']['customer'] : "greenlight"
roles.each do |role_name|
role = Role.find_by(provider: role_provider, name: role_name)
user.roles << role if !role.nil? && !user.has_role?(role_name)
user.role = role if !role.nil? && !user.has_role?(role_name)
end
end
end

View File

@ -17,10 +17,12 @@
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
class Role < ApplicationRecord
has_and_belongs_to_many :users, join_table: :users_roles
has_and_belongs_to_many :users, join_table: :users_roles # Obsolete -- not used anymore
has_many :role_permissions
default_scope { includes(:role_permissions).order(:priority) }
has_many :users
default_scope { includes(:role_permissions).distinct.order(:priority) }
scope :by_priority, -> { order(:priority) }
scope :editable_roles, ->(provider) { where(provider: provider).where.not(name: %w[super_admin denied pending]) }

View File

@ -45,10 +45,13 @@ class Room < ApplicationRecord
where(search_query, search: search_param)
end
def self.admins_order(column, direction)
def self.admins_order(column, direction, running_ids)
# Include the owner of the table
table = joins(:owner)
# Rely on manual ordering if trying to sort by status
return order_by_status(table, running_ids) if column == "status"
return table.order(Arel.sql("rooms.#{column} #{direction}")) if table.column_names.include?(column)
return table.order(Arel.sql("#{column} #{direction}")) if column == "users.name"
@ -80,6 +83,21 @@ class Room < ApplicationRecord
ActionCable.server.broadcast("#{uid}_waiting_channel", action: "started")
end
# Return table with the running rooms first
def self.order_by_status(table, ids)
return table if ids.blank?
order_string = "CASE bbb_id "
ids.each_with_index do |id, index|
order_string += "WHEN '#{id}' THEN #{index} "
end
order_string += "ELSE #{ids.length} END"
table.order(Arel.sql(order_string))
end
private
# Generates a uid for the room and BigBlueButton.
@ -90,21 +108,18 @@ class Room < ApplicationRecord
self.attendee_pw = RandomPassword.generate(length: 12)
end
# Generates a three character uid chunk.
def uid_chunk
charset = ("a".."z").to_a - %w(b i l o s) + ("2".."9").to_a - %w(5 8)
(0...3).map { charset.to_a[rand(charset.size)] }.join
end
# Generates a random room uid that uses the users name.
# Generates a fully random room uid.
def random_room_uid
[owner.name_chunk, uid_chunk, uid_chunk].join('-').downcase
# 6 character long random string of chars from a..z and 0..9
full_chunk = SecureRandom.alphanumeric(6).downcase
[owner.name_chunk, full_chunk[0..2], full_chunk[3..5]].join("-")
end
# Generates a unique bbb_id based on uuid.
def unique_bbb_id
loop do
bbb_id = SecureRandom.hex(20)
bbb_id = SecureRandom.alphanumeric(40).downcase
break bbb_id unless Room.exists?(bbb_id: bbb_id)
end
end

View File

@ -48,6 +48,10 @@ class Setting < ApplicationRecord
case name
when "Branding Image"
Rails.configuration.branding_image_default
when "Legal URL"
nil
when "Privacy Policy URL"
nil
when "Primary Color"
Rails.configuration.primary_color_default
when "Registration Method"

View File

@ -31,7 +31,9 @@ class User < ApplicationRecord
has_many :shared_access
belongs_to :main_room, class_name: 'Room', foreign_key: :room_id, required: false
has_and_belongs_to_many :roles, join_table: :users_roles
has_and_belongs_to_many :roles, join_table: :users_roles # obsolete
belongs_to :role, required: false
validates :name, length: { maximum: 256 }, presence: true
validates :provider, presence: true
@ -92,14 +94,12 @@ class User < ApplicationRecord
end
search_param = "%#{string}%"
joins("LEFT OUTER JOIN users_roles ON users_roles.user_id = users.id LEFT OUTER JOIN roles " \
"ON roles.id = users_roles.role_id").distinct
.where(search_query, search: search_param, roles_search: role_search_param)
where(search_query, search: search_param, roles_search: role_search_param)
end
def self.admins_order(column, direction)
# Arel.sql to avoid sql injection
order(Arel.sql("#{column} #{direction}"))
order(Arel.sql("users.#{column} #{direction}"))
end
# Returns a list of rooms ordered by last session (with nil rooms last)
@ -109,6 +109,7 @@ class User < ApplicationRecord
# Activates an account and initialize a users main room
def activate
set_role :user if role_id.nil?
update_attributes(email_verified: true, activated_at: Time.zone.now, activation_digest: nil)
end
@ -162,7 +163,7 @@ class User < ApplicationRecord
end
def admin_of?(user, permission)
has_correct_permission = highest_priority_role.get_permission(permission) && id != user.id
has_correct_permission = role.get_permission(permission) && id != user.id
return has_correct_permission unless Rails.configuration.loadbalanced_configuration
return id != user.id if has_role? :super_admin
@ -170,70 +171,31 @@ class User < ApplicationRecord
end
# role functions
def highest_priority_role
roles.min_by(&:priority)
end
def add_role(role)
unless has_role?(role)
role_provider = Rails.configuration.loadbalanced_configuration ? provider : "greenlight"
def set_role(role) # rubocop:disable Naming/AccessorMethodName
return if has_role?(role)
new_role = Role.find_by(name: role, provider: role_provider)
if new_role.nil?
return if Role.duplicate_name(role, role_provider) || role.strip.empty?
return if new_role.nil?
new_role = Role.create_new_role(role, role_provider)
end
create_home_room if main_room.nil? && new_role.get_permission("can_create_rooms")
roles << new_role
update_attribute(:role, new_role)
save!
end
end
def remove_role(role)
if has_role?(role)
role_provider = Rails.configuration.loadbalanced_configuration ? provider : "greenlight"
roles.delete(Role.find_by(name: role, provider: role_provider))
save!
end
new_role
end
# This rule is disabled as the function name must be has_role?
# rubocop:disable Naming/PredicateName
def has_role?(role)
# rubocop:enable Naming/PredicateName
roles.each do |single_role|
return true if single_role.name.eql? role.to_s
end
false
def has_role?(role_name) # rubocop:disable Naming/PredicateName
role&.name == role_name.to_s
end
def self.with_role(role)
User.all_users_with_roles.where(roles: { name: role })
User.includes(:role).where(roles: { name: role })
end
def self.without_role(role)
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
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
User.includes(:role).where.not(roles: { name: role })
end
private
@ -246,15 +208,13 @@ class User < ApplicationRecord
def setup_user
# Initializes a room for the user and assign a BigBlueButton user id.
id = "gl-#{(0...12).map { rand(65..90).chr }.join.downcase}"
room = Room.create!(owner: self, name: I18n.t("home_room"))
update_attributes(uid: id, main_room: room)
update_attributes(uid: id)
# Initialize the user to use the default user role
role_provider = Rails.configuration.loadbalanced_configuration ? provider : "greenlight"
Role.create_default_roles(role_provider) if Role.where(provider: role_provider).count.zero?
add_role(:user) if roles.blank?
end
def check_if_email_can_be_blank
@ -266,4 +226,13 @@ class User < ApplicationRecord
end
end
end
def create_home_room
room = Room.create!(owner: self, name: I18n.t("home_room"))
update_attributes(main_room: room)
end
def role_provider
Rails.configuration.loadbalanced_configuration ? provider : "greenlight"
end
end

View File

@ -14,7 +14,7 @@
%>
<div class="list-group list-group-transparent mb-0">
<% highest_role = current_user.highest_priority_role %>
<% highest_role = current_user.role %>
<% highest_role.name %>
<% if highest_role.get_permission("can_manage_users") || highest_role.name == "super_admin" %>
<%= link_to admins_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "index"}" do %>

View File

@ -16,7 +16,7 @@
<div class="row">
<div class="col-12">
<div class="table-responsive">
<table id="recordings-table" class="table table-hover table-outline table-vcenter text-nowrap card-table">
<table id="recordings-table" class="table table-hover table-outline table-vcenter card-table">
<thead>
<tr>
<th data-header="name" data-order="<%= @order_column == "name" ? @order_direction : "none" %>">
@ -94,7 +94,7 @@
</tbody>
</table>
<% if !@recordings.empty?%>
<div class="float-right mr-4 mt-4">
<div class="float-md-right mt-4">
<%== pagy_bootstrap_nav(@pagy) %>
</div>
<% end %>

View File

@ -15,7 +15,7 @@
<div class="container">
<div class="row">
<% current_role = current_user.highest_priority_role%>
<% current_role = current_user.role%>
<div class="col-lg-3 mb-4">
<div class="list-group list-group-transparent mb-0">
<div id="rolesSelect" data-url="<%= admin_roles_order_path %>">
@ -34,7 +34,7 @@
</div>
<div class="col-lg-9 <%="form-disable" if edit_disabled %>">
<%= form_with model: @selected_role, url: admin_update_role_path(@selected_role.id), method: :post do |f| %>
<%= f.label t('administrator.roles.name'), class: "form-label" %>
<%= f.label :name, t('administrator.roles.name'), class: "form-label" %>
<%= f.text_field :name, class: 'form-control mb-3', value: translated_role_name(@selected_role), readonly: edit_disabled || @selected_role.name == "user" || @selected_role.name == "admin", required: true %>
<%= f.hidden_field :colour, id: "role-colour", value: role_colour(@selected_role) %>

View File

@ -16,7 +16,7 @@
<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">
<table id="rooms-table" class="table table-hover table-outline table-vcenter card-table">
<thead>
<tr>
<th data-header="name" data-order="<%= @order_column == "name" ? @order_direction : "none" %>">
@ -43,6 +43,9 @@
<% end %>
</th>
<th>
<%= t("administrator.rooms.table.participants") %>
</th>
<th>
<%= t("administrator.rooms.table.status") %>
</th>
@ -56,7 +59,7 @@
</tbody>
</table>
<% if !@rooms.empty?%>
<div class="float-right mr-4 mt-4">
<div class="float-md-right mt-4">
<%== pagy_bootstrap_nav(@pagy) %>
</div>
<% end %>

View File

@ -15,14 +15,14 @@
<tr>
<td>
<div id="recording-title" class="form-inline edit_hover_class" data-recordid="<%= recording[:recordID] %>" data-room-uid="<%= room_uid_from_bbb(recording[:meetingID]) %>" data-path="<%= rename_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID]) %>">
<text id='recording-text'>
<div id="recording-title" class="edit_hover_class" data-recordid="<%= recording[:recordID] %>" data-room-uid="<%= room_uid_from_bbb(recording[:meetingID]) %>" data-path="<%= rename_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID]) %>">
<span id='recording-text' title="<%= recording[:name] %>">
<% if recording[:metadata][:name] %>
<%= recording[:metadata][:name] %>
<% else %>
<%= recording[:name] %>
<% end %>
</text>
</span>
<a><i id="edit-record" class="fa fa-edit align-top ml-2" data-edit-recordid="<%= recording[:recordID] %>"></i></a>
</div>
<div class="small text-muted">

View File

@ -15,16 +15,23 @@
<tr class="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">
<div id="room-title" class="edit_hover_class">
<% if room.id == room.owner.room_id %>
<i class="fas fa-home pr-1"></i>
<% end %>
<text class="room-name-text">
<span class="room-name-text" title="<%= room.name %>">
<%= room.name %>
</text>
</span>
</div>
<div class="small text-muted">
<%= [t("administrator.users.table.created"), ": ", room.created_at].join %>
<% running = room_is_running(room.bbb_id) %>
<% if running %>
<%= t("administrator.rooms.table.started", session: friendly_time(room.last_session)) %>
<% elsif room.last_session.present? %>
<%= t("administrator.rooms.table.ended", session: friendly_time(room.last_session)) %>
<% else %>
<%= [t("administrator.users.table.created"), ": ", friendly_time(room.created_at)].join %>
<% end %>
</div>
</td>
<td class="text-left">
@ -33,8 +40,10 @@
<td class="text-left">
<%= room.uid %>
</td>
<td class="text-center">
<%= @participants_count[room.bbb_id].presence || "-" %>
</td>
<td class="text-left">
<% running = room_is_running(room.bbb_id) %>
<% if running %>
<%= t("administrator.rooms.table.running") %>
<% else %>

View File

@ -28,6 +28,34 @@
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="mb-6 form-group">
<label class="form-label"><%= t("administrator.site_settings.legal.title") %></label>
<label class="form-label text-muted"><%= t("administrator.site_settings.legal.info") %></label>
<div class="input-group">
<input id="legal-url" type="text" class="form-control" value="<%= legal_url %>">
<span class="input-group-append">
<button id="legal-url" onclick="changeLegalURL('<%= admin_update_settings_path(setting: 'Legal URL') %>')" class="btn btn-primary" type="button"><%= t("administrator.site_settings.legal.change") %></button>
</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="mb-6 form-group">
<label class="form-label"><%= t("administrator.site_settings.privpolicy.title") %></label>
<label class="form-label text-muted"><%= t("administrator.site_settings.privpolicy.info") %></label>
<div class="input-group">
<input id="privpolicy-url" type="text" class="form-control" value="<%= privpolicy_url %>">
<span class="input-group-append">
<button id="privpolicy-url" onclick="changePrivacyPolicyURL('<%= admin_update_settings_path(setting: 'Privacy Policy URL') %>')" class="btn btn-primary" type="button"><%= t("administrator.site_settings.privpolicy.change") %></button>
</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="mb-6 form-group">

View File

@ -13,21 +13,6 @@
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
%>
<%
# 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/>.
%>
<% if @role.nil? %>
<%= render "admins/components/manage_users_tags" %>
<% else %>
@ -89,11 +74,10 @@
<td class="user-email"><%= user.email && user.email != "" ? user.email : user.username%></td>
<td><%= user.provider %></td>
<td class="text-center">
<% roles = user.roles().pluck(:name) %>
<%= render "admins/components/admins_role", role: user.highest_priority_role %>
<%= render "admins/components/admins_role", role: user.role %>
</td>
<td>
<% if !roles.include?("super_admin") %>
<% if !user.has_role?("super_admin") %>
<div class="item-action dropdown">
<a href="javascript:void(0)" data-toggle="dropdown" class="icon">
<i class="fas fa-ellipsis-v px-4"></i>
@ -106,14 +90,14 @@
<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") %>
<% elsif user.has_role?("denied") %>
<%= 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") %>
<% elsif user.has_role?("pending") %>
<%= 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 %>
@ -150,7 +134,7 @@
<% end %>
</tbody>
</table>
<div class="float-right mt-4">
<div class="float-md-right mt-4">
<%== pagy_bootstrap_nav(@pagy) %>
</div>
</div>

View File

@ -16,5 +16,5 @@
<div class="container text-center pt-9">
<div class="display-1 text-muted mb-5"><%= t("errors.bigbluebutton.title") %></div>
<h1 class="h2 mb-3"><%= t("errors.bigbluebutton.message") %></h1>
<p class="h4 text-muted font-weight-normal mb-7"><%= t("errors.bigbluebutton.help", doc_link: "http://docs.bigbluebutton.org/greenlight/gl-install.html#setting-bigbluebutton-credentials").html_safe %></p>
<p class="h4 text-muted font-weight-normal mb-7"><%= t("errors.bigbluebutton.help", doc_link: "https://docs.bigbluebutton.org/greenlight/gl-install.html#setting-bigbluebutton-credentials").html_safe %></p>
</div>

View File

@ -16,7 +16,7 @@
<div class="container mt-8 mb-6 text-center">
<h2 class="mb-6">Greenlight <%= t("features.title") %></h2>
<h2 class="mb-6"><%= t("greenlight") %> <%= t("features.title") %></h2>
<div class="row feature-stamp">
<div class="col-lg-3 col-md-6">

View File

@ -15,7 +15,7 @@
<div class="container">
<div class="row pt-7">
<div class="col col-4 offset-4">
<div class="col col-md-4 col-sm-12 mx-auto">
<div class="card">
<div class="card-header background">
<h4 class="mt-2"><%= t("reset_password.subtitle") %></h4>
@ -25,11 +25,11 @@
<%= hidden_field_tag :email, @user.email %>
<%= f.label t('reset_password.password'), class: "form-label" %>
<%= f.label :password, t('reset_password.password'), class: "form-label" %>
<%= f.password_field :password, class: 'form-control' %>
<br>
<%= f.label t('reset_password.confirm'), class: "form-label" %>
<%= f.label :password_confirmation, t('reset_password.confirm'), class: "form-label" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<br>

View File

@ -15,14 +15,14 @@
<div class="container">
<div class="row pt-7">
<div class="col col-4 offset-4">
<div class="col col-md-4 col-sm-12 mx-auto">
<div class="card">
<div class="card-header background">
<h4 class="mt-2"><%= t("forgot_password.subtitle") %></h4>
</div>
<div class="card-body background">
<%= form_for(:password_reset, url: password_resets_path) do |f| %>
<%= f.label t("forgot_password.email"), class: "form-label" %>
<%= f.label :email, t("forgot_password.email"), class: "form-label" %>
<%= f.email_field :email, class: "form-control" %>
<br>

View File

@ -1,5 +1,3 @@
<%
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
@ -15,12 +13,10 @@
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
%>
<div id="cant-create-room-wrapper" class="background h-100 cant-create-room-wrapper">
<div class="container h-100">
<div class="row h-100 align-items-center">
<div class="col-12">
<div class="row">
<div class="col-5">
<div id="cant-create-room-wrapper" class="d-flex align-content-md-center flex-wrap background h-100 cant-create-room-wrapper">
<div class="container">
<div class="row my-7">
<div class="col-lg-5 d-none d-lg-flex">
<div class="card card-profile h-100">
<div class="card-header bg-primary h-50"></div>
<div class="card-body text-center">
@ -36,15 +32,15 @@
</div>
</div>
</div>
<div class="col-7">
<div class="col-lg-7 col-sm-12">
<div class="card h-100">
<div class="card-status bg-primary"></div>
<div class="card-header cant-create-rooms-title">
<h3 class="card-title"><%= t("room.no_room.title") %></h3>
</div>
<div class="card-body d-flex flex-column justify-content-center align-items-center">
<p class="w-75"><%= t("room.no_room.description") %></p>
<%= form_for(:join_room, url: join_room_path, html: {class: "w-75"}) do |f| %>
<div class="card-body mx-auto col-sm-9 col-12">
<p><%= t("room.no_room.description") %></p>
<%= form_for(:join_room, url: join_room_path) do |f| %>
<div class="input-icon mb-2">
<span class="input-icon-addon">
<i class="fas fa-link"></i>
@ -57,8 +53,8 @@
<% end %>
</div>
<hr class="mt-0 mb-0">
<div class="card-body d-flex flex-column justify-content-center align-items-center">
<ul class="list-group w-75 text-center">
<div class="card-body mx-auto col-sm-9 col-12">
<ul class="list-group text-center">
<li class="list-group-item active"><%= t("room.no_room.recent_rooms") %></li>
<% @recent_rooms.each do |room| %>
<%= link_to room_path(room), class: "list-group-item list-group-item-action dropdown-item" do %>
@ -74,6 +70,4 @@
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -77,6 +77,7 @@
</div>
<div id="room_block_container" class="row pt-7 pb-5">
<% if current_user.role.get_permission("can_create_rooms") %>
<% current_user.ordered_rooms.each do |room| %>
<div class="col-lg-4 col-md-6 col-sm-12">
<%= link_to room do %>
@ -84,6 +85,7 @@
<% end %>
</div>
<% end %>
<% end %>
<% if shared_access_allowed %>
<% current_user.shared_rooms.each do |room| %>
@ -95,7 +97,7 @@
<% end %>
<% end %>
<% unless room_limit_exceeded %>
<% if current_user.role.get_permission("can_create_rooms") && !room_limit_exceeded %>
<%= render "rooms/components/create_room_block"%>
<% end %>
</div>

View File

@ -40,22 +40,22 @@
<% end %>
<%= form_for @user, url: create_user_path, method: :post do |f| %>
<div class="form-group">
<%= f.label t("settings.account.fullname"), class: "form-label" %>
<%= f.label :name, t("settings.account.fullname"), class: "form-label" %>
<%= f.text_field :name, class: "form-control #{form_is_invalid?(@user, :name)}", placeholder: t("settings.account.fullname") %>
<div class="invalid-feedback d-block"><%= @user.errors.full_messages_for(:name).first %></div>
</div>
<div class="form-group">
<%= f.label t("email"), class: "form-label" %>
<%= f.text_field :email, class: "form-control #{form_is_invalid?(@user, :email)}", placeholder: t("email") %>
<%= f.label :email, t("email"), class: "form-label" %>
<%= f.email_field :email, class: "form-control #{form_is_invalid?(@user, :email)}", placeholder: t("email") %>
<div class="invalid-feedback d-block"><%= @user.errors.full_messages_for(:email).first %></div>
</div>
<div class="form-group">
<%= f.label t("password"), class: "form-label" %>
<%= f.label :password, t("password"), class: "form-label" %>
<%= f.password_field :password, class: "form-control #{form_is_invalid?(@user, :password)}", placeholder: t("password") %>
<div class="invalid-feedback d-block"><%= @user.errors.full_messages_for(:password).first %></div>
</div>
<div class="form-group">
<%= f.label t("signup.password_confirm"), class: "form-label" %>
<%= f.label :password_confirmation, t("signup.password_confirm"), class: "form-label" %>
<%= f.password_field :password_confirmation, class: "form-control #{form_is_invalid?(@user, :password_confirmation)}", placeholder: t("signup.password_confirm") %>
<div class="invalid-feedback d-block"><%= @user.errors.full_messages_for(:password_confirmation).first %></div>
</div>

View File

@ -44,7 +44,7 @@
<span class="input-icon-addon">
<i class="fas fa-at"></i>
</span>
<%= f.text_field :email, class: "form-control", placeholder: t("email"), value: "" %>
<%= f.email_field :email, class: "form-control", placeholder: t("email"), value: "" %>
</div>
</div>
<div class="form-group">

View File

@ -17,22 +17,22 @@
<% if key.eql? "success" %>
<div class="alert alert-success alert-dismissible text-center mb-0">
<button type="button" class="close" data-dismiss="alert">&times</button>
<%= value.html_safe %>
<%= value %>
</div>
<% elsif key.eql? "alert" %>
<div class="alert alert-danger alert-dismissible text-center mb-0">
<button type="button" class="close" data-dismiss="alert">&times</button>
<%= value.html_safe %>
<%= value %>
</div>
<% elsif key.eql? "maintenance" %>
<div class="alert alert-info alert-dismissible text-center mb-0">
<%= value.html_safe %>
<%= value %>
<button id="maintenance-close" type="button" data-date="<%= Rails.configuration.maintenance_window %>" class="close" data-dismiss="alert">&times</button>
</div>
<% elsif key.eql? "info" %>
<div class="alert alert-info alert-dismissible text-center mb-0">
<button type="button" class="close" data-dismiss="alert">&times</button>
<%= value.html_safe %>
<%= value %>
</div>
<% end %>
<% end %>

View File

@ -14,7 +14,8 @@
%>
<footer class="footer pt-3">
<p class="text-center mb-1"><%= t("footer.powered_by", href: link_to(t("greenlight"), "https://bigbluebutton.org/2018/07/09/greenlight-2-0/", target: "_blank", rel: "noopener")).html_safe %> <%= Greenlight::Application::VERSION %></p>
<p class="text-center mb-1"><%= t("footer.powered_by", href: link_to(t("greenlight"), "https://bigbluebutton.org/2018/07/09/greenlight-2-0/", target: "_blank", rel: "noopener")).html_safe %> <%= Greenlight::Application::VERSION %>
<%= link_to( ' | ' + t("footer.legal"), legal_url ) if legal_url.present? %><%= link_to( ' | ' + t("footer.privpolicy"), privpolicy_url) if privpolicy_url.present? %></p>
</footer>
<%= render "shared/components/cookie_warning" %>

View File

@ -27,24 +27,16 @@
<div class="d-flex ml-auto">
<% if current_user %>
<% if current_user.has_role? :super_admin %>
<% admins_page = params[:controller] == "admins" && params[:action] == "index" ? "active" : "" %>
<%= link_to admins_path, class: "px-3 mx-1 mt-1 header-nav #{admins_page}" do %>
<i class="fas fa-home pr-1 "></i><span class="d-none d-sm-inline-block"><%= t("header.dropdown.home") %></span>
<% end %>
<% else %>
<% rooms_page = params[:controller] == "rooms" && params[:action] == "show" ? "active" : "" %>
<%= link_to current_user.main_room, class: "px-3 mx-1 mt-1 header-nav #{rooms_page}" do %>
<%= link_to home_page, class: "px-3 mx-1 mt-1 header-nav #{active_home}" do %>
<i class="fas fa-home pr-1 "></i><span class="d-none d-sm-inline-block"><%= t("header.dropdown.home") %></span>
<% end %>
<% if current_user.highest_priority_role.get_permission("can_create_rooms") %>
<% if current_user.role.get_permission("can_create_rooms") && !current_user.has_role?(:super_admin) %>
<% all_rec_page = params[:controller] == "users" && params[:action] == "recordings" ? "active" : "" %>
<%= link_to get_user_recordings_path(current_user), class: "px-3 mx-1 mt-1 header-nav #{all_rec_page}" do %>
<i class="fas fa-video pr-1"></i><span class="d-none d-sm-inline-block"><%= t("header.all_recordings") %></span>
<% end %>
<% end %>
<% end %>
<div class="dropdown">
<a href="#" class="nav-link pr-0" data-toggle="dropdown">
@ -62,7 +54,7 @@
<%= link_to edit_user_path(current_user), class: "dropdown-item" do %>
<i class="dropdown-icon fas fa-id-card mr-3"></i><%= t("header.dropdown.settings") %>
<% end %>
<% highest_role = current_user.highest_priority_role %>
<% highest_role = current_user.role %>
<% if highest_role.get_permission("can_manage_users") || highest_role.name == "super_admin" %>
<%= link_to admins_path, class: "dropdown-item" do %>
<i class="dropdown-icon fas fa-user-tie mr-3"></i><%= t("header.dropdown.account_settings") %>
@ -91,7 +83,7 @@
<i class="dropdown-icon fas fa-exclamation mr-3"></i><%= t("errors.internal.report") %>
</a>
<% end %>
<%= link_to logout_path, class: "dropdown-item" do %>
<%= button_to logout_path, class: "dropdown-item" do %>
<i class="dropdown-icon fas fa-sign-out-alt"></i> <%= t("header.dropdown.signout") %>
<% end %>
</div>

View File

@ -114,7 +114,7 @@
</tbody>
</table>
<% if !recordings.empty?%>
<div class="float-right mr-4 mt-4">
<div class="float-md-right mt-4">
<%== pagy_bootstrap_nav(pagy) %>
</div>
<% end %>

View File

@ -15,14 +15,14 @@
<tr>
<td>
<div id="recording-title" class="form-inline edit_hover_class" data-recordid="<%= recording[:recordID] %>" data-room-uid="<%= room_uid_from_bbb(recording[:meetingID]) %>" data-path="<%= rename_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID]) %>">
<text>
<div id="recording-title" class="edit_hover_class" data-recordid="<%= recording[:recordID] %>" data-room-uid="<%= room_uid_from_bbb(recording[:meetingID]) %>" data-path="<%= rename_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID]) %>">
<span id="recording-text" title="<%= recording[:name] %>">
<% if recording[:metadata][:name] %>
<%= recording[:metadata][:name] %>
<% else %>
<%= recording[:name] %>
<% end %>
</text>
</span>
</div>
<div class="small text-muted">
<%= t("recording.recorded_on", date: recording_date(recording[:startTime])) %>

View File

@ -15,14 +15,14 @@
<tr>
<td>
<div id="recording-title" class="form-inline edit_hover_class" data-recordid="<%= recording[:recordID] %>" data-room-uid="<%= room_uid_from_bbb(recording[:meetingID]) %>" data-path="<%= rename_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID]) %>">
<text id='recording-text'>
<div id="recording-title" class="edit_hover_class" data-recordid="<%= recording[:recordID] %>" data-room-uid="<%= room_uid_from_bbb(recording[:meetingID]) %>" data-path="<%= rename_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID]) %>">
<span id='recording-text' title="<%= recording[:name] %>">
<% if recording[:metadata][:name] %>
<%= recording[:metadata][:name] %>
<% else %>
<%= recording[:name] %>
<% end %>
</text>
</span>
<a><i id="edit-record" class="fa fa-edit align-top ml-2" data-edit-recordid="<%= recording[:recordID] %>"></i></a>
</div>
<div class="small text-muted">

View File

@ -15,11 +15,11 @@
<div class="row mt-2">
<% if search %>
<div class="col-4">
<div class="col-md-6">
<p class="subtitle"><%= subtitle %></p>
</div>
<div class="col-8">
<div class="col-md-6 mb-4">
<% if admin_invite_registration %>
<div id="invite-user" class="d-inline-block float-right ml-3">
<%= link_to "#inviteModal", :class => "btn btn-primary", "data-toggle": "modal" do %>

View File

@ -27,7 +27,7 @@
<span class="input-icon-addon">
<i class="fas fa-envelope"></i>
</span>
<%= f.text_field :email, class: "form-control", value: "", placeholder: t("modal.invite_user.email_placeholder"), autocomplete: :off %>
<%= f.email_field :email, class: "form-control", value: "", placeholder: t("modal.invite_user.email_placeholder"), autocomplete: :off %>
<div class="invalid-feedback text-left"><%= t("modal.invite_user.not_blank") %></div>
</div>
<div class="mt-4">

View File

@ -13,63 +13,56 @@
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
%>
<%= form_for @user, url: update_user_path, method: :patch do |f| %>
<%= form_for @user, url: update_user_path, method: :post do |f| %>
<%= hidden_field_tag :setting, "account" %>
<div class="form-group">
<div class="row">
<div class="col-6">
<%= f.label t("settings.account.fullname"), class: "form-label" %>
<div class="col-sm-6 mb-4">
<%= f.label :name, t("settings.account.fullname"), class: "form-label" %>
<div class="input-icon">
<%= f.text_field :name, class: "form-control #{form_is_invalid?(@user, :name)}", placeholder: t("settings.account.fullname") %>
<%= f.text_field :name, class: "form-control #{form_is_invalid?(@user, :name)}", placeholder: t("settings.account.fullname"), readonly: !@user.greenlight_account? %>
</div>
</div>
<div class="col-6">
<%= f.label t("email"), class: "form-label" %>
<div class="col-sm-6 mb-4">
<%= f.label :email, t("email"), class: "form-label" %>
<div class="input-icon">
<%= f.text_field :email, class: "form-control #{form_is_invalid?(@user, :email)}", placeholder: t("email"), readonly: !@user.greenlight_account? %>
<%= f.email_field :email, class: "form-control #{form_is_invalid?(@user, :email)}", placeholder: t("email"), readonly: !@user.greenlight_account? %>
</div>
</div>
</div>
<br>
<%= f.label t("settings.account.provider"), class: "form-label" %>
<%= f.label :provider, t("settings.account.provider"), class: "form-label" %>
<%= f.text_field :provider, class: "form-control", readonly: "" %>
<br>
<%= f.label t("settings.account.language"), class: "form-label" %>
<%= f.label :language, t("settings.account.language"), class: "form-label" %>
<%= f.select :language, language_options, {}, { class: "form-control custom-select" } %>
<% current_user_role = current_user.highest_priority_role %>
<br>
<br>
<%= f.label t("settings.account.roles"), class: "form-label" %>
<div id="role-tag-container" class="tags mb-1">
<% @user.roles.by_priority.each do |role| %>
<span id="<%= "user-role-tag_#{role.id}" %>" style="<%= "background-color: #{role_colour(role)};border-color: #{role_colour(role)};" %>" class="tag user-role-tag">
<%= translated_role_name(role) %>
<% if (current_user_role.get_permission("can_manage_users") || current_user_role.name == "super_admin") && (role.priority > current_user_role.priority || current_user_role.name == "admin") %>
<a data-role-id="<%= role.id %>" class="tag-addon clear-role">
<i data-role-id="<%= role.id %>" class="fas fa-times"></i>
</a>
<%= f.label :roles, t("settings.account.roles"), class: "form-label mt-5" %>
<% if current_user.role.get_permission("can_manage_users") %>
<select id="role-dropdown" class="selectpicker show-tick" >
<% role_options.each do |role| %>
<option value="<%=role.id%>"><%= translated_role_name(role) %></option>
<% end %>
</select>
<%= f.hidden_field :role_id, id: "user_role_id", value: @user.role.id %>
<% else %>
<span style="<%= "background-color: #{role_colour(@user.role)};border-color: #{role_colour(@user.role)};" %>" class="tag custom-role-tag">
<%= translated_role_name(@user.role) %>
</span>
<% end %>
</div>
<% if current_user_role.get_permission("can_manage_users") || current_user_role.name == "super_admin" %>
<% provider = Rails.configuration.loadbalanced_configuration ? current_user.provider : "greenlight" %>
<%= f.select :roles, Role.editable_roles(@user_domain).map{|role| [translated_role_name(role), role.id, {'data-colour' => role_colour(role)}]}.unshift(["", nil, {'data-colour' => nil}]), {disabled: disabled_roles(@user)}, { class: "form-control custom-select", id: "role-select-dropdown" } %>
<% end %>
<%= f.hidden_field :role_ids, id: "user_role_ids", value: @user.roles.by_priority.pluck(:id).uniq %>
<%= f.label t("settings.account.image"), class: "form-label mt-5" %>
<%= f.label :image, t("settings.account.image"), class: "form-label mt-5" %>
<div class="row">
<div class="col-2">
<% if @user.image.blank? %>
<div class="col-5 col-sm-2">
<% if @user.image.blank? || !valid_url?(@user.image) %>
<span class="avatar avatar-xxl mr-5 mt-2 bg-primary"><%= @user.name.first %></span>
<% else %>
<span class="avatar avatar-xxl mr-5 mt-2" style="background-image: url(<%= @user.image %>)"></span>
<%= image_tag(@user.image, class: "avatar avatar-xxl mr-5 mt-2") %>
<% end %>
</div>
<div class="col-10 mt-5">
<div class="col-7 col-sm-10 mt-5">
<%= f.text_field :image, class: "form-control #{form_is_invalid?(@user, :image)}", placeholder: t("settings.account.image_url") %>
</div>
</div>
@ -78,7 +71,7 @@
<%= f.submit t("update"), class: "btn btn-primary float-right ml-4" %>
<% if can_reset_password %>
<%= link_to "Reset user password", admin_reset_path(user_uid: @user.uid), class: "btn btn-primary float-right" %>
<%= link_to t("settings.account.reset_password"), admin_reset_path(user_uid: @user.uid), class: "btn btn-primary float-right" %>
<% end %>
</div>
<% end %>

View File

@ -13,7 +13,7 @@
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
%>
<%= form_for @user, url: update_user_path, method: :patch do |f| %>
<%= form_for @user, url: update_password_path, method: :post do |f| %>
<%= hidden_field_tag :setting, "password" %>
<div class="form-group">
<div class="row">

View File

@ -126,7 +126,7 @@ module Greenlight
config.maintenance_mode = ENV["MAINTENANCE_MODE"] == "true"
config.report_issue_url = ENV["REPORT_ISSUE_URL"]
config.help_url = ENV["HELP_URL"].presence || "https://docs.bigbluebutton.org/greenlight/gl-overview.html"
config.help_url = ENV["HELP_URL"].nil? ? "https://docs.bigbluebutton.org/greenlight/gl-overview.html" : ENV["HELP_URL"]
# DEFAULTS

View File

@ -43,6 +43,18 @@ en:
placeholder: Image Url...
title: Branding Image
invalid: Invalid URL
legal:
change: Change URL
info: Change the Legal Link that appears in the bottom of the page
placeholder: Legal URL...
title: Legal
invalid: Invalid URL
privpolicy:
change: Change URL
info: Change the Privacy Policy Link that appears in the bottom of the page
placeholder: Privacy Policy URL...
title: Privacy Policy
invalid: Invalid URL
cache:
info: Clears the stored provider cache which forces a new request for the updated info
title: Clear Provider Cache
@ -145,9 +157,12 @@ en:
rooms:
title: Server Rooms
table:
ended: "Ended: %{session}"
id: ID
not_running: Not Running
participants: Participants
running: Running
started: "Started: %{session}"
status: Status
view: View
title: Organization Settings
@ -246,6 +261,8 @@ en:
designs: Custom Designs
authentication: User Authentication
footer:
legal: Legal
privpolicy: Privacy Policy
powered_by: Powered by %{href}.
forgot_password:
subtitle: Forgot Password
@ -368,7 +385,7 @@ en:
warning: You will <b>not</b> be able to recover this room
recording_warning: or any of its %{recordings_num} associated recordings.
invite_user:
email_placeholder: Enter the users' emails (seperated by commas)
email_placeholder: Enter the users' emails (separated by commas)
footer: The user will receive an email with instructions on how to sign up
send: Send Invite
title: Invite User
@ -469,6 +486,7 @@ en:
remove: Remove
rename: Rename
reset_password:
invalid_token: Password reset token is invalid. Please try resetting your password again.
subtitle: Reset Password
password: New Password
confirm: New Password Confirmation
@ -534,9 +552,10 @@ en:
provider: Provider
image: Image
image_url: Profile Image URL
roles: User Roles
roles: User Role
subtitle: Update your Account Info
title: Account Info
reset_password: Reset user password
delete:
button: Yes, I would like to delete my account.
disclaimer: If you choose to delete your account, it will <b>NOT</b> be recoverable. All information regarding your account, including settings, rooms, and recording will be removed.

View File

@ -17,6 +17,9 @@ port ENV.fetch("PORT") { 80 }
#
environment ENV.fetch("RAILS_ENV") { "development" }
# Specifies the `pidfile` that Puma will use.
pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
# Specifies the number of `workers` to boot in clustered mode.
# Workers are forked webserver processes. If using threads and workers together
# the concurrency of the application would be max `threads` * `workers`.

View File

@ -88,13 +88,14 @@ Rails.application.routes.draw do
post '/login', to: 'sessions#create', as: :create_session
# Log the user out of the session.
get '/logout', to: 'sessions#destroy'
post '/logout', to: 'sessions#destroy'
# Account management.
get '/:user_uid/edit', to: 'users#edit', as: :edit_user
get '/:user_uid/change_password', to: 'users#change_password', as: :change_password
get '/:user_uid/delete_account', to: 'users#delete_account', as: :delete_account
patch '/:user_uid/edit', to: 'users#update', as: :update_user
post '/:user_uid/edit', to: 'users#update', as: :update_user
post '/:user_uid/change_password', to: 'users#update_password', as: :update_password
delete '/:user_uid', to: 'users#destroy', as: :delete_user
# All user recordings
@ -106,6 +107,9 @@ Rails.application.routes.draw do
get '/auth/failure', to: 'sessions#omniauth_fail'
post '/auth/ldap', to: 'sessions#ldap', as: :ldap_callback
# Users who can't create rooms
get '/rooms', to: 'rooms#cant_create_rooms', as: :cant_create_rooms
# Room resources.
resources :rooms, only: [:create, :show, :destroy], param: :room_uid, path: '/'

View File

@ -19,7 +19,7 @@ class RolifyCreateRoles < ActiveRecord::Migration[5.0]
add_index(:users_roles, [:user_id, :role_id])
User.all.each do |user|
user.add_role(:user) if user.roles.blank?
user.set_role(:user) if user.roles.blank?
end
end
end

View File

@ -0,0 +1,29 @@
# frozen_string_literal: true
class MigrationProduct < ActiveRecord::Base
self.table_name = :users
end
class SubMigrationProduct < ActiveRecord::Base
self.table_name = :roles
end
class AddRoleIdToUsers < ActiveRecord::Migration[5.2]
def change
reversible do |dir|
dir.up do
add_reference :users, :role, index: true
MigrationProduct.where(role_id: nil).each do |user|
highest_role = SubMigrationProduct.joins("INNER JOIN users_roles ON users_roles.role_id = roles.id")
.where("users_roles.user_id = '#{user.id}'").min_by(&:priority).id
user.update_attributes(role_id: highest_role) unless highest_role.nil?
end
end
dir.down do
remove_reference :users, :role, index: true
end
end
end
end

View File

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2020_01_30_144841) do
ActiveRecord::Schema.define(version: 2020_04_13_150518) do
create_table "features", force: :cascade do |t|
t.integer "setting_id"
@ -120,11 +120,13 @@ ActiveRecord::Schema.define(version: 2020_01_30_144841) do
t.string "activation_digest"
t.datetime "activated_at"
t.boolean "deleted", default: false, null: false
t.integer "role_id"
t.index ["created_at"], name: "index_users_on_created_at"
t.index ["deleted"], name: "index_users_on_deleted"
t.index ["email"], name: "index_users_on_email"
t.index ["password_digest"], name: "index_users_on_password_digest", unique: true
t.index ["provider"], name: "index_users_on_provider"
t.index ["role_id"], name: "index_users_on_role_id"
t.index ["room_id"], name: "index_users_on_room_id"
end

View File

@ -145,6 +145,7 @@ input:focus, select:focus {
& a {
color: $primary-color !important;
border-color: $primary-color !important;
white-space: nowrap;
}
& a:hover {

27
lib/tasks/room.rake Normal file
View File

@ -0,0 +1,27 @@
# frozen_string_literal: true
require 'bigbluebutton_api'
namespace :room do
desc "Removes all rooms for users that can't create rooms"
task :remove, [:include_used] => :environment do |_task, args|
roles = Role.where(role_permissions: { name: "can_create_rooms", value: "false" }).pluck(:name)
users = User.with_role(roles)
users.each do |user|
puts "Destroying #{user.uid} rooms"
user.rooms.each do |room|
if room.sessions.positive? && args[:include_used] != "true"
puts "Skipping room #{room.uid}"
next
end
begin
room.destroy(true)
puts "Destroying room #{room.uid}"
rescue => e
puts "Failed to remove room #{room.uid} - #{e}"
end
end
end
end
end

View File

@ -28,7 +28,7 @@ namespace :user do
# Create account if it doesn't exist
if !User.exists?(email: u[:email], provider: u[:provider])
user = User.create(name: u[:name], email: u[:email], password: u[:password],
provider: u[:provider], email_verified: true)
provider: u[:provider], email_verified: true, accepted_terms: true)
unless user.valid?
puts "Invalid Arguments"
@ -38,9 +38,9 @@ namespace :user do
if u[:role] == "super_admin"
user.remove_role(:user)
user.add_role(:super_admin)
user.set_role(:super_admin)
elsif u[:role] == "admin"
user.add_role(:admin)
user.set_role(:admin)
end
puts "Account succesfully created."

View File

@ -70,7 +70,8 @@ describe AccountActivationsController, type: :controller do
it "redirects a pending user to root with a flash" do
@user = create(:user, email_verified: false, provider: "greenlight")
@user.add_role :pending
@user.set_role :pending
@user.reload
get :edit, params: { token: @user.create_activation_token }

View File

@ -25,7 +25,7 @@ describe AdminsController, type: :controller do
@user = create(:user, provider: "provider1")
@admin = create(:user, provider: "provider1")
@admin.add_role :admin
@admin.set_role :admin
end
describe "User Roles" do
@ -78,7 +78,7 @@ describe AdminsController, type: :controller do
context "POST #unban" do
it "unbans the user from the application" do
@request.session[:user_id] = @admin.id
@user.add_role :denied
@user.set_role :denied
expect(@user.has_role?(:denied)).to eq(true)
@ -153,7 +153,7 @@ describe AdminsController, type: :controller do
it "approves a pending user" do
@request.session[:user_id] = @admin.id
@user.add_role :pending
@user.set_role :pending
post :approve, params: { user_uid: @user.uid }
@ -167,7 +167,7 @@ describe AdminsController, type: :controller do
it "sends the user an email telling them theyre approved" do
@request.session[:user_id] = @admin.id
@user.add_role :pending
@user.set_role :pending
params = { user_uid: @user.uid }
expect { post :approve, params: params }.to change { ActionMailer::Base.deliveries.count }.by(1)
end
@ -245,7 +245,7 @@ describe AdminsController, type: :controller do
Role.create_new_role("test", "greenlight").update_all_role_permissions(can_manage_users: true)
@user2 = create(:user)
@user2.add_role(:test)
@user2.set_role(:test)
# Random manage user action test
@ -266,7 +266,7 @@ describe AdminsController, type: :controller do
Role.create_new_role("test", "greenlight").update_all_role_permissions(can_manage_users: false)
@user2 = create(:user)
@user2.add_role(:test)
@user2.set_role(:test)
# Random manage user action test
@ -299,6 +299,40 @@ describe AdminsController, type: :controller do
end
end
context "POST #legal" do
it "changes the legal link on the page" 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
fake_url = "example.com"
post :update_settings, params: { setting: "Legal URL", value: fake_url }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Legal URL")
expect(feature[:value]).to eq(fake_url)
expect(response).to redirect_to(admin_site_settings_path)
end
end
context "POST #privpolicy" do
it "changes the privacy policy on the page" 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
fake_url = "example.com"
post :update_settings, params: { setting: "Privacy Policy URL", value: fake_url }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Privacy Policy URL")
expect(feature[:value]).to eq(fake_url)
expect(response).to redirect_to(admin_site_settings_path)
end
end
context "POST #coloring" do
it "changes the primary on the page" do
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
@ -450,7 +484,7 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id
@admin.add_role :super_admin
@admin.set_role :super_admin
@admin.update_attribute(:provider, "greenlight")
@user2 = create(:user, provider: "provider1")
@user3 = create(:user, provider: "provider1")
@ -479,7 +513,7 @@ describe AdminsController, type: :controller do
it "changes the log level" do
@request.session[:user_id] = @admin.id
@admin.add_role :super_admin
@admin.set_role :super_admin
expect(Rails.logger.level).to eq(0)
post :log_level, params: { value: 2 }
@ -492,7 +526,7 @@ describe AdminsController, type: :controller do
Role.create_new_role("test", "greenlight").update_all_role_permissions(can_edit_site_settings: true)
@user2 = create(:user)
@user2.add_role(:test)
@user2.set_role(:test)
# Random edit site settings action test
@ -510,7 +544,7 @@ describe AdminsController, type: :controller do
Role.create_new_role("test", "greenlight").update_all_role_permissions(can_manage_users: true)
@user2 = create(:user)
@user2.add_role(:test)
@user2.set_role(:test)
# Random edit site settings action test
@ -610,7 +644,7 @@ describe AdminsController, type: :controller do
new_role2 = Role.create_new_role("test2", "provider1")
new_role2.update_permission("can_edit_roles", "true")
@user.roles << new_role2
@user.role = new_role2
@user.save!
@request.session[:user_id] = @user.id
@ -657,7 +691,7 @@ describe AdminsController, type: :controller do
new_role2 = Role.create(name: "test2", priority: 2, provider: "provider1")
new_role2.update_permission("can_edit_roles", "true")
@user.roles << new_role2
@user.role = new_role2
@user.save!
@request.session[:user_id] = @user.id
@ -743,7 +777,7 @@ describe AdminsController, type: :controller do
Role.create_new_role("test", "greenlight").update_all_role_permissions(can_edit_roles: true)
@user2 = create(:user)
@user2.add_role(:test)
@user2.set_role(:test)
# Random edit roles action test
@ -764,7 +798,7 @@ describe AdminsController, type: :controller do
Role.create_new_role("test", "greenlight").update_all_role_permissions(can_manage_users: false)
@user2 = create(:user)
@user2.add_role(:test)
@user2.set_role(:test)
# Random edit roles action test

View File

@ -43,7 +43,7 @@ describe ApplicationController do
end
it "redirects a banned user to a 401 and logs them out" do
@user.add_role :denied
@user.set_role :denied
@request.session[:user_id] = @user.id
get :index
@ -53,7 +53,7 @@ describe ApplicationController do
end
it "redirects a pending user to a 401 and logs them out" do
@user.add_role :pending
@user.set_role :pending
@request.session[:user_id] = @user.id
get :index

View File

@ -19,7 +19,7 @@
require "rails_helper"
def random_valid_user_params
pass = Faker::Internet.password(8)
pass = Faker::Internet.password(min_length: 8)
{
user: {
name: Faker::Name.first_name,
@ -76,11 +76,12 @@ describe PasswordResetsController, type: :controller do
describe "PATCH #update" do
before do
allow(Rails.configuration).to receive(:enable_email_verification).and_return(true)
@user = create(:user, provider: "greenlight")
end
context "valid user" do
it "reloads page with notice if password is empty" do
token = "reset_token"
token = @user.create_reset_digest
allow(controller).to receive(:check_expiration).and_return(nil)
params = {
@ -95,7 +96,7 @@ describe PasswordResetsController, type: :controller do
end
it "reloads page with notice if password is confirmation doesn't match" do
token = "reset_token"
token = @user.create_reset_digest
allow(controller).to receive(:check_expiration).and_return(nil)

View File

@ -63,19 +63,6 @@ describe RoomsController, type: :controller do
expect(response).to render_template(:join)
end
it "should render cant_create_rooms if user doesn't have permission to create rooms" do
user_role = @user.highest_priority_role
user_role.update_permission("can_create_rooms", "false")
user_role.save!
@request.session[:user_id] = @user.id
get :show, params: { room_uid: @user.main_room }
expect(response).to render_template(:cant_create_rooms)
end
it "should be able to search public recordings if user is not owner" do
@request.session[:user_id] = @user.id
@ -117,7 +104,7 @@ describe RoomsController, type: :controller do
it "redirects to admin if user is a super_admin" do
@request.session[:user_id] = @owner.id
@owner.add_role :super_admin
@owner.set_role :super_admin
get :show, params: { room_uid: @owner.main_room, search: :none }
@ -140,7 +127,7 @@ describe RoomsController, type: :controller do
it "redirects to root if owner is pending" do
@request.session[:user_id] = @owner.id
@owner.add_role :pending
@owner.set_role :pending
get :show, params: { room_uid: @owner.main_room, search: :none }
@ -149,7 +136,7 @@ describe RoomsController, type: :controller do
it "redirects to root if owner is banned" do
@request.session[:user_id] = @owner.id
@owner.add_role :denied
@owner.set_role :denied
get :show, params: { room_uid: @owner.main_room, search: :none }
@ -157,6 +144,35 @@ describe RoomsController, type: :controller do
end
end
describe "GET #cant_create_rooms" do
before do
@user = create(:user)
@owner = create(:user)
end
it "renders cant_create_rooms if user doesn't have permission to create rooms and has no shared rooms" do
@user.role.update_permission("can_create_rooms", "false")
@request.session[:user_id] = @user.id
get :cant_create_rooms
expect(response).to render_template(:cant_create_rooms)
end
it "displays the room if the user can't create rooms but has a shared room" do
@user.role.update_permission("can_create_rooms", "false")
SharedAccess.create(room_id: @owner.main_room.id, user_id: @user.id)
@request.session[:user_id] = @user.id
get :cant_create_rooms
expect(response).to redirect_to(@owner.main_room)
end
end
describe "POST #create" do
before do
@owner = create(:user)
@ -406,7 +422,7 @@ describe RoomsController, type: :controller do
it "redirects to root if owner is pending" do
@request.session[:user_id] = @owner.id
@owner.add_role :pending
@owner.set_role :pending
post :join, params: { room_uid: @room }
@ -415,7 +431,7 @@ describe RoomsController, type: :controller do
it "redirects to root if owner is banned" do
@request.session[:user_id] = @owner.id
@owner.add_role :denied
@owner.set_role :denied
post :join, params: { room_uid: @room }
@ -456,7 +472,7 @@ describe RoomsController, type: :controller do
it "allows admin to delete room" do
@admin = create(:user)
@admin.add_role :admin
@admin.set_role :admin
@request.session[:user_id] = @admin.id
expect do
@ -468,7 +484,7 @@ describe RoomsController, type: :controller do
it "does not allow admin to delete a users home room" do
@admin = create(:user)
@admin.add_role :admin
@admin.set_role :admin
@request.session[:user_id] = @admin.id
expect do
@ -483,7 +499,7 @@ describe RoomsController, type: :controller do
allow_any_instance_of(User).to receive(:admin_of?).and_return(false)
@admin = create(:user)
@admin.add_role :admin
@admin.set_role :admin
@request.session[:user_id] = @admin.id
expect do
@ -527,7 +543,7 @@ describe RoomsController, type: :controller do
it "redirects to join path if admin" do
@admin = create(:user)
@admin.add_role :admin
@admin.set_role :admin
@request.session[:user_id] = @admin.id
post :start, params: { room_uid: @user.main_room }
@ -538,7 +554,7 @@ describe RoomsController, type: :controller do
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
@admin.set_role :admin
@request.session[:user_id] = @admin.id
post :start, params: { room_uid: @user.main_room }
@ -587,7 +603,7 @@ describe RoomsController, type: :controller do
it "allows admin to update room settings" do
@admin = create(:user)
@admin.add_role :admin
@admin.set_role :admin
@request.session[:user_id] = @admin.id
room_params = { "mute_on_join": "1", "name": @secondary_room.name }
@ -603,7 +619,7 @@ describe RoomsController, type: :controller do
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
@admin.set_role :admin
@request.session[:user_id] = @admin.id
room_params = { "mute_on_join": "1", "name": @secondary_room.name }
@ -743,7 +759,7 @@ describe RoomsController, type: :controller do
it "allows admins to update room access" do
@admin = create(:user)
@admin.add_role :admin
@admin.set_role :admin
@request.session[:user_id] = @admin.id
post :shared_access, params: { room_uid: @room.uid, add: [@user1.uid] }
@ -756,7 +772,7 @@ describe RoomsController, type: :controller do
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
@admin.set_role :admin
@request.session[:user_id] = @admin.id
post :shared_access, params: { room_uid: @room.uid, add: [] }

View File

@ -75,7 +75,7 @@ describe SessionsController, type: :controller do
before(:each) do
user = create(:user, provider: "greenlight")
@request.session[:user_id] = user.id
get :destroy
post :destroy
end
it "should logout user" do
@ -221,7 +221,7 @@ describe SessionsController, type: :controller do
it "redirects to the admins page for admins" do
user = create(:user, provider: "greenlight",
password: "example", password_confirmation: 'example')
user.add_role :super_admin
user.set_role :super_admin
post :create, params: {
session: {
@ -235,7 +235,7 @@ describe SessionsController, type: :controller do
end
it "should migrate old rooms from the twitter account to the new user" do
twitter_user = User.create(name: "Twitter User", email: "user@twitter.com", image: "example.png",
twitter_user = create(:user, name: "Twitter User", email: "user@twitter.com", image: "example.png",
username: "twitteruser", email_verified: true, provider: 'twitter', social_uid: "twitter-user")
room = Room.new(name: "Test")
@ -383,7 +383,7 @@ describe SessionsController, type: :controller do
it "should notify twitter users that twitter is deprecated" do
allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
twitter_user = User.create(name: "Twitter User", email: "user@twitter.com", image: "example.png",
twitter_user = create(:user, name: "Twitter User", email: "user@twitter.com", image: "example.png",
username: "twitteruser", email_verified: true, provider: 'twitter', social_uid: "twitter-user")
request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:twitter]
@ -394,7 +394,7 @@ describe SessionsController, type: :controller do
end
it "should migrate rooms from the twitter account to the google account" do
twitter_user = User.create(name: "Twitter User", email: "user@twitter.com", image: "example.png",
twitter_user = create(:user, name: "Twitter User", email: "user@twitter.com", image: "example.png",
username: "twitteruser", email_verified: true, provider: 'twitter', social_uid: "twitter-user")
room = Room.new(name: "Test")
@ -419,7 +419,7 @@ describe SessionsController, type: :controller do
allow(Rails.configuration).to receive(:enable_email_verification).and_return(true)
@user = create(:user, provider: "greenlight")
@admin = create(:user, provider: "greenlight", email: "test@example.com")
@admin.add_role :admin
@admin.set_role :admin
end
it "should notify admin on new user signup with approve/reject registration" do

View File

@ -19,7 +19,7 @@
require "rails_helper"
def random_valid_user_params
pass = Faker::Internet.password(8)
pass = Faker::Internet.password(min_length: 8)
{
user: {
name: Faker::Name.first_name,
@ -75,7 +75,7 @@ describe UsersController, type: :controller do
controller.instance_variable_set(:@user_domain, "provider1")
user = create(:user, provider: "provider1")
user.add_role :admin
user.set_role :admin
user2 = create(:user, provider: "provider1")
@request.session[:user_id] = user.id
@ -174,7 +174,7 @@ describe UsersController, type: :controller do
allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
@user = create(:user, provider: "greenlight")
@admin = create(:user, provider: "greenlight", email: "test@example.com")
@admin.add_role :admin
@admin.set_role :admin
end
it "should notify admins that user signed up" do
@ -232,7 +232,7 @@ describe UsersController, type: :controller do
allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
@user = create(:user, provider: "greenlight")
@admin = create(:user, provider: "greenlight", email: "test@example.com")
@admin.add_role :admin
@admin.set_role :admin
end
it "allows any user to sign up" do
@ -278,13 +278,13 @@ describe UsersController, type: :controller do
end
end
describe "PATCH #update" do
describe "POST #update" do
it "properly updates user attributes" do
user = create(:user)
@request.session[:user_id] = user.id
params = random_valid_user_params
patch :update, params: params.merge!(user_uid: user)
post :update, params: params.merge!(user_uid: user)
user.reload
expect(user.name).to eql(params[:user][:name])
@ -293,11 +293,26 @@ describe UsersController, type: :controller do
expect(response).to redirect_to(edit_user_path(user))
end
it "properly updates user attributes" do
allow_any_instance_of(User).to receive(:greenlight_account?).and_return(false)
user = create(:user)
@request.session[:user_id] = user.id
params = random_valid_user_params
post :update, params: params.merge!(user_uid: user)
user.reload
expect(user.name).not_to eql(params[:user][:name])
expect(user.email).not_to eql(params[:user][:email])
expect(flash[:success]).to be_present
expect(response).to redirect_to(edit_user_path(user))
end
it "renders #edit on unsuccessful save" do
@user = create(:user)
@request.session[:user_id] = @user.id
patch :update, params: invalid_params.merge!(user_uid: @user)
post :update, params: invalid_params.merge!(user_uid: @user)
expect(response).to render_template(:edit)
end
@ -306,7 +321,7 @@ describe UsersController, type: :controller do
user = create(:user)
@request.session[:user_id] = user.id
user_role = user.highest_priority_role
user_role = user.role
user_role.update_permission("can_manage_users", "true")
@ -315,30 +330,7 @@ describe UsersController, type: :controller do
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 })
expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_assignment"))
expect(response).to render_template(:edit)
end
it "should fail to update roles if a user tries to remove a role with a higher priority than their own" do
user = create(:user)
admin = create(:user)
admin.add_role :admin
@request.session[:user_id] = user.id
user_role = user.highest_priority_role
user_role.update_permission("can_manage_users", "true")
user_role.save!
params = random_valid_user_params
patch :update, params: params.merge!(user_uid: admin, user: { role_ids: "" })
user.reload
post :update, params: params.merge!(user_uid: user, user: { role_id: tmp_role.id.to_s })
expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_assignment"))
expect(response).to render_template(:edit)
@ -350,53 +342,88 @@ describe UsersController, type: :controller do
user = create(:user)
admin = create(:user)
admin.add_role :admin
admin.set_role :admin
@request.session[:user_id] = admin.id
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: 3, provider: "greenlight")
params = random_valid_user_params
params = params.merge!(user_uid: user, user: { role_ids: "#{tmp_role1.id} #{tmp_role2.id}" })
params = params.merge!(user_uid: user, user: { role_id: tmp_role1.id.to_s })
expect { patch :update, params: params }.to change { ActionMailer::Base.deliveries.count }.by(1)
expect { post :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(user.role.name).to eq("test1")
expect(response).to redirect_to(admins_path)
end
it "all users must at least have the user role" do
allow(Rails.configuration).to receive(:enable_email_verification).and_return(true)
user = create(:user)
admin = create(:user)
admin.add_role :admin
tmp_role1 = Role.create(name: "test1", priority: 2, provider: "greenlight")
tmp_role1.update_permission("send_demoted_email", "true")
user.roles << tmp_role1
user.save!
@request.session[:user_id] = admin.id
params = random_valid_user_params
params = params.merge!(user_uid: user, user: { role_ids: "" })
expect { patch :update, params: params }.to change { ActionMailer::Base.deliveries.count }.by(1)
expect(user.roles.count).to eq(1)
expect(user.highest_priority_role.name).to eq("user")
expect(response).to redirect_to(admins_path)
end
end
describe "POST #update_password" do
before do
@user = create(:user)
@password = Faker::Internet.password(min_length: 8)
end
it "properly updates users password" do
@request.session[:user_id] = @user.id
params = {
user: {
password: @user.password,
new_password: @password,
password_confirmation: @password,
}
}
post :update_password, params: params.merge!(user_uid: @user)
@user.reload
expect(@user.authenticate(@password)).not_to be false
expect(@user.errors).to be_empty
expect(flash[:success]).to be_present
expect(response).to redirect_to(change_password_path(@user))
end
it "doesn't update the users password if initial password is incorrect" do
@request.session[:user_id] = @user.id
params = {
user: {
password: "incorrect_password",
new_password: @password,
password_confirmation: @password,
}
}
post :update_password, params: params.merge!(user_uid: @user)
@user.reload
expect(@user.authenticate(@password)).to be false
expect(response).to render_template(:change_password)
end
it "doesn't update the users password if new passwords don't match" do
@request.session[:user_id] = @user.id
params = {
user: {
password: "incorrect_password",
new_password: @password,
password_confirmation: @password + "_random_string",
}
}
post :update_password, params: params.merge!(user_uid: @user)
@user.reload
expect(@user.authenticate(@password)).to be false
expect(response).to render_template(:change_password)
end
end
describe "DELETE #user" do
before { allow(Rails.configuration).to receive(:allow_user_signup).and_return(true) }
before do
allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
Role.create_default_roles("provider1")
end
it "permanently deletes user" do
user = create(:user)
@ -416,7 +443,7 @@ describe UsersController, type: :controller do
user = create(:user, provider: "provider1")
admin = create(:user, provider: "provider1")
admin.add_role :admin
admin.set_role :admin
@request.session[:user_id] = admin.id
delete :destroy, params: { user_uid: user.uid }
@ -434,7 +461,7 @@ describe UsersController, type: :controller do
user = create(:user, provider: "provider1")
admin = create(:user, provider: "provider1")
admin.add_role :admin
admin.set_role :admin
@request.session[:user_id] = admin.id
delete :destroy, params: { user_uid: user.uid, permanent: "true" }
@ -452,7 +479,7 @@ describe UsersController, type: :controller do
user = create(:user, provider: "provider1")
admin = create(:user, provider: "provider1")
admin.add_role :admin
admin.set_role :admin
@request.session[:user_id] = admin.id
uid = user.main_room.uid
@ -473,7 +500,7 @@ describe UsersController, type: :controller do
user = create(:user, provider: "provider1")
admin = create(:user, provider: "provider2")
admin.add_role :admin
admin.set_role :admin
@request.session[:user_id] = admin.id
delete :destroy, params: { user_uid: user.uid }

View File

@ -18,7 +18,7 @@
FactoryBot.define do
factory :user do
password = Faker::Internet.password(8)
password = Faker::Internet.password(min_length: 8)
provider { %w(google twitter).sample }
uid { rand(10**8) }
name { Faker::Name.first_name }
@ -29,6 +29,7 @@ FactoryBot.define do
accepted_terms { true }
email_verified { true }
activated_at { Time.zone.now }
role { set_role(:user) }
end
factory :room do

View File

@ -170,12 +170,12 @@ describe User, type: :model do
allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true)
@admin = create(:user, provider: @user.provider)
@admin.add_role :admin
@admin.set_role :admin
expect(@admin.admin_of?(@user, "can_manage_users")).to be true
@super_admin = create(:user, provider: "test")
@super_admin.add_role :super_admin
@super_admin.set_role :super_admin
expect(@super_admin.admin_of?(@user, "can_manage_users")).to be true
end
@ -188,32 +188,16 @@ describe User, type: :model do
it "should get the highest priority role" do
@admin = create(:user, provider: @user.provider)
@admin.add_role :admin
@admin.set_role :admin
expect(@admin.highest_priority_role.name).to eq("admin")
end
it "should skip adding the role if the user already has the role" do
@admin = create(:user, provider: @user.provider)
@admin.add_role :admin
@admin.add_role :admin
expect(@admin.roles.count).to eq(2)
expect(@admin.role.name).to eq("admin")
end
it "should add the role if the user doesn't already have the role" do
@admin = create(:user, provider: @user.provider)
@admin.add_role :admin
@admin.set_role :admin
expect(@admin.roles.count).to eq(2)
end
it "should remove the role if the user has the role assigned to them" do
@admin = create(:user, provider: @user.provider)
@admin.add_role :admin
@admin.remove_role :admin
expect(@admin.roles.count).to eq(1)
expect(@admin.has_role?(:admin)).to eq(true)
end
it "has_role? should return false if the user doesn't have the role" do
@ -222,7 +206,7 @@ describe User, type: :model do
it "has_role? should return true if the user has the role" do
@admin = create(:user, provider: @user.provider)
@admin.add_role :admin
@admin.set_role :admin
expect(@admin.has_role?(:admin)).to eq(true)
end
@ -230,8 +214,8 @@ describe User, type: :model do
it "with_role should return all users with the role" do
@admin1 = create(:user, provider: @user.provider)
@admin2 = create(:user, provider: @user.provider)
@admin1.add_role :admin
@admin2.add_role :admin
@admin1.set_role :admin
@admin2.set_role :admin
expect(User.with_role(:admin).count).to eq(2)
end
@ -239,18 +223,11 @@ describe User, type: :model do
it "without_role should return all users without the role" do
@admin1 = create(:user, provider: @user.provider)
@admin2 = create(:user, provider: @user.provider)
@admin1.add_role :admin
@admin2.add_role :admin
@admin1.set_role :admin
@admin2.set_role :admin
expect(User.without_role(:admin).count).to eq(1)
end
it "all_users_with_roles should return all users with at least one role" do
@admin1 = create(:user, provider: @user.provider)
@admin2 = create(:user, provider: @user.provider)
expect(User.all_users_with_roles.count).to eq(3)
end
end
context 'blank email' do

View File

@ -41,7 +41,7 @@ require "action_cable/testing/rspec"
# directory. Alternatively, in the individual `*_spec.rb` files, manually
# require only the support files necessary.
#
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
Dir[Rails.root.join('spec/support/**/*.rb')].sort.each { |f| require f }
# Checks for pending migrations and applies them before tests are run.
# If you are not using ActiveRecord, you can remove this line.

View File

@ -108,6 +108,8 @@ RSpec.configure do |config|
<GOOGLE_HD/>
</user>
</response>", headers: {}) if ENV['LOADBALANCER_ENDPOINT']
Role.create_default_roles("greenlight")
end
# rspec-expectations config goes here. You can use an alternate