forked from External/greenlight
		
	Merge branch 'v2.1.1' of github.com:bigbluebutton/greenlight into v2.1.1
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -35,6 +35,8 @@ env
 | 
				
			|||||||
# IDEs
 | 
					# IDEs
 | 
				
			||||||
.idea
 | 
					.idea
 | 
				
			||||||
.idea/**
 | 
					.idea/**
 | 
				
			||||||
 | 
					.vscode
 | 
				
			||||||
 | 
					.vscode/**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config/terms.md
 | 
					config/terms.md
 | 
				
			||||||
coverage*
 | 
					coverage*
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,6 +41,10 @@ Style/MixinUsage:
 | 
				
			|||||||
Style/SymbolArray:
 | 
					Style/SymbolArray:
 | 
				
			||||||
  Enabled: false
 | 
					  Enabled: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Don't use begin blocks when they are not needed.
 | 
				
			||||||
 | 
					Style/RedundantBegin:
 | 
				
			||||||
 | 
					  Enabled: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Use `%`-literal delimiters consistently
 | 
					# Use `%`-literal delimiters consistently
 | 
				
			||||||
Style/PercentLiteralDelimiters:
 | 
					Style/PercentLiteralDelimiters:
 | 
				
			||||||
  Enabled: false
 | 
					  Enabled: false
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -215,7 +215,7 @@ GEM
 | 
				
			|||||||
      rake (>= 0.8.7)
 | 
					      rake (>= 0.8.7)
 | 
				
			||||||
      thor (>= 0.18.1, < 2.0)
 | 
					      thor (>= 0.18.1, < 2.0)
 | 
				
			||||||
    rainbow (3.0.0)
 | 
					    rainbow (3.0.0)
 | 
				
			||||||
    rake (12.3.1)
 | 
					    rake (12.3.2)
 | 
				
			||||||
    random_password (0.1.1)
 | 
					    random_password (0.1.1)
 | 
				
			||||||
    rb-fsevent (0.10.3)
 | 
					    rb-fsevent (0.10.3)
 | 
				
			||||||
    rb-inotify (0.9.10)
 | 
					    rb-inotify (0.9.10)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,8 @@
 | 
				
			|||||||
$(document).on('turbolinks:load', function(){
 | 
					$(document).on('turbolinks:load', function(){
 | 
				
			||||||
  // Stores the current url when the user clicks the sign in button
 | 
					  // Stores the current url when the user clicks the sign in button
 | 
				
			||||||
  $(".sign-in-button").click(function(){
 | 
					  $(".sign-in-button").click(function(){
 | 
				
			||||||
    document.cookie ="return_to=" + window.location.href
 | 
					    var url = [location.protocol, '//', location.host, location.pathname].join('');
 | 
				
			||||||
 | 
					    document.cookie ="return_to=" + url
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Checks to see if the user provided an image url and displays it if they did
 | 
					  // Checks to see if the user provided an image url and displays it if they did
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,6 @@
 | 
				
			|||||||
.btn-primary:active,
 | 
					.btn-primary:active,
 | 
				
			||||||
.btn-primary:active:focus,
 | 
					.btn-primary:active:focus,
 | 
				
			||||||
.btn-primary:active:hover,
 | 
					.btn-primary:active:hover,
 | 
				
			||||||
.btn-primary:focus,
 | 
					 | 
				
			||||||
.btn-primary:hover,
 | 
					.btn-primary:hover,
 | 
				
			||||||
.btn-primary:hover i {
 | 
					.btn-primary:hover i {
 | 
				
			||||||
  background-color: $primary-color-darken !important;
 | 
					  background-color: $primary-color-darken !important;
 | 
				
			||||||
@@ -17,6 +16,13 @@
 | 
				
			|||||||
  color: white !important;
 | 
					  color: white !important;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.btn-primary:focus {
 | 
				
			||||||
 | 
					  background-color: $primary-color-darken !important;
 | 
				
			||||||
 | 
					  border-color: $primary-color-darken !important;
 | 
				
			||||||
 | 
					  color: white !important;
 | 
				
			||||||
 | 
					  box-shadow: 0 0 0 2px $primary-color-lighten !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
a {
 | 
					a {
 | 
				
			||||||
  color: $primary-color !important;
 | 
					  color: $primary-color !important;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -39,7 +45,7 @@ a {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  &:focus {
 | 
					  &:focus {
 | 
				
			||||||
    box-shadow: 0 0 0 2px $primary-color-lighten;
 | 
					    box-shadow: 0 0 0 2px $primary-color-lighten !important;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,6 +32,10 @@ class AccountActivationsController < ApplicationController
 | 
				
			|||||||
    if @user && !@user.activated? && @user.authenticated?(:activation, params[:token])
 | 
					    if @user && !@user.activated? && @user.authenticated?(:activation, params[:token])
 | 
				
			||||||
      @user.activate
 | 
					      @user.activate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # Redirect user to root with account pending flash if account is still pending
 | 
				
			||||||
 | 
					      return redirect_to root_path,
 | 
				
			||||||
 | 
					        flash: { success: I18n.t("registration.approval.signup") } if @user.has_role?(:pending)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      flash[:success] = I18n.t("verify.activated") + " " + I18n.t("verify.signin")
 | 
					      flash[:success] = I18n.t("verify.activated") + " " + I18n.t("verify.signin")
 | 
				
			||||||
      redirect_to signin_path
 | 
					      redirect_to signin_path
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,10 +18,15 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class AdminsController < ApplicationController
 | 
					class AdminsController < ApplicationController
 | 
				
			||||||
  include Pagy::Backend
 | 
					  include Pagy::Backend
 | 
				
			||||||
 | 
					  include Emailer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  manage_users = [:edit_user, :promote, :demote, :ban_user, :unban_user, :approve]
 | 
				
			||||||
 | 
					  site_settings = [:branding, :coloring, :registration_method]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  authorize_resource class: false
 | 
					  authorize_resource class: false
 | 
				
			||||||
  before_action :find_user, only: [:edit_user, :promote, :demote, :ban_user, :unban_user]
 | 
					  before_action :find_user, only: manage_users
 | 
				
			||||||
  before_action :verify_admin_of_user, only: [:edit_user, :promote, :demote, :ban_user, :unban_user]
 | 
					  before_action :verify_admin_of_user, only: manage_users
 | 
				
			||||||
  before_action :find_setting, only: [:branding, :coloring]
 | 
					  before_action :find_setting, only: site_settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # GET /admins
 | 
					  # GET /admins
 | 
				
			||||||
  def index
 | 
					  def index
 | 
				
			||||||
@@ -29,19 +34,11 @@ class AdminsController < ApplicationController
 | 
				
			|||||||
    @order_column = params[:column] && params[:direction] != "none" ? params[:column] : "created_at"
 | 
					    @order_column = params[:column] && params[:direction] != "none" ? params[:column] : "created_at"
 | 
				
			||||||
    @order_direction = params[:direction] && params[:direction] != "none" ? params[:direction] : "DESC"
 | 
					    @order_direction = params[:direction] && params[:direction] != "none" ? params[:direction] : "DESC"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if Rails.configuration.loadbalanced_configuration
 | 
					    @pagy, @users = pagy(user_list)
 | 
				
			||||||
      @pagy, @users = pagy(User.without_role(:super_admin)
 | 
					 | 
				
			||||||
                  .where(provider: user_settings_provider)
 | 
					 | 
				
			||||||
                  .where.not(id: current_user.id)
 | 
					 | 
				
			||||||
                  .admins_search(@search)
 | 
					 | 
				
			||||||
                  .admins_order(@order_column, @order_direction))
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
      @pagy, @users = pagy(User.where.not(id: current_user.id)
 | 
					 | 
				
			||||||
                      .admins_search(@search)
 | 
					 | 
				
			||||||
                      .admins_order(@order_column, @order_direction))
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # MANAGE USERS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # GET /admins/edit/:user_uid
 | 
					  # GET /admins/edit/:user_uid
 | 
				
			||||||
  def edit_user
 | 
					  def edit_user
 | 
				
			||||||
    render "admins/index", locals: { setting_id: "account" }
 | 
					    render "admins/index", locals: { setting_id: "account" }
 | 
				
			||||||
@@ -59,6 +56,48 @@ class AdminsController < ApplicationController
 | 
				
			|||||||
    redirect_to admins_path, flash: { success: I18n.t("administrator.flash.demoted") }
 | 
					    redirect_to admins_path, flash: { success: I18n.t("administrator.flash.demoted") }
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # POST /admins/ban/:user_uid
 | 
				
			||||||
 | 
					  def ban_user
 | 
				
			||||||
 | 
					    @user.remove_role :pending if @user.has_role? :pending
 | 
				
			||||||
 | 
					    @user.add_role :denied
 | 
				
			||||||
 | 
					    redirect_to admins_path, flash: { success: I18n.t("administrator.flash.banned") }
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # POST /admins/unban/:user_uid
 | 
				
			||||||
 | 
					  def unban_user
 | 
				
			||||||
 | 
					    @user.remove_role :denied
 | 
				
			||||||
 | 
					    redirect_to admins_path, flash: { success: I18n.t("administrator.flash.unbanned") }
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # POST /admins/approve/:user_uid
 | 
				
			||||||
 | 
					  def approve
 | 
				
			||||||
 | 
					    @user.remove_role :pending
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    send_user_approved_email(@user)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    redirect_to admins_path, flash: { success: I18n.t("administrator.flash.approved") }
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # POST /admins/invite
 | 
				
			||||||
 | 
					  def invite
 | 
				
			||||||
 | 
					    email = params[:invite_user][:email]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    begin
 | 
				
			||||||
 | 
					      invitation = create_or_update_invite(email)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      send_invitation_email(current_user.name, email, invitation.invite_token)
 | 
				
			||||||
 | 
					    rescue => e
 | 
				
			||||||
 | 
					      logger.error "Error in email delivery: #{e}"
 | 
				
			||||||
 | 
					      flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      flash[:success] = I18n.t("administrator.flash.invite", email: email)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    redirect_to admins_path
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # SITE SETTINGS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # POST /admins/branding
 | 
					  # POST /admins/branding
 | 
				
			||||||
  def branding
 | 
					  def branding
 | 
				
			||||||
    @settings.update_value("Branding Image", params[:url])
 | 
					    @settings.update_value("Branding Image", params[:url])
 | 
				
			||||||
@@ -68,19 +107,22 @@ class AdminsController < ApplicationController
 | 
				
			|||||||
  # POST /admins/color
 | 
					  # POST /admins/color
 | 
				
			||||||
  def coloring
 | 
					  def coloring
 | 
				
			||||||
    @settings.update_value("Primary Color", params[:color])
 | 
					    @settings.update_value("Primary Color", params[:color])
 | 
				
			||||||
    redirect_to admins_path(setting: "site_settings")
 | 
					    redirect_to admins_path
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # POST /admins/ban/:user_uid
 | 
					  # POST /admins/registration_method/:method
 | 
				
			||||||
  def ban_user
 | 
					  def registration_method
 | 
				
			||||||
    @user.add_role :denied
 | 
					    new_method = Rails.configuration.registration_methods[params[:method].to_sym]
 | 
				
			||||||
    redirect_to admins_path, flash: { success: I18n.t("administrator.flash.banned") }
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # POST /admins/unban/:user_uid
 | 
					    # Only allow change to Join by Invitation if user has emails enabled
 | 
				
			||||||
  def unban_user
 | 
					    if !Rails.configuration.enable_email_verification && new_method == Rails.configuration.registration_methods[:invite]
 | 
				
			||||||
    @user.remove_role :denied
 | 
					      redirect_to admins_path,
 | 
				
			||||||
    redirect_to admins_path, flash: { success: I18n.t("administrator.flash.unbanned") }
 | 
					        flash: { alert: I18n.t("administrator.flash.invite_email_verification") }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      @settings.update_value("Registration Method", new_method)
 | 
				
			||||||
 | 
					      redirect_to admins_path,
 | 
				
			||||||
 | 
					        flash: { success: I18n.t("administrator.flash.registration_method_updated") }
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private
 | 
					  private
 | 
				
			||||||
@@ -97,4 +139,35 @@ class AdminsController < ApplicationController
 | 
				
			|||||||
    redirect_to admins_path,
 | 
					    redirect_to admins_path,
 | 
				
			||||||
      flash: { alert: I18n.t("administrator.flash.unauthorized") } unless current_user.admin_of?(@user)
 | 
					      flash: { alert: I18n.t("administrator.flash.unauthorized") } unless current_user.admin_of?(@user)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Gets the list of users based on your configuration
 | 
				
			||||||
 | 
					  def user_list
 | 
				
			||||||
 | 
					    if Rails.configuration.loadbalanced_configuration
 | 
				
			||||||
 | 
					      User.without_role(:super_admin)
 | 
				
			||||||
 | 
					          .where(provider: user_settings_provider)
 | 
				
			||||||
 | 
					          .where.not(id: current_user.id)
 | 
				
			||||||
 | 
					          .admins_search(@search)
 | 
				
			||||||
 | 
					          .admins_order(@order_column, @order_direction)
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      User.where.not(id: current_user.id)
 | 
				
			||||||
 | 
					          .admins_search(@search)
 | 
				
			||||||
 | 
					          .admins_order(@order_column, @order_direction)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Creates the invite if it doesn't exist, or updates the updated_at time if it does
 | 
				
			||||||
 | 
					  def create_or_update_invite(email)
 | 
				
			||||||
 | 
					    invite = Invitation.find_by(email: email, provider: @user_domain)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Invite already exists
 | 
				
			||||||
 | 
					    if invite.present?
 | 
				
			||||||
 | 
					      # Updates updated_at to now
 | 
				
			||||||
 | 
					      invite.touch
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      # Creates invite
 | 
				
			||||||
 | 
					      invite = Invitation.create(email: email, provider: @user_domain)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    invite
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,7 @@
 | 
				
			|||||||
require 'bigbluebutton_api'
 | 
					require 'bigbluebutton_api'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ApplicationController < ActionController::Base
 | 
					class ApplicationController < ActionController::Base
 | 
				
			||||||
 | 
					  include ApplicationHelper
 | 
				
			||||||
  include SessionsHelper
 | 
					  include SessionsHelper
 | 
				
			||||||
  include ThemingHelper
 | 
					  include ThemingHelper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -26,7 +27,7 @@ class ApplicationController < ActionController::Base
 | 
				
			|||||||
  before_action :set_locale
 | 
					  before_action :set_locale
 | 
				
			||||||
  before_action :check_admin_password
 | 
					  before_action :check_admin_password
 | 
				
			||||||
  before_action :set_user_domain
 | 
					  before_action :set_user_domain
 | 
				
			||||||
  before_action :check_if_unbanned
 | 
					  before_action :check_user_role
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Force SSL for loadbalancer configurations.
 | 
					  # Force SSL for loadbalancer configurations.
 | 
				
			||||||
  before_action :redirect_to_https
 | 
					  before_action :redirect_to_https
 | 
				
			||||||
@@ -84,7 +85,7 @@ class ApplicationController < ActionController::Base
 | 
				
			|||||||
  helper_method :recording_thumbnails?
 | 
					  helper_method :recording_thumbnails?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def allow_greenlight_users?
 | 
					  def allow_greenlight_users?
 | 
				
			||||||
    Rails.configuration.greenlight_accounts
 | 
					    allow_greenlight_accounts?
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
  helper_method :allow_greenlight_users?
 | 
					  helper_method :allow_greenlight_users?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -136,11 +137,14 @@ class ApplicationController < ActionController::Base
 | 
				
			|||||||
  helper_method :set_user_domain
 | 
					  helper_method :set_user_domain
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Checks if the user is banned and logs him out if he is
 | 
					  # Checks if the user is banned and logs him out if he is
 | 
				
			||||||
  def check_if_unbanned
 | 
					  def check_user_role
 | 
				
			||||||
    if current_user&.has_role?(:denied)
 | 
					    if current_user&.has_role? :denied
 | 
				
			||||||
      session.delete(:user_id)
 | 
					      session.delete(:user_id)
 | 
				
			||||||
      redirect_to unauthorized_path
 | 
					      redirect_to root_path, flash: { alert: I18n.t("registration.banned.fail") }
 | 
				
			||||||
 | 
					    elsif current_user&.has_role? :pending
 | 
				
			||||||
 | 
					      session.delete(:user_id)
 | 
				
			||||||
 | 
					      redirect_to root_path, flash: { alert: I18n.t("registration.approval.fail") }
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
  helper_method :check_if_unbanned
 | 
					  helper_method :check_user_role
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,12 +31,32 @@ module Emailer
 | 
				
			|||||||
    UserMailer.password_reset(@user, reset_link, logo_image, user_color).deliver_now
 | 
					    UserMailer.password_reset(@user, reset_link, logo_image, user_color).deliver_now
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Sends inivitation to join
 | 
				
			||||||
 | 
					  def send_invitation_email(name, email, token)
 | 
				
			||||||
 | 
					    @token = token
 | 
				
			||||||
 | 
					    UserMailer.invite_email(name, email, invitation_link, logo_image, user_color).deliver_now
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def send_user_approved_email(user)
 | 
				
			||||||
 | 
					    UserMailer.approve_user(user, root_url, logo_image, user_color).deliver_now
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Returns the link the user needs to click to verify their account
 | 
					  # Returns the link the user needs to click to verify their account
 | 
				
			||||||
  def user_verification_link
 | 
					  def user_verification_link
 | 
				
			||||||
    request.base_url + edit_account_activation_path(token: @user.activation_token, email: @user.email)
 | 
					    edit_account_activation_url(token: @user.activation_token, email: @user.email)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def reset_link
 | 
					  def reset_link
 | 
				
			||||||
    request.base_url + edit_password_reset_path(@user.reset_token, email: @user.email)
 | 
					    edit_password_reset_url(@user.reset_token, email: @user.email)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def invitation_link
 | 
				
			||||||
 | 
					    if allow_greenlight_users?
 | 
				
			||||||
 | 
					      signup_url(invite_token: @token)
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      root_url(invite_token: @token)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										54
									
								
								app/controllers/concerns/registrar.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								app/controllers/concerns/registrar.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This program is free software; you can redistribute it and/or modify it under the
 | 
				
			||||||
 | 
					# terms of the GNU Lesser General Public License as published by the Free Software
 | 
				
			||||||
 | 
					# Foundation; either version 3.0 of the License, or (at your option) any later
 | 
				
			||||||
 | 
					# version.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
				
			||||||
 | 
					# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 | 
				
			||||||
 | 
					# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU Lesser General Public License along
 | 
				
			||||||
 | 
					# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module Registrar
 | 
				
			||||||
 | 
					  extend ActiveSupport::Concern
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def registration_method
 | 
				
			||||||
 | 
					    Setting.find_or_create_by!(provider: user_settings_provider).get_value("Registration Method")
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def open_registration
 | 
				
			||||||
 | 
					     registration_method == Rails.configuration.registration_methods[:open]
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def approval_registration
 | 
				
			||||||
 | 
					     registration_method == Rails.configuration.registration_methods[:approval]
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def invite_registration
 | 
				
			||||||
 | 
					     registration_method == Rails.configuration.registration_methods[:invite]
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Returns a hash containing whether the user has been invited and if they
 | 
				
			||||||
 | 
					  # signed up with the same email that they were invited with
 | 
				
			||||||
 | 
					  def check_user_invited(email, token, domain)
 | 
				
			||||||
 | 
					    return { present: true, verified: false } unless invite_registration
 | 
				
			||||||
 | 
					    return { present: false, verified: false } if token.nil?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    invite = Invitation.valid.find_by(invite_token: token, provider: domain)
 | 
				
			||||||
 | 
					    if invite.present?
 | 
				
			||||||
 | 
					      # Check if they used the same email to sign up
 | 
				
			||||||
 | 
					      same_email = email.casecmp(invite.email).zero?
 | 
				
			||||||
 | 
					      invite.destroy
 | 
				
			||||||
 | 
					      { present: true, verified: same_email }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      { present: false, verified: false }
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
@@ -17,7 +17,10 @@
 | 
				
			|||||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 | 
					# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MainController < ApplicationController
 | 
					class MainController < ApplicationController
 | 
				
			||||||
 | 
					  include Registrar
 | 
				
			||||||
  # GET /
 | 
					  # GET /
 | 
				
			||||||
  def index
 | 
					  def index
 | 
				
			||||||
 | 
					    # Store invite token
 | 
				
			||||||
 | 
					    session[:invite_token] = params[:invite_token] if params[:invite_token] && invite_registration
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,8 @@
 | 
				
			|||||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 | 
					# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SessionsController < ApplicationController
 | 
					class SessionsController < ApplicationController
 | 
				
			||||||
 | 
					  include Registrar
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  skip_before_action :verify_authenticity_token, only: [:omniauth, :fail]
 | 
					  skip_before_action :verify_authenticity_token, only: [:omniauth, :fail]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # GET /users/logout
 | 
					  # GET /users/logout
 | 
				
			||||||
@@ -32,11 +34,11 @@ class SessionsController < ApplicationController
 | 
				
			|||||||
      user = admin
 | 
					      user = admin
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      user = User.find_by(email: session_params[:email], provider: @user_domain)
 | 
					      user = User.find_by(email: session_params[:email], provider: @user_domain)
 | 
				
			||||||
      redirect_to(root_path, alert: I18n.t("invalid_user")) && return unless user
 | 
					      redirect_to(signin_path, alert: I18n.t("invalid_user")) && return unless user
 | 
				
			||||||
      redirect_to(root_path, alert: I18n.t("invalid_login_method")) && return unless user.greenlight_account?
 | 
					      redirect_to(root_path, alert: I18n.t("invalid_login_method")) && return unless user.greenlight_account?
 | 
				
			||||||
      redirect_to(account_activation_path(email: user.email)) && return unless user.activated?
 | 
					      redirect_to(account_activation_path(email: user.email)) && return unless user.activated?
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
    redirect_to(root_path, alert: I18n.t("invalid_credentials")) && return unless user.try(:authenticate,
 | 
					    redirect_to(signin_path, alert: I18n.t("invalid_credentials")) && return unless user.try(:authenticate,
 | 
				
			||||||
      session_params[:password])
 | 
					      session_params[:password])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    login(user)
 | 
					    login(user)
 | 
				
			||||||
@@ -44,12 +46,27 @@ class SessionsController < ApplicationController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  # GET/POST /auth/:provider/callback
 | 
					  # GET/POST /auth/:provider/callback
 | 
				
			||||||
  def omniauth
 | 
					  def omniauth
 | 
				
			||||||
    user = User.from_omniauth(request.env['omniauth.auth'])
 | 
					    begin
 | 
				
			||||||
 | 
					      @auth = request.env['omniauth.auth']
 | 
				
			||||||
 | 
					      @user_exists = check_user_exists
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # If using invitation registration method, make sure user is invited
 | 
				
			||||||
 | 
					      return redirect_to root_path, flash: { alert: I18n.t("registration.invite.no_invite") } unless passes_invite_reqs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      user = User.from_omniauth(@auth)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # Add pending role if approval method and is a new user
 | 
				
			||||||
 | 
					      if approval_registration && !@user_exists
 | 
				
			||||||
 | 
					        user.add_role :pending
 | 
				
			||||||
 | 
					        return redirect_to root_path, flash: { success: I18n.t("registration.approval.signup") }
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      login(user)
 | 
					      login(user)
 | 
				
			||||||
    rescue => e
 | 
					    rescue => e
 | 
				
			||||||
        logger.error "Error authenticating via omniauth: #{e}"
 | 
					        logger.error "Error authenticating via omniauth: #{e}"
 | 
				
			||||||
        omniauth_fail
 | 
					        omniauth_fail
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # POST /auth/failure
 | 
					  # POST /auth/failure
 | 
				
			||||||
  def omniauth_fail
 | 
					  def omniauth_fail
 | 
				
			||||||
@@ -61,4 +78,17 @@ class SessionsController < ApplicationController
 | 
				
			|||||||
  def session_params
 | 
					  def session_params
 | 
				
			||||||
    params.require(:session).permit(:email, :password)
 | 
					    params.require(:session).permit(:email, :password)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def check_user_exists
 | 
				
			||||||
 | 
					    provider = @auth['provider'] == "bn_launcher" ? @auth['info']['customer'] : @auth['provider']
 | 
				
			||||||
 | 
					    User.exists?(social_uid: @auth['uid'], provider: provider)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Check if the user already exists, if not then check for invitation
 | 
				
			||||||
 | 
					  def passes_invite_reqs
 | 
				
			||||||
 | 
					    return true if @user_exists
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    invitation = check_user_invited("", session[:invite_token], @user_domain)
 | 
				
			||||||
 | 
					    invitation[:present]
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,6 +20,7 @@ class UsersController < ApplicationController
 | 
				
			|||||||
  include RecordingsHelper
 | 
					  include RecordingsHelper
 | 
				
			||||||
  include Pagy::Backend
 | 
					  include Pagy::Backend
 | 
				
			||||||
  include Emailer
 | 
					  include Emailer
 | 
				
			||||||
 | 
					  include Registrar
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  before_action :find_user, only: [:edit, :update, :destroy]
 | 
					  before_action :find_user, only: [:edit, :update, :destroy]
 | 
				
			||||||
  before_action :ensure_unauthenticated, only: [:new, :create]
 | 
					  before_action :ensure_unauthenticated, only: [:new, :create]
 | 
				
			||||||
@@ -32,29 +33,29 @@ class UsersController < ApplicationController
 | 
				
			|||||||
    @user = User.new(user_params)
 | 
					    @user = User.new(user_params)
 | 
				
			||||||
    @user.provider = @user_domain
 | 
					    @user.provider = @user_domain
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Add validation errors to model if they exist
 | 
					    # User or recpatcha is not valid
 | 
				
			||||||
    valid_user = @user.valid?
 | 
					    render(:new) && return unless valid_user_or_captcha
 | 
				
			||||||
    valid_captcha = Rails.configuration.recaptcha_enabled ? verify_recaptcha(model: @user) : true
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if valid_user && valid_captcha
 | 
					    # Redirect to root if user token is either invalid or expired
 | 
				
			||||||
 | 
					    return redirect_to root_path, flash: { alert: I18n.t("registration.invite.fail") } unless passes_invite_reqs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # User has passed all validations required
 | 
				
			||||||
    @user.save
 | 
					    @user.save
 | 
				
			||||||
    else
 | 
					
 | 
				
			||||||
      render(:new) && return
 | 
					    # Set user to pending and redirect if Approval Registration is set
 | 
				
			||||||
 | 
					    if approval_registration
 | 
				
			||||||
 | 
					      @user.add_role :pending
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return redirect_to root_path,
 | 
				
			||||||
 | 
					        flash: { success: I18n.t("registration.approval.signup") } unless Rails.configuration.enable_email_verification
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Sign in automatically if email verification is disabled.
 | 
					    # Sign in automatically if email verification is disabled or if user is already verified.
 | 
				
			||||||
    login(@user) && return unless Rails.configuration.enable_email_verification
 | 
					    login(@user) && return if !Rails.configuration.enable_email_verification || @user.email_verified
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Start email verification and redirect to root.
 | 
					    send_verification
 | 
				
			||||||
    begin
 | 
					
 | 
				
			||||||
      send_activation_email(@user)
 | 
					    redirect_to root_path
 | 
				
			||||||
    rescue => e
 | 
					 | 
				
			||||||
      logger.error "Error in email delivery: #{e}"
 | 
					 | 
				
			||||||
      flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
      flash[:success] = I18n.t("email_sent", email_type: t("verify.verification"))
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
    redirect_to(root_path)
 | 
					 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # GET /signin
 | 
					  # GET /signin
 | 
				
			||||||
@@ -63,11 +64,16 @@ class UsersController < ApplicationController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  # GET /signup
 | 
					  # GET /signup
 | 
				
			||||||
  def new
 | 
					  def new
 | 
				
			||||||
    if Rails.configuration.allow_user_signup
 | 
					    return redirect_to root_path unless Rails.configuration.allow_user_signup
 | 
				
			||||||
      @user = User.new
 | 
					
 | 
				
			||||||
    else
 | 
					    # Check if the user needs to be invited
 | 
				
			||||||
      redirect_to root_path
 | 
					    if invite_registration
 | 
				
			||||||
 | 
					      redirect_to root_path, flash: { alert: I18n.t("registration.invite.no_invite") } unless params[:invite_token]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      session[:invite_token] = params[:invite_token]
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @user = User.new
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # GET /u/:user_uid/edit
 | 
					  # GET /u/:user_uid/edit
 | 
				
			||||||
@@ -174,4 +180,34 @@ class UsersController < ApplicationController
 | 
				
			|||||||
    params.require(:user).permit(:name, :email, :image, :password, :password_confirmation,
 | 
					    params.require(:user).permit(:name, :email, :image, :password, :password_confirmation,
 | 
				
			||||||
      :new_password, :provider, :accepted_terms, :language)
 | 
					      :new_password, :provider, :accepted_terms, :language)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def send_verification
 | 
				
			||||||
 | 
					    # Start email verification and redirect to root.
 | 
				
			||||||
 | 
					    begin
 | 
				
			||||||
 | 
					      send_activation_email(@user)
 | 
				
			||||||
 | 
					    rescue => e
 | 
				
			||||||
 | 
					      logger.error "Error in email delivery: #{e}"
 | 
				
			||||||
 | 
					      flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      flash[:success] = I18n.t("email_sent", email_type: t("verify.verification"))
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Add validation errors to model if they exist
 | 
				
			||||||
 | 
					  def valid_user_or_captcha
 | 
				
			||||||
 | 
					    valid_user = @user.valid?
 | 
				
			||||||
 | 
					    valid_captcha = Rails.configuration.recaptcha_enabled ? verify_recaptcha(model: @user) : true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    valid_user && valid_captcha
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Checks if the user passes the requirements to be invited
 | 
				
			||||||
 | 
					  def passes_invite_reqs
 | 
				
			||||||
 | 
					    # check if user needs to be invited and IS invited
 | 
				
			||||||
 | 
					    invitation = check_user_invited(@user.email, session[:invite_token], @user_domain)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @user.email_verified = true if invitation[:verified]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    invitation[:present]
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,4 +18,31 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
module AdminsHelper
 | 
					module AdminsHelper
 | 
				
			||||||
  include Pagy::Frontend
 | 
					  include Pagy::Frontend
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def display_invite
 | 
				
			||||||
 | 
					    current_page?(admins_path) && invite_registration
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def registration_method
 | 
				
			||||||
 | 
					    Setting.find_or_create_by!(provider: user_settings_provider).get_value("Registration Method")
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def invite_registration
 | 
				
			||||||
 | 
					    registration_method == Rails.configuration.registration_methods[:invite]
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def approval_registration
 | 
				
			||||||
 | 
					    registration_method == Rails.configuration.registration_methods[:approval]
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def registration_method_string
 | 
				
			||||||
 | 
					    case registration_method
 | 
				
			||||||
 | 
					    when Rails.configuration.registration_methods[:open]
 | 
				
			||||||
 | 
					        I18n.t("administrator.site_settings.registration.methods.open")
 | 
				
			||||||
 | 
					    when Rails.configuration.registration_methods[:invite]
 | 
				
			||||||
 | 
					        I18n.t("administrator.site_settings.registration.methods.invite")
 | 
				
			||||||
 | 
					    when Rails.configuration.registration_methods[:approval]
 | 
				
			||||||
 | 
					        I18n.t("administrator.site_settings.registration.methods.approval")
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,4 +34,21 @@ class UserMailer < ApplicationMailer
 | 
				
			|||||||
    @color = color
 | 
					    @color = color
 | 
				
			||||||
    mail to: user.email, subject: t('reset_password.subtitle')
 | 
					    mail to: user.email, subject: t('reset_password.subtitle')
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def invite_email(name, email, url, image, color)
 | 
				
			||||||
 | 
					    @name = name
 | 
				
			||||||
 | 
					    @email = email
 | 
				
			||||||
 | 
					    @url = url
 | 
				
			||||||
 | 
					    @image = image
 | 
				
			||||||
 | 
					    @color = color
 | 
				
			||||||
 | 
					    mail to: email, subject: t('mailer.user.invite.subject')
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def approve_user(user, url, image, color)
 | 
				
			||||||
 | 
					    @user = user
 | 
				
			||||||
 | 
					    @url = url
 | 
				
			||||||
 | 
					    @image = image
 | 
				
			||||||
 | 
					    @color = color
 | 
				
			||||||
 | 
					    mail to: user.email, subject: t('mailer.user.approve.subject')
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										23
									
								
								app/models/invitation.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								app/models/invitation.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This program is free software; you can redistribute it and/or modify it under the
 | 
				
			||||||
 | 
					# terms of the GNU Lesser General Public License as published by the Free Software
 | 
				
			||||||
 | 
					# Foundation; either version 3.0 of the License, or (at your option) any later
 | 
				
			||||||
 | 
					# version.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
				
			||||||
 | 
					# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 | 
				
			||||||
 | 
					# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU Lesser General Public License along
 | 
				
			||||||
 | 
					# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Invitation < ApplicationRecord
 | 
				
			||||||
 | 
					  has_secure_token :invite_token
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  scope :valid, -> { where(updated_at: (Time.now - 48.hours)..Time.now) }
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
@@ -37,6 +37,8 @@ class Setting < ApplicationRecord
 | 
				
			|||||||
        Rails.configuration.branding_image_default
 | 
					        Rails.configuration.branding_image_default
 | 
				
			||||||
      when "Primary Color"
 | 
					      when "Primary Color"
 | 
				
			||||||
        Rails.configuration.primary_color_default
 | 
					        Rails.configuration.primary_color_default
 | 
				
			||||||
 | 
					      when "Registration Method"
 | 
				
			||||||
 | 
					        Rails.configuration.registration_method_default
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,6 +15,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<div class="container text-center pt-9">
 | 
					<div class="container text-center pt-9">
 | 
				
			||||||
  <div class="display-1 text-muted mb-5">401</div>
 | 
					  <div class="display-1 text-muted mb-5">401</div>
 | 
				
			||||||
  <h1 class="h2 mb-3"><%= t("errors.unauthorized.message") %></h1>
 | 
					  <h1 class="h2 mb-3"><%= I18n.t("errors.unauthorized.message") %></h1>
 | 
				
			||||||
  <p class="h4 text-muted font-weight-normal mb-7"><%= t("errors.unauthorized.help") %></p>
 | 
					  <p class="h4 text-muted font-weight-normal mb-7"><%= I18n.t("errors.unauthorized.help") %></p>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,8 +26,11 @@
 | 
				
			|||||||
          </span>
 | 
					          </span>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
      <div class="form-group">
 | 
					  </div>
 | 
				
			||||||
 | 
					  <div class="row">
 | 
				
			||||||
 | 
					    <div class="col-12">
 | 
				
			||||||
 | 
					      <div class="mb-7 form-group">
 | 
				
			||||||
        <label class="form-label"><%= t("administrator.site_settings.color.title") %></label>
 | 
					        <label class="form-label"><%= t("administrator.site_settings.color.title") %></label>
 | 
				
			||||||
        <label class="form-label text-muted"><%= t("administrator.site_settings.color.info") %></label>
 | 
					        <label class="form-label text-muted"><%= t("administrator.site_settings.color.info") %></label>
 | 
				
			||||||
        <div class="row gutters-xs">
 | 
					        <div class="row gutters-xs">
 | 
				
			||||||
@@ -44,4 +47,28 @@
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
 | 
					  <div class="row">
 | 
				
			||||||
 | 
					    <div class="col-12">
 | 
				
			||||||
 | 
					      <div class="form-group">
 | 
				
			||||||
 | 
					        <label class="form-label"><%= t("administrator.site_settings.registration.title") %></label>
 | 
				
			||||||
 | 
					        <label class="form-label text-muted"><%= t("administrator.site_settings.registration.info") %></label>
 | 
				
			||||||
 | 
					        <div class="dropdown">
 | 
				
			||||||
 | 
					          <button class="btn btn-primary dropdown-toggle" type="button" id="registrationMethods" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
 | 
				
			||||||
 | 
					            <%= registration_method_string %>
 | 
				
			||||||
 | 
					          </button>
 | 
				
			||||||
 | 
					          <div class="dropdown-menu" aria-labelledby="registrationMethods">
 | 
				
			||||||
 | 
					            <%= button_to admin_change_registration_path("open"), class: "dropdown-item" do %>
 | 
				
			||||||
 | 
					              <%= t("administrator.site_settings.registration.methods.open") %>
 | 
				
			||||||
 | 
					            <% end %>
 | 
				
			||||||
 | 
					            <%= button_to admin_change_registration_path("invite"), class: "dropdown-item" do %>
 | 
				
			||||||
 | 
					              <%= t("administrator.site_settings.registration.methods.invite") %>
 | 
				
			||||||
 | 
					            <% end %>
 | 
				
			||||||
 | 
					            <%= button_to admin_change_registration_path("approval"), class: "dropdown-item" do %>
 | 
				
			||||||
 | 
					              <%= t("administrator.site_settings.registration.methods.approval") %>
 | 
				
			||||||
 | 
					            <% end %>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -73,6 +73,10 @@
 | 
				
			|||||||
                        <div class="user-role btn btn-sm btn-gray-dark">
 | 
					                        <div class="user-role btn btn-sm btn-gray-dark">
 | 
				
			||||||
                          <%= t("roles.banned") %>
 | 
					                          <%= t("roles.banned") %>
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
 | 
					                      <% elsif roles.include?("pending") %>
 | 
				
			||||||
 | 
					                        <div class="user-role btn btn-sm btn-cyan">
 | 
				
			||||||
 | 
					                          <%= t("roles.pending") %>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
                      <% elsif roles.include?("super_admin") %>
 | 
					                      <% elsif roles.include?("super_admin") %>
 | 
				
			||||||
                        <div class="user-role btn btn-sm btn-red">
 | 
					                        <div class="user-role btn btn-sm btn-red">
 | 
				
			||||||
                          <%= t("roles.super_admin") %>
 | 
					                          <%= t("roles.super_admin") %>
 | 
				
			||||||
@@ -88,7 +92,21 @@
 | 
				
			|||||||
                      <% end %>
 | 
					                      <% end %>
 | 
				
			||||||
                    </td>
 | 
					                    </td>
 | 
				
			||||||
                    <td>
 | 
					                    <td>
 | 
				
			||||||
                      <% unless roles.include?("super_admin") %>
 | 
					                      <% if roles.include?("pending") %>
 | 
				
			||||||
 | 
					                        <div class="item-action dropdown">
 | 
				
			||||||
 | 
					                          <a href="javascript:void(0)" data-toggle="dropdown" class="icon">
 | 
				
			||||||
 | 
					                            <i class="fas fa-ellipsis-v px-4"></i>
 | 
				
			||||||
 | 
					                          </a>
 | 
				
			||||||
 | 
					                          <div class="dropdown-menu dropdown-menu">
 | 
				
			||||||
 | 
					                            <%= button_to admin_approve_path(user_uid: user.uid), class: "dropdown-item" do %>
 | 
				
			||||||
 | 
					                              <i class="dropdown-icon far fa-check-circle"></i> <%= t("administrator.users.settings.approve") %>
 | 
				
			||||||
 | 
					                            <% end %>
 | 
				
			||||||
 | 
					                            <%= button_to admin_ban_path(user_uid: user.uid), class: "dropdown-item" do %>
 | 
				
			||||||
 | 
					                              <i class="dropdown-icon far fa-times-circle"></i> <%= t("administrator.users.settings.decline") %>
 | 
				
			||||||
 | 
					                            <% end %>
 | 
				
			||||||
 | 
					                          </div>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                      <% elsif !roles.include?("super_admin") %>
 | 
				
			||||||
                        <div class="item-action dropdown">
 | 
					                        <div class="item-action dropdown">
 | 
				
			||||||
                          <a href="javascript:void(0)" data-toggle="dropdown" class="icon">
 | 
					                          <a href="javascript:void(0)" data-toggle="dropdown" class="icon">
 | 
				
			||||||
                            <i class="fas fa-ellipsis-v px-4"></i>
 | 
					                            <i class="fas fa-ellipsis-v px-4"></i>
 | 
				
			||||||
@@ -142,3 +160,5 @@
 | 
				
			|||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%= render "shared/modals/invite_user_modal" %>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,12 +14,20 @@
 | 
				
			|||||||
%>
 | 
					%>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="row mt-2">
 | 
					<div class="row mt-2">
 | 
				
			||||||
  <div class="col-8">
 | 
					  <div class="col-4">
 | 
				
			||||||
    <p class="subtitle"><%= subtitle %></p>
 | 
					    <p class="subtitle"><%= subtitle %></p>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
  <% if search %>
 | 
					  <% if search %>
 | 
				
			||||||
    <div class="col-4">
 | 
					    <div class="col-8">
 | 
				
			||||||
      <div id="search-bar">
 | 
					      <% if display_invite %>
 | 
				
			||||||
 | 
					        <div id="invite-user" class="d-inline-block float-right ml-3">
 | 
				
			||||||
 | 
					          <%= link_to "#inviteModal", :class => "btn btn-primary", "data-toggle": "modal" do %>
 | 
				
			||||||
 | 
					            <%= t("administrator.users.invite") %> <i class="fas fa-paper-plane ml-1"></i>
 | 
				
			||||||
 | 
					          <% end %>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      <% end %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <div id="search-bar" class="d-inline-block float-right">
 | 
				
			||||||
        <div class="input-group">
 | 
					        <div class="input-group">
 | 
				
			||||||
          <input id="search-input" type="text" class="form-control" placeholder="<%= t("settings.search") %>..." value="<%= @search %>">
 | 
					          <input id="search-input" type="text" class="form-control" placeholder="<%= t("settings.search") %>..." value="<%= @search %>">
 | 
				
			||||||
          <% unless @search.blank? %>
 | 
					          <% unless @search.blank? %>
 | 
				
			||||||
@@ -28,7 +36,7 @@
 | 
				
			|||||||
            </span>
 | 
					            </span>
 | 
				
			||||||
          <% end %>
 | 
					          <% end %>
 | 
				
			||||||
          <span class="input-group-append">
 | 
					          <span class="input-group-append">
 | 
				
			||||||
            <button class="btn btn-primary" type="button" onclick="searchPage()">
 | 
					            <button class="btn btn-outline-primary" type="button" onclick="searchPage()">
 | 
				
			||||||
              <i class="fas fa-search"></i>
 | 
					              <i class="fas fa-search"></i>
 | 
				
			||||||
            </button>
 | 
					            </button>
 | 
				
			||||||
          </span>
 | 
					          </span>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										44
									
								
								app/views/shared/modals/_invite_user_modal.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								app/views/shared/modals/_invite_user_modal.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					<%
 | 
				
			||||||
 | 
					# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
 | 
				
			||||||
 | 
					# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
 | 
				
			||||||
 | 
					# This program is free software; you can redistribute it and/or modify it under the
 | 
				
			||||||
 | 
					# terms of the GNU Lesser General Public License as published by the Free Software
 | 
				
			||||||
 | 
					# Foundation; either version 3.0 of the License, or (at your option) any later
 | 
				
			||||||
 | 
					# version.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
				
			||||||
 | 
					# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 | 
				
			||||||
 | 
					# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU Lesser General Public License along
 | 
				
			||||||
 | 
					# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					%>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="modal fade" id="inviteModal" tabindex="-1" role="dialog">
 | 
				
			||||||
 | 
					  <div class="modal-dialog modal-dialog-centered" role="document">
 | 
				
			||||||
 | 
					    <div class="modal-content text-center">
 | 
				
			||||||
 | 
					      <div class="modal-body">
 | 
				
			||||||
 | 
					        <div class="card-body p-6">
 | 
				
			||||||
 | 
					          <div class="card-title">
 | 
				
			||||||
 | 
					            <h3><%= t("modal.invite_user.title") %></h3>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          <%= form_for(:invite_user, url: invite_user_path) do |f| %>
 | 
				
			||||||
 | 
					            <div class="input-icon mb-2">
 | 
				
			||||||
 | 
					              <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 %>
 | 
				
			||||||
 | 
					              <div class="invalid-feedback text-left"><%= t("modal.invite_user.not_blank") %></div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          <div class="mt-4">
 | 
				
			||||||
 | 
					            <%= f.submit t("modal.invite_user.send"), class:"btn btn-primary btn-block" %>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					          <% end %>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="card-footer">
 | 
				
			||||||
 | 
					          <p><%= t("modal.invite_user.footer") %></p>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
							
								
								
									
										43
									
								
								app/views/user_mailer/approve_user.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								app/views/user_mailer/approve_user.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
				
			|||||||
 | 
					<%
 | 
				
			||||||
 | 
					# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This program is free software; you can redistribute it and/or modify it under the
 | 
				
			||||||
 | 
					# terms of the GNU Lesser General Public License as published by the Free Software
 | 
				
			||||||
 | 
					# Foundation; either version 3.0 of the License, or (at your option) any later
 | 
				
			||||||
 | 
					# version.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
				
			||||||
 | 
					# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 | 
				
			||||||
 | 
					# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU Lesser General Public License along
 | 
				
			||||||
 | 
					# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					%>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div style="text-align:center; font-family:'Source Sans Pro', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif">
 | 
				
			||||||
 | 
					    <div style="display:inline-block; background-color:#F5F7FB; border:1px solid #d3d3d3; padding: 25px 70px">
 | 
				
			||||||
 | 
					        <%= image_tag(@image, height: '70') %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <h1 style="margin-bottom:30px">
 | 
				
			||||||
 | 
					        <%= t('mailer.user.approve.subject') %>
 | 
				
			||||||
 | 
					        </h1>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <p>
 | 
				
			||||||
 | 
					        <%= t('mailer.user.approve.info') %>
 | 
				
			||||||
 | 
					        </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <p>
 | 
				
			||||||
 | 
					        <%= t('mailer.user.approve.username', email: @user.email) %>
 | 
				
			||||||
 | 
					        </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <p style="margin-bottom:35px;">
 | 
				
			||||||
 | 
					        <%= t('mailer.user.approve.signin') %>
 | 
				
			||||||
 | 
					        </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <a style="background: <%= @color %>;color: #ffffff; padding: 10px 15px; box-shadow: 0 2px 4px 0 rgba(0,0,0,.25);border: 1px solid transparent;text-decoration:none;" href="<%= @url %>">
 | 
				
			||||||
 | 
					        <%= t('mailer.user.approve.signin_link') %>
 | 
				
			||||||
 | 
					        </a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
							
								
								
									
										27
									
								
								app/views/user_mailer/approve_user.text.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/views/user_mailer/approve_user.text.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					<%
 | 
				
			||||||
 | 
					# 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/>.
 | 
				
			||||||
 | 
					%>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%= t('mailer.user.approve.subject') %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%= t('mailer.user.approve.info') %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%= t('mailer.user.approve.username', email: @user.email) %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%= t('mailer.user.approve.signin') %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%= @url %>
 | 
				
			||||||
							
								
								
									
										43
									
								
								app/views/user_mailer/invite_email.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								app/views/user_mailer/invite_email.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
				
			|||||||
 | 
					<%
 | 
				
			||||||
 | 
					# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This program is free software; you can redistribute it and/or modify it under the
 | 
				
			||||||
 | 
					# terms of the GNU Lesser General Public License as published by the Free Software
 | 
				
			||||||
 | 
					# Foundation; either version 3.0 of the License, or (at your option) any later
 | 
				
			||||||
 | 
					# version.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
				
			||||||
 | 
					# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 | 
				
			||||||
 | 
					# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU Lesser General Public License along
 | 
				
			||||||
 | 
					# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					%>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <div style="text-align:center; font-family:'Source Sans Pro', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif">
 | 
				
			||||||
 | 
					    <div style="display:inline-block; background-color:#F5F7FB; border:1px solid #d3d3d3; padding: 25px 70px">
 | 
				
			||||||
 | 
					      <%= image_tag(@image, height: '70') %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <h1 style="margin-bottom:30px">
 | 
				
			||||||
 | 
					        <%= t('mailer.user.invite.subject') %>
 | 
				
			||||||
 | 
					      </h1>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <p>
 | 
				
			||||||
 | 
					        <%= t('mailer.user.invite.info', name: @name) %>
 | 
				
			||||||
 | 
					      </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <p>
 | 
				
			||||||
 | 
					        <%= t('mailer.user.invite.username', email: @email) %>
 | 
				
			||||||
 | 
					      </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <p style="margin-bottom:35px;">
 | 
				
			||||||
 | 
					        <%= t('mailer.user.invite.signup') %>
 | 
				
			||||||
 | 
					      </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <a style="background: <%= @color %>;color: #ffffff; padding: 10px 15px; box-shadow: 0 2px 4px 0 rgba(0,0,0,.25);border: 1px solid transparent;text-decoration:none;" href="<%= @url %>">
 | 
				
			||||||
 | 
					        <%= t('mailer.user.invite.signup_link') %>
 | 
				
			||||||
 | 
					      </a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
							
								
								
									
										27
									
								
								app/views/user_mailer/invite_email.text.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/views/user_mailer/invite_email.text.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					<%
 | 
				
			||||||
 | 
					# 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/>.
 | 
				
			||||||
 | 
					%>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%= t('mailer.user.invite.subject') %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%= t('mailer.user.invite.info', name: @name) %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%= t('mailer.user.invite.username', email: @email) %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%= t('mailer.user.invite.signup') %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%= @url %>
 | 
				
			||||||
@@ -96,22 +96,30 @@ module Greenlight
 | 
				
			|||||||
    # The maximum number of rooms included in one bbbapi call
 | 
					    # The maximum number of rooms included in one bbbapi call
 | 
				
			||||||
    config.pagination_number = ENV['PAGINATION_NUMBER'].to_i.zero? ? 25 : ENV['PAGINATION_NUMBER'].to_i
 | 
					    config.pagination_number = ENV['PAGINATION_NUMBER'].to_i.zero? ? 25 : ENV['PAGINATION_NUMBER'].to_i
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Default branding image if the user does not specify one
 | 
					 | 
				
			||||||
    config.branding_image_default = "https://raw.githubusercontent.com/bigbluebutton/greenlight/master/app/assets/images/logo_with_text.png"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Default primary color if the user does not specify one
 | 
					 | 
				
			||||||
    config.primary_color_default = "#467fcf"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Default admin password
 | 
					 | 
				
			||||||
    config.admin_password_default = ENV['ADMIN_PASSWORD'] || 'administrator'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Number of rows to display per page
 | 
					    # Number of rows to display per page
 | 
				
			||||||
    config.pagination_rows = ENV['NUMBER_OF_ROWS'].to_i.zero? ? 10 : ENV['NUMBER_OF_ROWS'].to_i
 | 
					    config.pagination_rows = ENV['NUMBER_OF_ROWS'].to_i.zero? ? 25 : ENV['NUMBER_OF_ROWS'].to_i
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Whether the user has defined the variables required for recaptcha
 | 
					    # Whether the user has defined the variables required for recaptcha
 | 
				
			||||||
    config.recaptcha_enabled = ENV['RECAPTCHA_SITE_KEY'].present? && ENV['RECAPTCHA_SECRET_KEY'].present?
 | 
					    config.recaptcha_enabled = ENV['RECAPTCHA_SITE_KEY'].present? && ENV['RECAPTCHA_SECRET_KEY'].present?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Show/hide "Add to Google Calendar" button in the room page
 | 
					    # Show/hide "Add to Google Calendar" button in the room page
 | 
				
			||||||
    config.enable_google_calendar_button = (ENV['ENABLE_GOOGLE_CALENDAR_BUTTON'] == "true")
 | 
					    config.enable_google_calendar_button = (ENV['ENABLE_GOOGLE_CALENDAR_BUTTON'] == "true")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Enum containing the different possible registration methods
 | 
				
			||||||
 | 
					    config.registration_methods = { open: "0", invite: "1", approval: "2" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # DEFAULTS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Default branding image if the user does not specify one
 | 
				
			||||||
 | 
					    config.branding_image_default = "https://raw.githubusercontent.com/bigbluebutton/greenlight/master/app/assets/images/logo_with_text.png"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Default primary color if the user does not specify one
 | 
				
			||||||
 | 
					    config.primary_color_default = "#467fcf"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Default registration method if the user does not specify one
 | 
				
			||||||
 | 
					    config.registration_method_default = config.registration_methods[:open]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Default admin password
 | 
				
			||||||
 | 
					    config.admin_password_default = ENV['ADMIN_PASSWORD'] || 'administrator'
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,18 +31,30 @@ en:
 | 
				
			|||||||
      color:
 | 
					      color:
 | 
				
			||||||
        info: Change the primary color used across the website
 | 
					        info: Change the primary color used across the website
 | 
				
			||||||
        title: Primary Color
 | 
					        title: Primary Color
 | 
				
			||||||
 | 
					      registration:
 | 
				
			||||||
 | 
					        info: Change the way that users register to the website
 | 
				
			||||||
 | 
					        title: Registration Method
 | 
				
			||||||
 | 
					        methods:
 | 
				
			||||||
 | 
					          approval: Approve/Decline
 | 
				
			||||||
 | 
					          invite: Join by Invitation
 | 
				
			||||||
 | 
					          open: Open Registration
 | 
				
			||||||
      subtitle: Customize Greenlight
 | 
					      subtitle: Customize Greenlight
 | 
				
			||||||
      title: Site Settings
 | 
					      title: Site Settings
 | 
				
			||||||
    flash:
 | 
					    flash:
 | 
				
			||||||
 | 
					      approved: User has been successfully approved.
 | 
				
			||||||
      banned: User has been successfully banned.
 | 
					      banned: User has been successfully banned.
 | 
				
			||||||
      unbanned: User has been successfully unbanned.
 | 
					      unbanned: User has been successfully unbanned.
 | 
				
			||||||
      delete: User deleted successfully
 | 
					      delete: User deleted successfully
 | 
				
			||||||
      delete_fail: Failed to delete user
 | 
					      delete_fail: Failed to delete user
 | 
				
			||||||
      demoted: User has been successfully demoted
 | 
					      demoted: User has been successfully demoted
 | 
				
			||||||
 | 
					      invite: Invite successfully sent to %{email}
 | 
				
			||||||
 | 
					      invite_email_verification: ALLOW_MAIL_NOTIFICATIONS must be set to true in order to use this method
 | 
				
			||||||
      promoted: User has been successfully promoted
 | 
					      promoted: User has been successfully promoted
 | 
				
			||||||
 | 
					      registration_method_updated: Registration method successfully updated
 | 
				
			||||||
      unauthorized: You are not authorized to perform actions on this user
 | 
					      unauthorized: You are not authorized to perform actions on this user
 | 
				
			||||||
    title: Organization Settings
 | 
					    title: Organization Settings
 | 
				
			||||||
    users:
 | 
					    users:
 | 
				
			||||||
 | 
					      invite: Invite User
 | 
				
			||||||
      edit:
 | 
					      edit:
 | 
				
			||||||
        title: Edit User Details
 | 
					        title: Edit User Details
 | 
				
			||||||
      settings:
 | 
					      settings:
 | 
				
			||||||
@@ -105,6 +117,7 @@ en:
 | 
				
			|||||||
    unauthorized:
 | 
					    unauthorized:
 | 
				
			||||||
      message: You do not have access to this application
 | 
					      message: You do not have access to this application
 | 
				
			||||||
      help: If you believe this is a mistake, please contact your system administrator.
 | 
					      help: If you believe this is a mistake, please contact your system administrator.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unprocessable:
 | 
					    unprocessable:
 | 
				
			||||||
      message: Oops! Request is unprocessable.
 | 
					      message: Oops! Request is unprocessable.
 | 
				
			||||||
      help: Unfortunately this isn't a valid request.
 | 
					      help: Unfortunately this isn't a valid request.
 | 
				
			||||||
@@ -157,6 +170,18 @@ en:
 | 
				
			|||||||
  login_title: Sign in to your account
 | 
					  login_title: Sign in to your account
 | 
				
			||||||
  mailer:
 | 
					  mailer:
 | 
				
			||||||
    user:
 | 
					    user:
 | 
				
			||||||
 | 
					      approve:
 | 
				
			||||||
 | 
					        info: Your account has been approved.
 | 
				
			||||||
 | 
					        signin: To access your personal rooms, click the button below and sign in.
 | 
				
			||||||
 | 
					        signin_link: Sign In
 | 
				
			||||||
 | 
					        subject: Account Approved
 | 
				
			||||||
 | 
					        username: Your username is %{email}.
 | 
				
			||||||
 | 
					      invite:
 | 
				
			||||||
 | 
					        info: You have been invited to your own personal space by %{name}
 | 
				
			||||||
 | 
					        signup: To signup using your email, click the button below and follow the steps.
 | 
				
			||||||
 | 
					        signup_link: Sign Up
 | 
				
			||||||
 | 
					        subject: Invitation to join BigBlueButton
 | 
				
			||||||
 | 
					        username: Your username is %{email}.
 | 
				
			||||||
      password_reset:
 | 
					      password_reset:
 | 
				
			||||||
        title: 'Password reset'
 | 
					        title: 'Password reset'
 | 
				
			||||||
        welcome: It seems like you forgot your password for %{bigbluebutton}
 | 
					        welcome: It seems like you forgot your password for %{bigbluebutton}
 | 
				
			||||||
@@ -191,6 +216,11 @@ en:
 | 
				
			|||||||
      delete: I'm sure, delete this room.
 | 
					      delete: I'm sure, delete this room.
 | 
				
			||||||
      keep: On second thought, I'll keep it.
 | 
					      keep: On second thought, I'll keep it.
 | 
				
			||||||
      warning: You will <b>not</b> be able to recover this room or any of its %{recordings_num} associated recordings.
 | 
					      warning: You will <b>not</b> be able to recover this room or any of its %{recordings_num} associated recordings.
 | 
				
			||||||
 | 
					    invite_user:
 | 
				
			||||||
 | 
					      email_placeholder: Enter the user's email
 | 
				
			||||||
 | 
					      footer: The user will receive an email with instructions on how to sign up
 | 
				
			||||||
 | 
					      send: Send Invite
 | 
				
			||||||
 | 
					      title: Invite User
 | 
				
			||||||
    login:
 | 
					    login:
 | 
				
			||||||
      or: or
 | 
					      or: or
 | 
				
			||||||
      with: Sign in with %{provider}
 | 
					      with: Sign in with %{provider}
 | 
				
			||||||
@@ -246,6 +276,15 @@ en:
 | 
				
			|||||||
      unlisted: Unlisted
 | 
					      unlisted: Unlisted
 | 
				
			||||||
    format:
 | 
					    format:
 | 
				
			||||||
      presentation: Presentation
 | 
					      presentation: Presentation
 | 
				
			||||||
 | 
					  registration:
 | 
				
			||||||
 | 
					    approval: 
 | 
				
			||||||
 | 
					      fail: Your account has not been approved yet. If multiples days have passed since you signed up, please contact your administrator.
 | 
				
			||||||
 | 
					      signup: Your account was successfully created. It has been sent to an administrator for approval.
 | 
				
			||||||
 | 
					    banned:
 | 
				
			||||||
 | 
					      fail: You do not have access to this application. If you believe this is a mistake, please contact your administrator. 
 | 
				
			||||||
 | 
					    invite:
 | 
				
			||||||
 | 
					      fail: Your token is either invalid or has expired. If you believe this is a mistake, please contact your administrator.
 | 
				
			||||||
 | 
					      no_invite: You do not have an invitation to join. Please contact your administrator to receive one.
 | 
				
			||||||
  rename: Rename
 | 
					  rename: Rename
 | 
				
			||||||
  reset_password:
 | 
					  reset_password:
 | 
				
			||||||
    subtitle: Reset Password
 | 
					    subtitle: Reset Password
 | 
				
			||||||
@@ -255,6 +294,7 @@ en:
 | 
				
			|||||||
  roles:
 | 
					  roles:
 | 
				
			||||||
    administrator: Administrator
 | 
					    administrator: Administrator
 | 
				
			||||||
    banned: Banned
 | 
					    banned: Banned
 | 
				
			||||||
 | 
					    pending: Pending
 | 
				
			||||||
    super_admin: Super Admin
 | 
					    super_admin: Super Admin
 | 
				
			||||||
    user: User
 | 
					    user: User
 | 
				
			||||||
  room:
 | 
					  room:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -45,6 +45,9 @@ Rails.application.routes.draw do
 | 
				
			|||||||
    post '/demote/:user_uid', to: 'admins#demote', as: :admin_demote
 | 
					    post '/demote/:user_uid', to: 'admins#demote', as: :admin_demote
 | 
				
			||||||
    post '/ban/:user_uid', to: 'admins#ban_user', as: :admin_ban
 | 
					    post '/ban/:user_uid', to: 'admins#ban_user', as: :admin_ban
 | 
				
			||||||
    post '/unban/:user_uid', to: 'admins#unban_user', as: :admin_unban
 | 
					    post '/unban/:user_uid', to: 'admins#unban_user', as: :admin_unban
 | 
				
			||||||
 | 
					    post '/invite', to: 'admins#invite', as: :invite_user
 | 
				
			||||||
 | 
					    post '/registration_method/:method', to: 'admins#registration_method', as: :admin_change_registration
 | 
				
			||||||
 | 
					    post '/approve/:user_uid', to: 'admins#approve', as: :admin_approve
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  scope '/themes' do
 | 
					  scope '/themes' do
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								db/migrate/20190507190710_create_invitations.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								db/migrate/20190507190710_create_invitations.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CreateInvitations < ActiveRecord::Migration[5.0]
 | 
				
			||||||
 | 
					  def change
 | 
				
			||||||
 | 
					    create_table :invitations do |t|
 | 
				
			||||||
 | 
					      t.string "email", null: false
 | 
				
			||||||
 | 
					      t.string "provider", null: false
 | 
				
			||||||
 | 
					      t.string "invite_token"
 | 
				
			||||||
 | 
					      t.timestamps
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										10
									
								
								db/schema.rb
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								db/schema.rb
									
									
									
									
									
								
							@@ -10,7 +10,7 @@
 | 
				
			|||||||
#
 | 
					#
 | 
				
			||||||
# It's strongly recommended that you check this file into your version control system.
 | 
					# It's strongly recommended that you check this file into your version control system.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ActiveRecord::Schema.define(version: 20190326144939) do
 | 
					ActiveRecord::Schema.define(version: 20190507190710) do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  create_table "features", force: :cascade do |t|
 | 
					  create_table "features", force: :cascade do |t|
 | 
				
			||||||
    t.integer  "setting_id"
 | 
					    t.integer  "setting_id"
 | 
				
			||||||
@@ -22,6 +22,14 @@ ActiveRecord::Schema.define(version: 20190326144939) do
 | 
				
			|||||||
    t.index ["setting_id"], name: "index_features_on_setting_id"
 | 
					    t.index ["setting_id"], name: "index_features_on_setting_id"
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  create_table "invitations", force: :cascade do |t|
 | 
				
			||||||
 | 
					    t.string   "email",        null: false
 | 
				
			||||||
 | 
					    t.string   "provider",     null: false
 | 
				
			||||||
 | 
					    t.string   "invite_token"
 | 
				
			||||||
 | 
					    t.datetime "created_at",   null: false
 | 
				
			||||||
 | 
					    t.datetime "updated_at",   null: false
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  create_table "roles", force: :cascade do |t|
 | 
					  create_table "roles", force: :cascade do |t|
 | 
				
			||||||
    t.string   "name"
 | 
					    t.string   "name"
 | 
				
			||||||
    t.string   "resource_type"
 | 
					    t.string   "resource_type"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -136,8 +136,8 @@ ROOM_FEATURES=default-client,mute-on-join
 | 
				
			|||||||
PAGINATION_NUMBER=25
 | 
					PAGINATION_NUMBER=25
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Specify the maximum number of rows that should be displayed per page for a paginated table
 | 
					# Specify the maximum number of rows that should be displayed per page for a paginated table
 | 
				
			||||||
# Default is set to 10 rows
 | 
					# Default is set to 25 rows
 | 
				
			||||||
NUMBER_OF_ROWS=10
 | 
					NUMBER_OF_ROWS=25
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Specify if you want to display the Google Calendar button
 | 
					# Specify if you want to display the Google Calendar button
 | 
				
			||||||
#   ENABLE_GOOGLE_CALENDAR_BUTTON=true|false
 | 
					#   ENABLE_GOOGLE_CALENDAR_BUTTON=true|false
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -72,6 +72,17 @@ describe AccountActivationsController, type: :controller do
 | 
				
			|||||||
      expect(flash[:alert]).to be_present
 | 
					      expect(flash[:alert]).to be_present
 | 
				
			||||||
      expect(response).to redirect_to(root_path)
 | 
					      expect(response).to redirect_to(root_path)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "redirects a pending user to root with a flash" do
 | 
				
			||||||
 | 
					      @user = create(:user, email_verified: false, provider: "greenlight")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      @user.add_role :pending
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      get :edit, params: { email: @user.email, token: @user.activation_token }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      expect(flash[:success]).to be_present
 | 
				
			||||||
 | 
					      expect(response).to redirect_to(root_path)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe "GET #resend" do
 | 
					  describe "GET #resend" do
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -109,6 +109,56 @@ describe AdminsController, type: :controller do
 | 
				
			|||||||
        expect(response).to redirect_to(admins_path)
 | 
					        expect(response).to redirect_to(admins_path)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context "POST #invite" do
 | 
				
			||||||
 | 
					      before do
 | 
				
			||||||
 | 
					        allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
 | 
				
			||||||
 | 
					        allow_any_instance_of(ApplicationController).to receive(:allow_greenlight_users?).and_return(true)
 | 
				
			||||||
 | 
					        allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "invites a user" do
 | 
				
			||||||
 | 
					        @request.session[:user_id] = @admin.id
 | 
				
			||||||
 | 
					        email = Faker::Internet.email
 | 
				
			||||||
 | 
					        post :invite, params: { invite_user: { email: email } }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        invite = Invitation.find_by(email: email, provider: "greenlight")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(invite.present?).to eq(true)
 | 
				
			||||||
 | 
					        expect(flash[:success]).to be_present
 | 
				
			||||||
 | 
					        expect(response).to redirect_to(admins_path)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "sends an invitation email" do
 | 
				
			||||||
 | 
					        @request.session[:user_id] = @admin.id
 | 
				
			||||||
 | 
					        email = Faker::Internet.email
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        params = { invite_user: { email: email } }
 | 
				
			||||||
 | 
					        expect { post :invite, params: params }.to change { ActionMailer::Base.deliveries.count }.by(1)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context "POST #approve" do
 | 
				
			||||||
 | 
					      it "approves a pending user" do
 | 
				
			||||||
 | 
					        @request.session[:user_id] = @admin.id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @user.add_role :pending
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        post :approve, params: { user_uid: @user.uid }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(@user.has_role?(:pending)).to eq(false)
 | 
				
			||||||
 | 
					        expect(flash[:success]).to be_present
 | 
				
			||||||
 | 
					        expect(response).to redirect_to(admins_path)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "sends the user an email telling them theyre approved" do
 | 
				
			||||||
 | 
					        @request.session[:user_id] = @admin.id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @user.add_role :pending
 | 
				
			||||||
 | 
					        params = { user_uid: @user.uid }
 | 
				
			||||||
 | 
					        expect { post :approve, params: params }.to change { ActionMailer::Base.deliveries.count }.by(1)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe "User Design" do
 | 
					  describe "User Design" do
 | 
				
			||||||
@@ -142,7 +192,38 @@ describe AdminsController, type: :controller do
 | 
				
			|||||||
        feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color")
 | 
					        feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(feature[:value]).to eq(primary_color)
 | 
					        expect(feature[:value]).to eq(primary_color)
 | 
				
			||||||
        expect(response).to redirect_to(admins_path(setting: "site_settings"))
 | 
					        expect(response).to redirect_to(admins_path)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context "POST #registration_method" do
 | 
				
			||||||
 | 
					      it "changes the registration method for the given context" do
 | 
				
			||||||
 | 
					        allow(Rails.configuration).to receive(:enable_email_verification).and_return(true)
 | 
				
			||||||
 | 
					        allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
 | 
				
			||||||
 | 
					        allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @request.session[:user_id] = @admin.id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        post :registration_method, params: { method: "invite" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        feature = Setting.find_by(provider: "provider1").features.find_by(name: "Registration Method")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(feature[:value]).to eq(Rails.configuration.registration_methods[:invite])
 | 
				
			||||||
 | 
					        expect(flash[:success]).to be_present
 | 
				
			||||||
 | 
					        expect(response).to redirect_to(admins_path)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "does not allow the user to change to invite if emails are off" do
 | 
				
			||||||
 | 
					        allow(Rails.configuration).to receive(:enable_email_verification).and_return(false)
 | 
				
			||||||
 | 
					        allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
 | 
				
			||||||
 | 
					        allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @request.session[:user_id] = @admin.id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        post :registration_method, params: { method: "invite" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(flash[:alert]).to be_present
 | 
				
			||||||
 | 
					        expect(response).to redirect_to(admins_path)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,14 +32,28 @@ describe ApplicationController do
 | 
				
			|||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  context "roles" do
 | 
					  context "roles" do
 | 
				
			||||||
    it "redirects a banned user to a 401 and logs them out" do
 | 
					    before do
 | 
				
			||||||
      @user = create(:user)
 | 
					      @user = create(:user)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "redirects a banned user to a 401 and logs them out" do
 | 
				
			||||||
      @user.add_role :denied
 | 
					      @user.add_role :denied
 | 
				
			||||||
      @request.session[:user_id] = @user.id
 | 
					      @request.session[:user_id] = @user.id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      get :index
 | 
					      get :index
 | 
				
			||||||
      expect(@request.session[:user_id]).to be_nil
 | 
					      expect(@request.session[:user_id]).to be_nil
 | 
				
			||||||
      expect(response).to redirect_to(unauthorized_path)
 | 
					      expect(flash[:alert]).to be_present
 | 
				
			||||||
 | 
					      expect(response).to redirect_to(root_path)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "redirects a pending user to a 401 and logs them out" do
 | 
				
			||||||
 | 
					      @user.add_role :pending
 | 
				
			||||||
 | 
					      @request.session[:user_id] = @user.id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      get :index
 | 
				
			||||||
 | 
					      expect(@request.session[:user_id]).to be_nil
 | 
				
			||||||
 | 
					      expect(flash[:alert]).to be_present
 | 
				
			||||||
 | 
					      expect(response).to redirect_to(root_path)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -169,7 +169,9 @@ describe UsersController, type: :controller do
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    context "allow email verification" do
 | 
					    context "allow email verification" do
 | 
				
			||||||
      before { allow(Rails.configuration).to receive(:enable_email_verification).and_return(true) }
 | 
					      before do
 | 
				
			||||||
 | 
					        allow(Rails.configuration).to receive(:enable_email_verification).and_return(true)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it "should raise if there there is a delivery failure" do
 | 
					      it "should raise if there there is a delivery failure" do
 | 
				
			||||||
        params = random_valid_user_params
 | 
					        params = random_valid_user_params
 | 
				
			||||||
@@ -179,6 +181,91 @@ describe UsersController, type: :controller do
 | 
				
			|||||||
          raise :anyerror
 | 
					          raise :anyerror
 | 
				
			||||||
        end.to raise_error { :anyerror }
 | 
					        end.to raise_error { :anyerror }
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context "enable invite registration" do
 | 
				
			||||||
 | 
					        before do
 | 
				
			||||||
 | 
					          allow_any_instance_of(Registrar).to receive(:invite_registration).and_return(true)
 | 
				
			||||||
 | 
					          allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it "rejects the user if they are not invited" do
 | 
				
			||||||
 | 
					          get :new
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          expect(flash[:alert]).to be_present
 | 
				
			||||||
 | 
					          expect(response).to redirect_to(root_path)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it "allows the user to signup if they are invited" do
 | 
				
			||||||
 | 
					          allow(Rails.configuration).to receive(:enable_email_verification).and_return(false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          params = random_valid_user_params
 | 
				
			||||||
 | 
					          invite = Invitation.create(email: params[:user][:name], provider: "greenlight")
 | 
				
			||||||
 | 
					          @request.session[:invite_token] = invite.invite_token
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          post :create, params: params
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          u = User.find_by(name: params[:user][:name], email: params[:user][:email])
 | 
				
			||||||
 | 
					          expect(response).to redirect_to(u.main_room)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it "verifies the user if they sign up with the email they receieved the invite with" do
 | 
				
			||||||
 | 
					          allow(Rails.configuration).to receive(:enable_email_verification).and_return(true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          params = random_valid_user_params
 | 
				
			||||||
 | 
					          invite = Invitation.create(email: params[:user][:email], provider: "greenlight")
 | 
				
			||||||
 | 
					          @request.session[:invite_token] = invite.invite_token
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          post :create, params: params
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          u = User.find_by(name: params[:user][:name], email: params[:user][:email])
 | 
				
			||||||
 | 
					          expect(response).to redirect_to(u.main_room)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it "asks the user to verify if they signup with a different email" do
 | 
				
			||||||
 | 
					          allow(Rails.configuration).to receive(:enable_email_verification).and_return(true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          params = random_valid_user_params
 | 
				
			||||||
 | 
					          invite = Invitation.create(email: Faker::Internet.email, provider: "greenlight")
 | 
				
			||||||
 | 
					          @request.session[:invite_token] = invite.invite_token
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          post :create, params: params
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          expect(User.exists?(name: params[:user][:name], email: params[:user][:email])).to eq(true)
 | 
				
			||||||
 | 
					          expect(flash[:success]).to be_present
 | 
				
			||||||
 | 
					          expect(response).to redirect_to(root_path)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context "enable approval registration" do
 | 
				
			||||||
 | 
					        before do
 | 
				
			||||||
 | 
					          allow_any_instance_of(Registrar).to receive(:approval_registration).and_return(true)
 | 
				
			||||||
 | 
					          allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it "allows any user to sign up" do
 | 
				
			||||||
 | 
					          allow(Rails.configuration).to receive(:enable_email_verification).and_return(false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          params = random_valid_user_params
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          post :create, params: params
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          expect(User.exists?(name: params[:user][:name], email: params[:user][:email])).to eq(true)
 | 
				
			||||||
 | 
					          expect(flash[:success]).to be_present
 | 
				
			||||||
 | 
					          expect(response).to redirect_to(root_path)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it "sets the user to pending on sign up" do
 | 
				
			||||||
 | 
					          allow(Rails.configuration).to receive(:enable_email_verification).and_return(false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          params = random_valid_user_params
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          post :create, params: params
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          u = User.find_by(name: params[:user][:name], email: params[:user][:email])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          expect(u.has_role?(:pending)).to eq(true)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "redirects to main room if already authenticated" do
 | 
					    it "redirects to main room if already authenticated" do
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,18 @@
 | 
				
			|||||||
# frozen_string_literal: true
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class UserMailerPreview < ActionMailer::Preview
 | 
					class UserMailerPreview < ActionMailer::Preview
 | 
				
			||||||
 | 
					  def initialize
 | 
				
			||||||
 | 
					    @logo = "https://raw.githubusercontent.com/bigbluebutton/greenlight/master/app/assets/images/logo_with_text.png"
 | 
				
			||||||
 | 
					    @color = "#467fcf"
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Preview this email at
 | 
					  # Preview this email at
 | 
				
			||||||
  # http://localhost:3000/rails/mailers/user_mailer/password_reset
 | 
					  # http://localhost:3000/rails/mailers/user_mailer/password_reset
 | 
				
			||||||
  def password_reset
 | 
					  def password_reset
 | 
				
			||||||
    user = User.first
 | 
					    user = User.first
 | 
				
			||||||
    user.reset_token = User.new_token
 | 
					    user.reset_token = User.new_token
 | 
				
			||||||
    url = "http://example.com" + "/password_resets/" + user.reset_token + "/edit?email=" + user.email
 | 
					    url = "http://example.com" + "/password_resets/" + user.reset_token + "/edit?email=" + user.email
 | 
				
			||||||
    UserMailer.password_reset(user, url)
 | 
					    UserMailer.password_reset(user, url, @logo, @color)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Preview this email at
 | 
					  # Preview this email at
 | 
				
			||||||
@@ -15,6 +20,19 @@ class UserMailerPreview < ActionMailer::Preview
 | 
				
			|||||||
  def verify_email
 | 
					  def verify_email
 | 
				
			||||||
    user = User.first
 | 
					    user = User.first
 | 
				
			||||||
    url = "http://example.com" + "/u/verify/confirm/" + user.uid
 | 
					    url = "http://example.com" + "/u/verify/confirm/" + user.uid
 | 
				
			||||||
    UserMailer.verify_email(user, url)
 | 
					    UserMailer.verify_email(user, url, @logo, @color)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Preview this email at
 | 
				
			||||||
 | 
					  # http://localhost:3000/rails/mailers/user_mailer/invite_email
 | 
				
			||||||
 | 
					  def invite_email
 | 
				
			||||||
 | 
					    UserMailer.invite_email("Example User", "from@example.com", "http://example.com/signup", @logo, @color)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Preview this email at
 | 
				
			||||||
 | 
					  # http://localhost:3000/rails/mailers/user_mailer/approve_user
 | 
				
			||||||
 | 
					  def approve_user
 | 
				
			||||||
 | 
					    user = User.first
 | 
				
			||||||
 | 
					    UserMailer.approve_user(user, "http://example.com/", @logo, @color)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user