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 |