Passed
Push — master ( 23b088...27bc68 )
by Ahmad
06:31
created

User.shared_list_search()   A

Complexity

Conditions 2

Size

Total Lines 10

Duplication

Lines 10
Ratio 100 %

Importance

Changes 0
Metric Value
cc 2
dl 10
loc 10
rs 9.9
c 0
b 0
f 0
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 Deleteable
23
24
  after_create :setup_user
25
26
  before_save { email.try(:downcase!) }
27
28
  before_destroy :destroy_rooms
29
30
  has_many :rooms
31
  has_many :shared_access
32
  belongs_to :main_room, class_name: 'Room', foreign_key: :room_id, required: false
33
34
  has_and_belongs_to_many :roles, join_table: :users_roles # obsolete
35
36
  belongs_to :role, required: false
37
38
  validates :name, length: { maximum: 256 }, presence: true,
39
                   format: { without: %r{https?://}i }
40
  validates :provider, presence: true
41
  validate :check_if_email_can_be_blank
42
  validates :email, length: { maximum: 256 }, allow_blank: true,
43
                    uniqueness: { case_sensitive: false, scope: :provider },
44
                    format: { with: /\A[\w+\-\'.]+@[a-z\d\-.]+\.[a-z]+\z/i }
45
46
  validates :password, length: { minimum: 6 }, confirmation: true, if: :greenlight_account?, on: :create
47
48
  # Bypass validation if omniauth
49
  validates :accepted_terms, acceptance: true,
50
                             unless: -> { !greenlight_account? || !Rails.configuration.terms }
51
52
  # We don't want to require password validations on all accounts.
53
  has_secure_password(validations: false)
54
55
  class << self
56
    include AuthValues
57
    include Queries
58
59
    # Generates a user from omniauth.
60
    def from_omniauth(auth)
61
      # Provider is the customer name if in loadbalanced config mode
62
      provider = auth['provider'] == "bn_launcher" ? auth['info']['customer'] : auth['provider']
63
      find_or_initialize_by(social_uid: auth['uid'], provider: provider).tap do |u|
64
        u.name = auth_name(auth) unless u.name
65
        u.username = auth_username(auth) unless u.username
66
        u.email = auth_email(auth)
67
        u.image = auth_image(auth) unless u.image
68
        auth_roles(u, auth)
69
        u.email_verified = true
70
        u.save!
71
      end
72
    end
73
74
    def admins_search(string)
75
      return all if string.blank?
76
77
      like = like_text # Get the correct like clause to use based on db adapter
78
79
      search_query = "users.name #{like} :search OR email #{like} :search OR username #{like} :search" \
80
                    " OR users.#{created_at_text} #{like} :search OR users.provider #{like} :search" \
81
                    " OR roles.name #{like} :search"
82
83
      search_param = "%#{sanitize_sql_like(string)}%"
84
      where(search_query, search: search_param)
85
    end
86
87
    def admins_order(column, direction)
88
      # Arel.sql to avoid sql injection
89
      order(Arel.sql("users.#{column} #{direction}"))
90
    end
91
92 View Code Duplication
    def shared_list_search(string)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
93
      return all if string.blank?
94
95
      like = like_text # Get the correct like clause to use based on db adapter
96
97
      search_query = "users.name #{like} :search OR users.uid #{like} :search"
98
99
      search_param = "%#{sanitize_sql_like(string)}%"
100
      where(search_query, search: search_param)
101
    end
102
103 View Code Duplication
    def merge_list_search(string)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
104
      return all if string.blank?
105
106
      like = like_text # Get the correct like clause to use based on db adapter
107
108
      search_query = "users.name #{like} :search OR users.email #{like} :search"
109
110
      search_param = "%#{sanitize_sql_like(string)}%"
111
      where(search_query, search: search_param)
112
    end
113
  end
114
115
  # Returns a list of rooms ordered by last session (with nil rooms last)
116
  def ordered_rooms
117
    return [] if main_room.nil?
118
119
    [main_room] + rooms.where.not(id: main_room.id).order(Arel.sql("last_session IS NULL, last_session desc"))
120
  end
121
122
  # Activates an account and initialize a users main room
123
  def activate
124
    set_role :user if role_id.nil?
125
    update_attributes(email_verified: true, activated_at: Time.zone.now, activation_digest: nil)
126
  end
127
128
  def activated?
129
    Rails.configuration.enable_email_verification ? email_verified : true
130
  end
131
132
  def self.hash_token(token)
133
    Digest::SHA2.hexdigest(token)
134
  end
135
136
  # Sets the password reset attributes.
137
  def create_reset_digest
138
    new_token = SecureRandom.urlsafe_base64
139
    update_attributes(reset_digest: User.hash_token(new_token), reset_sent_at: Time.zone.now)
140
    new_token
141
  end
142
143
  def create_activation_token
144
    new_token = SecureRandom.urlsafe_base64
145
    update_attributes(activation_digest: User.hash_token(new_token))
146
    new_token
147
  end
148
149
  # Return true if password reset link expires
150
  def password_reset_expired?
151
    reset_sent_at < 2.hours.ago
152
  end
153
154
  # Retrieves a list of rooms that are shared with the user
155
  def shared_rooms
156
    Room.where(id: shared_access.pluck(:room_id))
157
  end
158
159
  def name_chunk
160
    charset = ("a".."z").to_a - %w(b i l o s) + ("2".."9").to_a - %w(5 8)
161
    chunk = name.parameterize[0...3]
162
    if chunk.empty?
163
      chunk + (0...3).map { charset.to_a[rand(charset.size)] }.join
164
    elsif chunk.length == 1
165
      chunk + (0...2).map { charset.to_a[rand(charset.size)] }.join
166
    elsif chunk.length == 2
167
      chunk + (0...1).map { charset.to_a[rand(charset.size)] }.join
168
    else
169
      chunk
170
    end
171
  end
172
173
  def greenlight_account?
174
    social_uid.nil?
175
  end
176
177
  def admin_of?(user, permission)
178
    has_correct_permission = role.get_permission(permission) && id != user.id
179
180
    return has_correct_permission unless Rails.configuration.loadbalanced_configuration
181
    return id != user.id if has_role? :super_admin
182
    has_correct_permission && provider == user.provider && !user.has_role?(:super_admin)
183
  end
184
185
  # role functions
186
  def set_role(role) # rubocop:disable Naming/AccessorMethodName
187
    return if has_role?(role)
188
189
    new_role = Role.find_by(name: role, provider: role_provider)
190
191
    return if new_role.nil?
192
193
    create_home_room if main_room.nil? && new_role.get_permission("can_create_rooms")
194
195
    update_attribute(:role, new_role)
196
197
    new_role
198
  end
199
200
  # This rule is disabled as the function name must be has_role?
201
  def has_role?(role_name) # rubocop:disable Naming/PredicateName
202
    role&.name == role_name.to_s
203
  end
204
205 View Code Duplication
  def self.with_role(role)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
206
    User.includes(:role).where(roles: { name: role })
207
  end
208
209 View Code Duplication
  def self.without_role(role)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
210
    User.includes(:role).where.not(roles: { name: role })
211
  end
212
213
  def create_home_room
214
    room = Room.create!(owner: self, name: I18n.t("home_room"))
215
    update_attributes(main_room: room)
216
  end
217
218
  private
219
220
  # Destory a users rooms when they are removed.
221
  def destroy_rooms
222
    rooms.destroy_all
223
  end
224
225
  def setup_user
226
    # Initializes a room for the user and assign a BigBlueButton user id.
227
    id = "gl-#{(0...12).map { rand(65..90).chr }.join.downcase}"
228
229
    update_attributes(uid: id)
230
231
    # Initialize the user to use the default user role
232
    role_provider = Rails.configuration.loadbalanced_configuration ? provider : "greenlight"
233
234
    Role.create_default_roles(role_provider) if Role.where(provider: role_provider).count.zero?
235
  end
236
237
  def check_if_email_can_be_blank
238
    if email.blank?
239
      if Rails.configuration.loadbalanced_configuration && greenlight_account?
240
        errors.add(:email, I18n.t("errors.messages.blank"))
241
      elsif provider == "greenlight"
242
        errors.add(:email, I18n.t("errors.messages.blank"))
243
      end
244
    end
245
  end
246
247
  def role_provider
248
    Rails.configuration.loadbalanced_configuration ? provider : "greenlight"
249
  end
250
end
251