| Total Complexity | 55 |
| Total Lines | 228 |
| Duplicated Lines | 3.07 % |
| Changes | 4 | ||
| Bugs | 0 | Features | 0 |
Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like ApplicationController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
| 1 | # frozen_string_literal: true |
||
| 19 | class ApplicationController < ActionController::Base |
||
| 20 | include BbbServer |
||
| 21 | include ThemingHelper |
||
| 22 | |||
| 23 | before_action :redirect_to_https |
||
| 24 | before_action :set_user_domain |
||
| 25 | before_action :set_user_settings |
||
| 26 | before_action :maintenance_mode? |
||
| 27 | before_action :migration_error? |
||
| 28 | before_action :user_locale |
||
| 29 | before_action :check_admin_password |
||
| 30 | before_action :check_user_role |
||
| 31 | |||
| 32 | # Manually handle BigBlueButton errors |
||
| 33 | rescue_from BigBlueButton::BigBlueButtonException, with: :handle_bigbluebutton_error |
||
| 34 | |||
| 35 | protect_from_forgery with: :exceptions |
||
| 36 | |||
| 37 | # Retrieves the current user. |
||
| 38 | def current_user |
||
| 39 | @current_user ||= User.where(id: session[:user_id]).includes(:roles).first |
||
| 40 | |||
| 41 | if Rails.configuration.loadbalanced_configuration |
||
| 42 | if @current_user && !@current_user.has_role?(:super_admin) && |
||
| 43 | @current_user.provider != @user_domain |
||
| 44 | @current_user = nil |
||
| 45 | session.clear |
||
| 46 | end |
||
| 47 | end |
||
| 48 | |||
| 49 | @current_user |
||
| 50 | end |
||
| 51 | helper_method :current_user |
||
| 52 | |||
| 53 | def bbb_server |
||
| 54 | @bbb_server ||= Rails.configuration.loadbalanced_configuration ? bbb(@user_domain) : bbb("greenlight") |
||
| 55 | end |
||
| 56 | |||
| 57 | # Force SSL |
||
| 58 | def redirect_to_https |
||
| 59 | if Rails.configuration.loadbalanced_configuration && request.headers["X-Forwarded-Proto"] == "http" |
||
| 60 | redirect_to protocol: "https://" |
||
| 61 | end |
||
| 62 | end |
||
| 63 | |||
| 64 | # Sets the user domain variable |
||
| 65 | def set_user_domain |
||
| 66 | if Rails.env.test? || !Rails.configuration.loadbalanced_configuration |
||
| 67 | @user_domain = "greenlight" |
||
| 68 | else |
||
| 69 | @user_domain = parse_user_domain(request.host) |
||
| 70 | |||
| 71 | check_provider_exists |
||
| 72 | end |
||
| 73 | end |
||
| 74 | |||
| 75 | # Sets the settinfs variable |
||
| 76 | def set_user_settings |
||
| 77 | @settings = Setting.find_or_create_by(provider: @user_domain) |
||
| 78 | end |
||
| 79 | |||
| 80 | # Redirects users to a Maintenance Page if the ENV variable is set to true |
||
| 81 | def maintenance_mode? |
||
| 82 | if Rails.configuration.maintenance_mode |
||
| 83 | render "errors/greenlight_error", status: 503, formats: :html, |
||
| 84 | locals: { |
||
| 85 | status_code: 503, |
||
| 86 | message: I18n.t("errors.maintenance.message"), |
||
| 87 | help: I18n.t("errors.maintenance.help"), |
||
| 88 | } |
||
| 89 | end |
||
| 90 | if Rails.configuration.maintenance_window.present? |
||
| 91 | unless cookies[:maintenance_window] == Rails.configuration.maintenance_window |
||
| 92 | flash.now[:maintenance] = I18n.t("maintenance.window_alert", date: Rails.configuration.maintenance_window) |
||
| 93 | end |
||
| 94 | end |
||
| 95 | end |
||
| 96 | |||
| 97 | # Show an information page when migration fails and there is a version error. |
||
| 98 | def migration_error? |
||
| 99 | render :migration_error unless ENV["DB_MIGRATE_FAILED"].blank? |
||
| 100 | end |
||
| 101 | |||
| 102 | # Sets the appropriate locale. |
||
| 103 | def user_locale(user = current_user) |
||
| 104 | locale = if user && user.language != 'default' |
||
| 105 | user.language |
||
| 106 | else |
||
| 107 | http_accept_language.language_region_compatible_from(I18n.available_locales) |
||
| 108 | end |
||
| 109 | I18n.locale = locale.tr('-', '_') unless locale.nil? |
||
| 110 | end |
||
| 111 | |||
| 112 | # Checks to make sure that the admin has changed his password from the default |
||
| 113 | def check_admin_password |
||
| 114 | if current_user&.has_role?(:admin) && current_user.email == "[email protected]" && |
||
| 115 | current_user&.greenlight_account? && current_user&.authenticate(Rails.configuration.admin_password_default) |
||
| 116 | |||
| 117 | flash.now[:alert] = I18n.t("default_admin", |
||
| 118 | edit_link: edit_user_path(user_uid: current_user.uid) + "?setting=password").html_safe |
||
| 119 | end |
||
| 120 | end |
||
| 121 | |||
| 122 | # Checks if the user is banned and logs him out if he is |
||
| 123 | def check_user_role |
||
| 124 | if current_user&.has_role? :denied |
||
| 125 | session.delete(:user_id) |
||
| 126 | redirect_to root_path, flash: { alert: I18n.t("registration.banned.fail") } |
||
| 127 | elsif current_user&.has_role? :pending |
||
| 128 | session.delete(:user_id) |
||
| 129 | redirect_to root_path, flash: { alert: I18n.t("registration.approval.fail") } |
||
| 130 | end |
||
| 131 | end |
||
| 132 | |||
| 133 | # Redirects the user to a Maintenance page if turned on |
||
| 134 | def maintenance_mode? |
||
| 135 | if ENV["MAINTENANCE_MODE"] == "true" |
||
| 136 | render "errors/greenlight_error", status: 503, formats: :html, |
||
| 137 | locals: { |
||
| 138 | status_code: 503, |
||
| 139 | message: I18n.t("errors.maintenance.message"), |
||
| 140 | help: I18n.t("errors.maintenance.help"), |
||
| 141 | } |
||
| 142 | end |
||
| 143 | end |
||
| 144 | |||
| 145 | # Relative root helper (when deploying to subdirectory). |
||
| 146 | def relative_root |
||
| 147 | Rails.configuration.relative_url_root || "" |
||
| 148 | end |
||
| 149 | helper_method :relative_root |
||
| 150 | |||
| 151 | # Determines if the BigBlueButton endpoint is configured (or set to default). |
||
| 152 | def bigbluebutton_endpoint_default? |
||
| 153 | return false if Rails.configuration.loadbalanced_configuration |
||
| 154 | Rails.configuration.bigbluebutton_endpoint_default == Rails.configuration.bigbluebutton_endpoint |
||
| 155 | end |
||
| 156 | helper_method :bigbluebutton_endpoint_default? |
||
| 157 | |||
| 158 | def allow_greenlight_accounts? |
||
| 159 | return Rails.configuration.allow_user_signup unless Rails.configuration.loadbalanced_configuration |
||
| 160 | return false unless @user_domain && !@user_domain.empty? && Rails.configuration.allow_user_signup |
||
| 161 | return false if @user_domain == "greenlight" |
||
| 162 | # Proceed with retrieving the provider info |
||
| 163 | begin |
||
| 164 | provider_info = retrieve_provider_info(@user_domain, 'api2', 'getUserGreenlightCredentials') |
||
| 165 | provider_info['provider'] == 'greenlight' |
||
| 166 | rescue => e |
||
| 167 | logger.error "Error in checking if greenlight accounts are allowed: #{e}" |
||
| 168 | false |
||
| 169 | end |
||
| 170 | end |
||
| 171 | helper_method :allow_greenlight_accounts? |
||
| 172 | |||
| 173 | # Determine if Greenlight is configured to allow user signups. |
||
| 174 | def allow_user_signup? |
||
| 175 | Rails.configuration.allow_user_signup |
||
| 176 | end |
||
| 177 | helper_method :allow_user_signup? |
||
| 178 | |||
| 179 | # Gets all configured omniauth providers. |
||
| 180 | def configured_providers |
||
| 181 | Rails.configuration.providers.select do |provider| |
||
| 182 | Rails.configuration.send("omniauth_#{provider}") |
||
| 183 | end |
||
| 184 | end |
||
| 185 | helper_method :configured_providers |
||
| 186 | |||
| 187 | # Parses the url for the user domain |
||
| 188 | View Code Duplication | def parse_user_domain(hostname) |
|
|
|
|||
| 189 | return hostname.split('.').first if Rails.configuration.url_host.empty? |
||
| 190 | Rails.configuration.url_host.split(',').each do |url_host| |
||
| 191 | return hostname.chomp(url_host).chomp('.') if hostname.include?(url_host) |
||
| 192 | end |
||
| 193 | '' |
||
| 194 | end |
||
| 195 | |||
| 196 | # Include user domain in lograge logs |
||
| 197 | def append_info_to_payload(payload) |
||
| 198 | super |
||
| 199 | payload[:host] = @user_domain |
||
| 200 | end |
||
| 201 | |||
| 202 | # Manually Handle BigBlueButton errors |
||
| 203 | def handle_bigbluebutton_error |
||
| 204 | render "errors/bigbluebutton_error" |
||
| 205 | end |
||
| 206 | |||
| 207 | # Manually deal with 401 errors |
||
| 208 | rescue_from CanCan::AccessDenied do |_exception| |
||
| 209 | render "errors/greenlight_error" |
||
| 210 | end |
||
| 211 | |||
| 212 | private |
||
| 213 | |||
| 214 | def check_provider_exists |
||
| 215 | # Checks to see if the user exists |
||
| 216 | begin |
||
| 217 | # Check if the session has already checked that the user exists |
||
| 218 | # and return true if they did for this domain |
||
| 219 | return if session[:provider_exists] == @user_domain |
||
| 220 | |||
| 221 | retrieve_provider_info(@user_domain, 'api2', 'getUserGreenlightCredentials') |
||
| 222 | |||
| 223 | # Add a session variable if the provider exists |
||
| 224 | session[:provider_exists] = @user_domain |
||
| 225 | rescue => e |
||
| 226 | logger.error "Error in retrieve provider info: #{e}" |
||
| 227 | # Use the default site settings |
||
| 228 | @user_domain = "greenlight" |
||
| 229 | |||
| 230 | if e.message.eql? "No user with that id exists" |
||
| 231 | render "errors/greenlight_error", locals: { message: I18n.t("errors.not_found.user_not_found.message"), |
||
| 232 | help: I18n.t("errors.not_found.user_not_found.help") } |
||
| 233 | elsif e.message.eql? "Provider not included." |
||
| 234 | render "errors/greenlight_error", locals: { message: I18n.t("errors.not_found.user_missing.message"), |
||
| 235 | help: I18n.t("errors.not_found.user_missing.help") } |
||
| 236 | elsif e.message.eql? "That user has no configured provider." |
||
| 237 | render "errors/greenlight_error", locals: { status_code: 501, |
||
| 238 | message: I18n.t("errors.no_provider.message"), |
||
| 239 | help: I18n.t("errors.no_provider.help") } |
||
| 240 | else |
||
| 241 | render "errors/greenlight_error", locals: { status_code: 500, message: I18n.t("errors.internal.message"), |
||
| 242 | help: I18n.t("errors.internal.help"), display_back: true } |
||
| 243 | end |
||
| 244 | end |
||
| 245 | end |
||
| 246 | end |
||
| 247 |