Passed
Push — master ( 6bc43d...2da2ee )
by Ahmad
07:04
created

Rolify.update_priority()   B

Complexity

Conditions 4

Size

Total Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
dl 0
loc 43
rs 8.8478
c 1
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
module Rolify
20
  extend ActiveSupport::Concern
21
22
  # Gets all roles
23
  def all_roles(selected_role)
24
    @roles = Role.editable_roles(@user_domain)
25
26
    if @roles.count.zero?
27
      Role.create_default_roles(@user_domain)
28
      @roles = Role.editable_roles(@user_domain)
29
    end
30
31
    @selected_role = if selected_role.nil?
32
      @roles.find_by(name: 'user')
33
    else
34
      @roles.find(selected_role)
35
    end
36
37
    @roles
38
  end
39
40
  # Creates a new role
41
  def create_role(new_role_name)
42
    # Make sure that the role name isn't a duplicate or a reserved name like super_admin or empty
43
    return nil if Role.duplicate_name(new_role_name, @user_domain) || new_role_name.strip.empty?
44
45
    Role.create_new_role(new_role_name, @user_domain)
46
  end
47
48
  # Updates a user's roles
49
  def update_roles(roles)
50
    # Check that the user can manage users
51
    return true unless current_user.highest_priority_role.get_permission("can_manage_users")
52
53
    new_roles = roles.split(' ').map(&:to_i)
54
    old_roles = @user.roles.pluck(:id)
55
56
    added_role_ids = new_roles - old_roles
57
    removed_role_ids = old_roles - new_roles
58
59
    added_roles = []
60
    removed_roles = []
61
    current_user_role = current_user.highest_priority_role
62
63
    # Check that the user has the permissions to add all the new roles
64
    added_role_ids.each do |id|
65
      role = Role.find(id)
66
67
      # Admins are able to add the admin role to other users. All other roles may only
68
      # add roles with a higher priority
69
      if (role.priority > current_user_role.priority || current_user_role.name == "admin") &&
70
         role.provider == @user_domain
71
        added_roles << role
72
      else
73
        return false
74
      end
75
    end
76
77
    # Check that the user has the permissions to remove all the deleted roles
78
    removed_role_ids.each do |id|
79
      role = Role.find(id)
80
81
      # Admins are able to remove the admin role from other users. All other roles may only
82
      # remove roles with a higher priority
83
      if (role.priority > current_user_role.priority || current_user_role.name == "admin") &&
84
         role.provider == @user_domain
85
        removed_roles << role
86
      else
87
        return false
88
      end
89
    end
90
91
    # Send promoted/demoted emails
92
    added_roles.each { |role| send_user_promoted_email(@user, role) if role.get_permission("send_promoted_email") }
93
    removed_roles.each { |role| send_user_demoted_email(@user, role) if role.get_permission("send_demoted_email") }
94
95
    # Update the roles
96
    @user.roles.delete(removed_roles)
97
    @user.roles << added_roles
98
99
    # Make sure each user always has at least the user role
100
    @user.roles = [Role.find_by(name: "user", provider: @user_domain)] if @user.roles.count.zero?
101
102
    @user.save!
103
  end
104
105
  # Updates a roles priority
106
  def update_priority(role_to_update)
107
    user_role = Role.find_by(name: "user", provider: @user_domain)
108
    admin_role = Role.find_by(name: "admin", provider: @user_domain)
109
110
    current_user_role = current_user.highest_priority_role
111
112
    # Users aren't allowed to update the priority of the admin or user roles
113
    return false if role_to_update.include?(user_role.id.to_s) || role_to_update.include?(admin_role.id.to_s)
114
115
    # Restrict users to only updating the priority for roles in their domain with a higher
116
    # priority
117
    role_to_update.each do |id|
118
      role = Role.find(id)
119
      return false if role.priority <= current_user_role.priority || role.provider != @user_domain
120
    end
121
122
    # Get the priority of the current user's role and start with 1 higher
123
    new_priority = [current_user_role.priority, 0].max + 1
124
125
    begin
126
      # Save the old priorities incase something fails
127
      old_priority = Role.where(id: role_to_update).select(:id, :priority).index_by(&:id)
128
129
      # Set all the priorities to nil to avoid unique column issues
130
      Role.where(id: role_to_update).update_all(priority: nil)
131
132
      # Starting at the starting priority, increase by 1 every time
133
      role_to_update.each_with_index do |id, index|
134
        Role.find(id).update_attribute(:priority, new_priority + index)
135
      end
136
137
      true
138
    rescue => e
139
      # Reset to old prorities
140
      role_to_update.each_with_index do |id, _index|
141
        Role.find(id).update_attribute(:priority, old_priority[id.to_i].priority)
142
      end
143
144
      logger.error "#{current_user} failed to update role priorities: #{e}"
145
146
      false
147
    end
148
  end
149
150
  # Update Permissions
151
  def update_permissions(role)
152
    current_user_role = current_user.highest_priority_role
153
154
    # Checks that it is valid for the provider to update the role
155
    return false if role.priority <= current_user_role.priority || role.provider != @user_domain
156
157
    role_params = params.require(:role).permit(:name)
158
    permission_params = params.require(:role).permit(:can_create_rooms, :send_promoted_email,
159
      :send_demoted_email, :can_edit_site_settings, :can_edit_roles, :can_manage_users,
160
      :can_manage_rooms_recordings, :can_appear_in_share_list, :colour)
161
162
    permission_params.transform_values! do |v|
163
      if v == "0"
164
        "false"
165
      elsif v == "1"
166
        "true"
167
      else
168
        v
169
      end
170
    end
171
172
    # Role is a default role so users can't change the name
173
    role_params[:name] = role.name if Role::RESERVED_ROLE_NAMES.include?(role.name)
174
175
    # Make sure if the user is updating the role name that the role name is valid
176
    if role.name != role_params[:name] && !Role.duplicate_name(role_params[:name], @user_domain) &&
177
       !role_params[:name].strip.empty?
178
      role.name = role_params[:name]
179
    elsif role.name != role_params[:name]
180
      return false
181
    end
182
183
    role.update(colour: permission_params[:colour])
184
    role.update_all_role_permissions(permission_params)
185
186
    role.save!
187
  end
188
end
189