GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — master (#709)
by Jesus
38:17 queued 33:16
created

User   F

Complexity

Total Complexity 63

Size/Duplication

Total Lines 305
Duplicated Lines 0 %

Importance

Changes 7
Bugs 0 Features 0
Metric Value
c 7
b 0
f 0
dl 0
loc 305
rs 3.36
wmc 63

17 Methods

Rating   Name   Duplication   Size   Complexity  
A from_omniauth() 0 13 2
A new_token() 0 3 1
A admins_order() 0 4 1
A admin_of? 0 12 3
A activate() 0 5 1
A digest() 0 4 2
A auth_roles() 0 11 3
A authenticated? 0 5 2
A admins_search() 0 28 3
A highest_priority_role() 0 3 1
A add_role() 0 9 3
A remove_role() 0 8 3
A with_role() 0 3 1
A check_if_email_can_be_blank() 0 9 5
A all_users_with_roles() 0 4 1
A assign_default_role() 0 7 4
A without_role() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like User 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
2
3
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
4
#
5
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
6
#
7
# This program is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU Lesser General Public License as published by the Free Software
9
# Foundation; either version 3.0 of the License, or (at your option) any later
10
# version.
11
#
12
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
14
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
15
#
16
# You should have received a copy of the GNU Lesser General Public License along
17
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
18
19
require 'bbb_api'
20
21
class User < ApplicationRecord
22
  include ::BbbApi
23
24
  attr_accessor :reset_token
25
  after_create :assign_default_role
26
  after_create :initialize_main_room
27
28
  before_save { email.try(:downcase!) }
29
30
  before_destroy :destroy_rooms
31
32
  has_many :rooms
33
  belongs_to :main_room, class_name: 'Room', foreign_key: :room_id, required: false
34
35
  has_and_belongs_to_many :roles, join_table: :users_roles
36
37
  validates :name, length: { maximum: 256 }, presence: true
38
  validates :provider, presence: true
39
  validate :check_if_email_can_be_blank
40
  validates :email, length: { maximum: 256 }, allow_blank: true,
41
                    uniqueness: { case_sensitive: false, scope: :provider },
42
                    format: { with: /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i }
43
44
  validates :password, length: { minimum: 6 }, confirmation: true, if: :greenlight_account?, on: :create
45
46
  # Bypass validation if omniauth
47
  validates :accepted_terms, acceptance: true,
48
                             unless: -> { !greenlight_account? || !Rails.configuration.terms }
49
50
  # We don't want to require password validations on all accounts.
51
  has_secure_password(validations: false)
52
53
  class << self
54
    # Generates a user from omniauth.
55
    def from_omniauth(auth)
56
      # Provider is the customer name if in loadbalanced config mode
57
      provider = auth['provider'] == "bn_launcher" ? auth['info']['customer'] : auth['provider']
58
      find_or_initialize_by(social_uid: auth['uid'], provider: provider).tap do |u|
59
        u.name = auth_name(auth) unless u.name
60
        u.username = auth_username(auth) unless u.username
61
        u.email = auth_email(auth)
62
        u.image = auth_image(auth) unless u.image
63
        auth_roles(u, auth)
64
        u.email_verified = true
65
        u.save!
66
      end
67
    end
68
69
    private
70
71
    # Provider attributes.
72
    def auth_name(auth)
73
      case auth['provider']
74
      when :office365
75
        auth['info']['display_name']
76
      else
77
        auth['info']['name']
78
      end
79
    end
80
81
    def auth_username(auth)
82
      case auth['provider']
83
      when :google
84
        auth['info']['email'].split('@').first
85
      when :bn_launcher
86
        auth['info']['username']
87
      else
88
        auth['info']['nickname']
89
      end
90
    end
91
92
    def auth_email(auth)
93
      auth['info']['email']
94
    end
95
96
    def auth_image(auth)
97
      case auth['provider']
98
      when :twitter
99
        auth['info']['image'].gsub("http", "https").gsub("_normal", "")
100
      else
101
        auth['info']['image']
102
      end
103
    end
104
105
    def auth_roles(user, auth)
106
      unless auth['info']['roles'].nil?
107
        roles = auth['info']['roles'].split(',')
108
109
        role_provider = auth['provider'] == "bn_launcher" ? auth['info']['customer'] : "greenlight"
110
        roles.each do |role_name|
111
          role = Role.where(provider: role_provider, name: role_name).first
112
          user.roles << role unless role.nil?
113
        end
114
      end
115
    end
116
  end
117
118
  def self.admins_search(string, role)
119
    active_database = Rails.configuration.database_configuration[Rails.env]["adapter"]
120
    # Postgres requires created_at to be cast to a string
121
    created_at_query = if active_database == "postgresql"
122
      "created_at::text"
123
    else
124
      "created_at"
125
    end
126
127
    search_query = ""
128
    role_search_param = ""
129
    if role.nil?
130
      search_query = "users.name LIKE :search OR email LIKE :search OR username LIKE :search" \
131
                    " OR users.#{created_at_query} LIKE :search OR users.provider LIKE :search" \
132
                    " OR roles.name LIKE :roles_search"
133
      role_search_param = "%#{string}%"
134
    else
135
      search_query = "(users.name LIKE :search OR email LIKE :search OR username LIKE :search" \
136
                    " OR users.#{created_at_query} LIKE :search OR users.provider LIKE :search)" \
137
                    " AND roles.name = :roles_search"
138
      role_search_param = role.name
139
    end
140
141
    search_param = "%#{string}%"
142
    joins("LEFT OUTER JOIN users_roles ON users_roles.user_id = users.id LEFT OUTER JOIN roles " \
143
      "ON roles.id = users_roles.role_id").distinct
144
      .where(search_query, search: search_param, roles_search: role_search_param)
145
  end
146
147
  def self.admins_order(column, direction)
148
    # Arel.sql to avoid sql injection
149
    order(Arel.sql("#{column} #{direction}"))
150
  end
151
152
  # Activates an account and initialize a users main room
153
  def activate
154
    update_attribute(:email_verified, true)
155
    update_attribute(:activated_at, Time.zone.now)
156
    save
157
  end
158
159
  def activated?
160
    return true unless Rails.configuration.enable_email_verification
161
    email_verified
162
  end
163
164
  # Sets the password reset attributes.
165
  def create_reset_digest
166
    self.reset_token = User.new_token
167
    update_attribute(:reset_digest,  User.digest(reset_token))
168
    update_attribute(:reset_sent_at, Time.zone.now)
169
  end
170
171
  # Returns true if the given token matches the digest.
172
  def authenticated?(attribute, token)
173
    digest = send("#{attribute}_digest")
174
    return false if digest.nil?
175
    BCrypt::Password.new(digest).is_password?(token)
176
  end
177
178
  # Return true if password reset link expires
179
  def password_reset_expired?
180
    reset_sent_at < 2.hours.ago
181
  end
182
183
  # Retrives a list of all a users rooms that are not the main room, sorted by last session date.
184
  def secondary_rooms
185
    secondary = (rooms - [main_room])
186
    no_session, session = secondary.partition { |r| r.last_session.nil? }
187
    sorted = session.sort_by(&:last_session)
188
    sorted + no_session
189
  end
190
191
  def name_chunk
192
    charset = ("a".."z").to_a - %w(b i l o s) + ("2".."9").to_a - %w(5 8)
193
    chunk = name.parameterize[0...3]
194
    if chunk.empty?
195
      chunk + (0...3).map { charset.to_a[rand(charset.size)] }.join
196
    elsif chunk.length == 1
197
      chunk + (0...2).map { charset.to_a[rand(charset.size)] }.join
198
    elsif chunk.length == 2
199
      chunk + (0...1).map { charset.to_a[rand(charset.size)] }.join
200
    else
201
      chunk
202
    end
203
  end
204
205
  def greenlight_account?
206
    return true unless provider # For testing cases when provider is set to null
207
    return true if provider == "greenlight"
208
    return false unless Rails.configuration.loadbalanced_configuration
209
    # Proceed with fetching the provider info
210
    provider_info = retrieve_provider_info(provider, 'api2', 'getUserGreenlightCredentials')
211
    provider_info['provider'] == 'greenlight'
212
  end
213
214
  def activation_token
215
    # Create the token.
216
    create_reset_activation_digest(User.new_token)
217
  end
218
219
  def admin_of?(user)
220
    if Rails.configuration.loadbalanced_configuration
221
      if has_role? :super_admin
222
        id != user.id
223
      else
224
        highest_priority_role.can_manage_users && (id != user.id) && (provider == user.provider) &&
225
          (!user.has_role? :super_admin)
226
      end
227
    else
228
      (highest_priority_role.can_manage_users || (has_role? :super_admin)) && (id != user.id)
229
    end
230
  end
231
232
  def self.digest(string)
233
    cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost
234
    BCrypt::Password.create(string, cost: cost)
235
  end
236
237
  # Returns a random token.
238
  def self.new_token
239
    SecureRandom.urlsafe_base64
240
  end
241
242
  # role functions
243
  def highest_priority_role
244
    roles.by_priority.first
245
  end
246
247
  def add_role(role)
248
    unless has_role?(role)
249
      role_provider = Rails.configuration.loadbalanced_configuration ? provider : "greenlight"
250
251
      roles << Role.find_or_create_by(name: role, provider: role_provider)
252
253
      save!
254
    end
255
  end
256
257
  def remove_role(role)
258
    if has_role?(role)
259
      role_provider = Rails.configuration.loadbalanced_configuration ? provider : "greenlight"
260
261
      roles.delete(Role.find_by(name: role, provider: role_provider))
262
      save!
263
    end
264
  end
265
266
  # This rule is disabled as the function name must be has_role?
267
  # rubocop:disable Naming/PredicateName
268
  def has_role?(role)
269
    # rubocop:enable Naming/PredicateName
270
    roles.exists?(name: role)
271
  end
272
273
  def self.with_role(role)
274
    User.all_users_with_roles.where(roles: { name: role })
275
  end
276
277
  def self.without_role(role)
278
    User.where.not(id: with_role(role).pluck(:id))
279
  end
280
281
  def self.all_users_with_roles
282
    User.joins("INNER JOIN users_roles ON users_roles.user_id = users.id INNER JOIN roles " \
283
      "ON roles.id = users_roles.role_id")
284
  end
285
286
  private
287
288
  def create_reset_activation_digest(token)
289
    # Create the digest and persist it.
290
    self.activation_digest = User.digest(token)
291
    save
292
    token
293
  end
294
295
  # Destory a users rooms when they are removed.
296
  def destroy_rooms
297
    rooms.destroy_all
298
  end
299
300
  # Initializes a room for the user and assign a BigBlueButton user id.
301
  def initialize_main_room
302
    self.uid = "gl-#{(0...12).map { rand(65..90).chr }.join.downcase}"
303
    self.main_room = Room.create!(owner: self, name: I18n.t("home_room"))
304
    save
305
  end
306
307
  # Initialize the user to use the default user role
308
  def assign_default_role
309
    role_provider = Rails.configuration.loadbalanced_configuration ? provider : "greenlight"
310
311
    Role.create_default_roles(role_provider) if Role.where(provider: role_provider).count.zero?
312
313
    add_role(:user) if roles.blank?
314
  end
315
316
  def check_if_email_can_be_blank
317
    if email.blank?
318
      if Rails.configuration.loadbalanced_configuration && greenlight_account?
319
        errors.add(:email, I18n.t("errors.messages.blank"))
320
      elsif provider == "greenlight"
321
        errors.add(:email, I18n.t("errors.messages.blank"))
322
      end
323
    end
324
  end
325
end
326