scinote-web/app/controllers/users/registrations_controller.rb

294 lines
9 KiB
Ruby
Raw Normal View History

2016-02-12 23:52:43 +08:00
class Users::RegistrationsController < Devise::RegistrationsController
2016-11-22 21:57:41 +08:00
prepend_before_action :check_captcha, only: [:create]
2018-02-26 18:05:05 +08:00
before_action :registration_enabled?,
only: %i(new create new_with_provider create_with_provider)
before_action :sign_up_with_provider_enabled?,
only: %i(new_with_provider create_with_provider)
2018-04-06 23:16:04 +08:00
layout :layout
2016-02-12 23:52:43 +08:00
def avatar
2016-07-21 19:11:15 +08:00
user = User.find_by_id(params[:id]) || current_user
style = params[:style] || :icon_small
redirect_to user.avatar_url(style)
2016-02-12 23:52:43 +08:00
end
def update_resource(resource, params)
2016-07-21 19:11:15 +08:00
@user_avatar_url = avatar_path(current_user, :thumb)
2016-02-12 23:52:43 +08:00
if params.include? :change_password
# Special handling if changing password
params.delete(:change_password)
if resource.valid_password?(params[:current_password]) &&
params.include?(:password) &&
params.include?(:password_confirmation) &&
params[:password].blank?
2016-02-12 23:52:43 +08:00
# If new password is blank and we're in process of changing
# password, add error to the resource and return false
resource.errors.add(:password, :blank)
false
else
resource.update_with_password(params)
end
elsif params.include? :change_avatar
params.delete(:change_avatar)
if !params.include?(:avatar) || (params[:avatar].length > Constants::AVATAR_MAX_SIZE_MB.megabytes * 2)
2016-02-12 23:52:43 +08:00
resource.errors.add(:avatar, :blank)
false
else
temp_file = Tempfile.new('avatar', Rails.root.join('tmp'))
begin
2019-10-02 15:52:37 +08:00
check_extension = params[:avatar].split(';')[0].split('/')[1]
temp_file.binmode
2019-10-02 15:52:37 +08:00
temp_file.write(Base64.decode64(params[:avatar].split(',')[1]))
temp_file.rewind
2019-10-02 15:52:37 +08:00
resource.avatar.attach(io: temp_file, filename: "avatar.#{check_extension}")
ensure
temp_file.close
temp_file.unlink
end
params.delete(:avatar)
2016-02-12 23:52:43 +08:00
resource.update_without_password(params)
end
elsif params.include?(:email) || params.include?(:password)
2016-02-12 23:52:43 +08:00
# For changing email or password, validate current_password
resource.update_with_password(params)
else
# For changing some attributes, no current_password validation
# is required
resource.update_without_password(params)
end
end
# Override default registrations_controller.rb implementation
# to support JSON
def update
change_password = account_update_params.include? :change_password
respond_to do |format|
self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)
resource_updated = update_resource(resource, account_update_params)
2016-02-12 23:52:43 +08:00
yield resource if block_given?
if resource_updated
# Set "needs confirmation" flash if neccesary
2019-10-02 19:22:07 +08:00
if is_flashing_format? || account_update_params['change_avatar']
2016-02-12 23:52:43 +08:00
flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?
:update_needs_confirmation : :updated
set_flash_message :notice, flash_key
end
# Set "password successfully updated" flash if neccesary
if change_password
set_flash_message :notice, :password_changed
end
format.html {
sign_in resource_name, resource, bypass: true
respond_with resource, location: edit_user_registration_path
}
format.json {
flash.keep
sign_in resource_name, resource, bypass: true
render json: {}
2016-02-12 23:52:43 +08:00
}
else
clean_up_passwords resource
format.html {
respond_with resource, location: edit_user_registration_path
}
format.json {
2016-08-18 02:49:20 +08:00
render json: resource.errors, status: :bad_request
2016-02-12 23:52:43 +08:00
}
end
end
end
2018-02-26 18:05:05 +08:00
def new; end
2016-02-12 23:52:43 +08:00
def create
build_resource(sign_up_params)
valid_resource = resource.valid?
# ugly checking if new team on sign up is enabled :(
if Rails.configuration.x.new_team_on_signup
# Create new team for the new user
@team = Team.new
@team.name = params[:team][:name]
valid_team = @team.valid?
if valid_team && valid_resource
# this must be called after @team variable is defined. Otherwise this
# variable won't be accessable in view.
super do |resource|
# Set the confirmed_at == created_at IF not using email confirmations
unless Rails.configuration.x.enable_email_confirmations
resource.update(confirmed_at: resource.created_at)
end
2016-02-12 23:52:43 +08:00
if resource.valid? && resource.persisted?
@team.created_by = resource # set created_by for oraganization
@team.save
2016-02-12 23:52:43 +08:00
# Add this user to the team as owner
UserTeam.create(user: resource, team: @team, role: :admin)
2016-10-12 18:02:04 +08:00
# set current team to new user
resource.current_team_id = @team.id
resource.save
end
2016-02-12 23:52:43 +08:00
end
else
render :new
2016-02-12 23:52:43 +08:00
end
2017-10-26 16:42:18 +08:00
elsif valid_resource
super do |resource|
# Set the confirmed_at == created_at IF not using email confirmations
unless Rails.configuration.x.enable_email_confirmations
resource.update(confirmed_at: resource.created_at)
resource.save
end
end
2017-10-26 16:42:18 +08:00
else
render :new
2016-02-12 23:52:43 +08:00
end
end
2018-02-26 18:05:05 +08:00
def new_with_provider; end
def create_with_provider
@user = User.find_by_id(user_provider_params['user'])
# Create new team for the new user
@team = Team.new(team_provider_params)
2018-03-05 20:12:44 +08:00
if @team.valid? && @user && Rails.configuration.x.new_team_on_signup
2018-02-26 18:05:05 +08:00
# Set the confirmed_at == created_at IF not using email confirmations
unless Rails.configuration.x.enable_email_confirmations
@user.update!(confirmed_at: @user.created_at)
end
@team.created_by = @user # set created_by for team
@team.save!
# Add this user to the team as owner
UserTeam.create(user: @user, team: @team, role: :admin)
# set current team to new user
@user.current_team_id = @team.id
@user.save!
sign_in_and_redirect @user
else
render :new_with_provider
end
end
2020-07-01 17:07:33 +08:00
def two_factor_enable
2020-07-01 20:41:55 +08:00
if current_user.valid_otp?(params[:submit_code])
2020-07-09 23:01:00 +08:00
recovery_codes = current_user.enable_2fa!
render json: { recovery_codes: recovery_codes }
2020-07-01 17:07:33 +08:00
else
render json: { error: t('users.registrations.edit.2fa_errors.wrong_submit_code') }, status: :unprocessable_entity
end
end
def two_factor_disable
if current_user.valid_password?(params[:password])
2020-07-01 21:44:52 +08:00
current_user.disable_2fa!
2020-07-01 17:07:33 +08:00
redirect_to edit_user_registration_path
else
render json: { error: t('users.registrations.edit.2fa_errors.wrong_password') }, status: :forbidden
end
end
def two_factor_qr_code
2020-07-02 17:24:33 +08:00
current_user.assign_2fa_token!
2020-07-01 17:07:33 +08:00
qr_code_url = ROTP::TOTP.new(current_user.otp_secret, issuer: 'SciNote').provisioning_uri(current_user.email)
qr_code = RQRCode::QRCode.new(qr_code_url)
2020-07-07 18:59:48 +08:00
render json: { qr_code: qr_code.as_svg(module_size: 4) }
2020-07-01 17:07:33 +08:00
end
2016-02-12 23:52:43 +08:00
protected
# Called upon creating User (before .save). Permits parameters and extracts
# initials from :full_name (takes at most 4 chars). If :full_name is empty, it
# uses "PLCH" as a placeholder (user won't get error complaining about
# initials being empty.
def sign_up_params
tmp = params.require(:user).permit(:full_name, :initials, :email, :password, :password_confirmation)
initials = tmp[:full_name].titleize.scan(/[A-Z]+/).join()
initials = if initials.strip.empty?
'PLCH'
else
initials[0..Constants::USER_INITIALS_MAX_LENGTH]
end
2016-02-12 23:52:43 +08:00
tmp.merge(:initials => initials)
end
2018-02-26 18:05:05 +08:00
def team_provider_params
params.require(:team).permit(:name)
end
def user_provider_params
params.permit(:user)
end
2016-02-12 23:52:43 +08:00
def account_update_params
params.require(:user).permit(
:full_name,
:initials,
:avatar,
:email,
:password,
:password_confirmation,
:current_password,
:change_password,
:change_avatar
)
end
def avatar_params
params.permit(
2016-08-18 02:49:20 +08:00
:file
)
2016-08-18 02:49:20 +08:00
end
2016-02-12 23:52:43 +08:00
private
2018-04-06 23:16:04 +08:00
def layout
'fluid' if action_name == 'edit'
end
2016-11-22 21:57:41 +08:00
def check_captcha
if Rails.configuration.x.enable_recaptcha
unless verify_recaptcha
# Construct new resource before rendering :new
2016-11-22 21:57:41 +08:00
self.resource = resource_class.new sign_up_params
# Also validate team
@team = Team.new(name: params[:team][:name])
@team.valid?
2016-11-22 21:57:41 +08:00
respond_with_navigational(resource) { render :new }
end
end
end
2018-02-26 18:05:05 +08:00
def registration_enabled?
render_403 unless Rails.configuration.x.enable_user_registration
end
def sign_up_with_provider_enabled?
render_403 unless Rails.configuration.x.linkedin_signin_enabled
end
2016-02-12 23:52:43 +08:00
# Redirect to login page after signing up
def after_sign_up_path_for(resource)
new_user_session_path
end
# Redirect to login page after signing up
def after_inactive_sign_up_path_for(resource)
new_user_session_path
end
end