-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Expand file tree
/
Copy pathusers_controller.rb
More file actions
192 lines (150 loc) · 7.67 KB
/
users_controller.rb
File metadata and controls
192 lines (150 loc) · 7.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2022 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# Greenlight is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with Greenlight; if not, see <http://www.gnu.org/licenses/>.
# frozen_string_literal: true
module Api
module V1
class UsersController < ApiController
include ClientRoutable
skip_before_action :ensure_authenticated, only: %i[create]
before_action except: %i[create change_password] do
ensure_authorized('ManageUsers', user_id: params[:id])
end
# GET /api/v1/users/:id.json
# Returns the details of a specific user
def show
user = User.find(params[:id])
render_data data: user, status: :ok
end
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
# POST /api/v1/users.json
# Creates and saves a new user record in the database with the provided parameters
def create
return render_error status: :forbidden if external_auth?
# Check if this is an admin creating a user
admin_create = current_user && PermissionsChecker.new(current_user:, permission_names: 'ManageUsers', current_provider:).call
# Allow only administrative access for authenticated requests
return render_error status: :forbidden if current_user && !admin_create
registration_method = SettingGetter.new(setting_name: 'RegistrationMethod', provider: current_provider).call
if registration_method == SiteSetting::REGISTRATION_METHODS[:invite] && !admin_create
if create_user_params[:invite_token].blank?
return render_error errors: Rails.configuration.custom_error_msgs[:invite_token_invalid]
end
invite = Invitation.find_by(provider: current_provider, token: create_user_params[:invite_token])
if !invite.present?
return render_error errors: Rails.configuration.custom_error_msgs[:invite_token_invalid]
end
create_user_params[:email] = invite.email
invite.destroy
end
# TODO: Add proper error logging for non-verified token hcaptcha
if !admin_create && hcaptcha_enabled? && !verify_hcaptcha(response: params[:token])
return render_error errors: Rails.configuration.custom_error_msgs[:hcaptcha_invalid]
end
# Users created by a user will have the creator language by default with a fallback to the server configured default_locale.
create_user_params[:language] = current_user&.language || I18n.default_locale if create_user_params[:language].blank?
user = UserCreator.new(user_params: create_user_params.except(:invite_token), provider: current_provider, role: default_role).call
smtp_enabled = ENV['SMTP_SERVER'].present?
user.verify! unless smtp_enabled
# Set to pending if registration method is approval
user.pending! if !admin_create && registration_method == SiteSetting::REGISTRATION_METHODS[:approval]
if user.save
if smtp_enabled
token = user.generate_activation_token!
UserMailer.with(user:,
activation_url: activate_account_url(token), base_url: request.base_url,
provider: current_provider).activate_account_email.deliver_later
UserMailer.with(user:, admin_panel_url:, base_url: request.base_url, provider: current_provider).new_user_signup_email.deliver_later
end
create_default_room(user)
return render_data data: user, serializer: CurrentUserSerializer, status: :created unless user.verified?
user.generate_session_token!
session[:session_token] = user.session_token unless admin_create # if this is NOT an admin creating a user
render_data data: user, serializer: CurrentUserSerializer, status: :created
elsif user.errors.size == 1 && user.errors.of_kind?(:email, :taken)
render_error errors: Rails.configuration.custom_error_msgs[:email_exists], status: :bad_request
else
render_error errors: Rails.configuration.custom_error_msgs[:record_invalid], status: :bad_request
end
end
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
# PATCH /api/v1/users/:id.json
# Updates the values of a user
def update
user = User.find(params[:id])
# User can't change their own role
if params[:user][:role_id].present? && current_user == user && params[:user][:role_id] != user.role_id
return render_error errors: Rails.configuration.custom_error_msgs[:unauthorized], status: :forbidden
end
original_avatar = params['user']['original_avatar']
if ENV.fetch('CLAMAV_SCANNING', 'false') == 'true' && original_avatar.present? && !Clamby.safe?(original_avatar.tempfile.path)
user.errors.add(:avatar, 'MalwareDetected')
return render_error errors: user.errors.to_a
end
if user.update(update_user_params)
create_default_room(user)
render_data status: :ok
else
render_error errors: user.errors.to_a
end
end
# DELETE /api/v1/users/:id.json
# Deletes a user
def destroy
user = User.find(params[:id])
if user.destroy
render_data status: :ok
else
render_error errors: Rails.configuration.custom_error_msgs[:record_invalid]
end
end
# DELETE /api/v1/users/:id/purge_avatar.json
# Removes the avatar attached to the user
def purge_avatar
user = User.find(params[:id])
user.avatar.purge
render_data status: :ok
end
# POST /api/v1/users/change_password.json
# Validates and change the user's password
def change_password
return render_error status: :forbidden if current_user.external_id?
old_password = change_password_params[:old_password]
new_password = change_password_params[:new_password]
return render_error status: :bad_request if new_password.blank? || old_password.blank?
unless current_user.authenticate old_password
return render_error status: :bad_request,
errors: Rails.configuration.custom_error_msgs[:incorrect_old_password]
end
current_user.update! password: new_password
render_data status: :ok
end
private
def create_user_params
@create_user_params ||= params.require(:user).permit(:name, :email, :password, :avatar, :language, :role_id, :invite_token)
end
def update_user_params
@update_user_params ||= if external_auth?
params.require(:user).permit(:password, :avatar, :language, :role_id, :invite_token)
else
params.require(:user).permit(:name, :password, :avatar, :language, :role_id, :invite_token)
end
end
def change_password_params
params.require(:user).permit(:old_password, :new_password)
end
end
end
end