2019-03-16 09:37:35 +00:00
# frozen_string_literal: true
2019-03-15 01:32:57 +00:00
2009-10-29 18:37:00 +00:00
# Redmine - project management software
2024-02-27 20:34:13 +00:00
# Copyright (C) 2006- Jean-Philippe Lang
2007-03-12 17:59:02 +00:00
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
2011-08-31 08:42:38 +00:00
#
2007-03-12 17:59:02 +00:00
# This program 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 General Public License for more details.
2011-08-31 08:42:38 +00:00
#
2007-03-12 17:59:02 +00:00
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class UsersController < ApplicationController
2009-12-17 18:21:02 +00:00
layout 'admin'
2016-11-19 10:30:02 +00:00
self . main_menu = false
2011-08-31 08:42:38 +00:00
2016-07-14 07:27:31 +00:00
before_action :require_admin , :except = > :show
2020-12-17 13:10:13 +00:00
before_action lambda { find_user ( false ) } , :only = > :show
2017-04-03 12:59:55 +00:00
before_action :find_user , :only = > [ :edit , :update , :destroy ]
2011-07-09 08:56:07 +00:00
accept_api_auth :index , :show , :create , :update , :destroy
2007-03-12 17:59:02 +00:00
helper :sort
include SortHelper
helper :custom_fields
2011-08-31 08:42:38 +00:00
include CustomFieldsHelper
2018-08-05 12:30:40 +00:00
include UsersHelper
2014-10-23 21:46:40 +00:00
helper :principal_memberships
2017-12-25 04:38:07 +00:00
helper :activities
include ActivitiesHelper
2022-09-20 03:16:05 +00:00
helper :queries
include QueriesHelper
helper :user_queries
include UserQueriesHelper
2006-07-09 16:30:01 +00:00
2015-06-19 18:41:10 +00:00
require_sudo_mode :create , :update , :destroy
2006-07-09 16:30:01 +00:00
def index
2022-09-20 03:16:05 +00:00
use_session = ! request . format . csv?
retrieve_query ( UserQuery , use_session )
2023-10-17 09:27:31 +00:00
# API backwards compatibility: handle legacy filter parameters
2023-10-15 01:42:07 +00:00
unless request . format . html?
2024-01-25 12:57:08 +00:00
if params . include? ( :status ) && params [ :status ] . blank?
2024-01-25 15:32:57 +00:00
ActiveSupport :: Deprecation . warn " Getting all users from API using an empty status param (status=) is deprecated and it will be removed in Redmine 6.0. Please use \" status=* \" . "
2024-01-25 12:57:08 +00:00
@query . add_filter 'status' , '*'
2023-10-15 01:42:07 +00:00
end
if name = params [ :name ] . presence
@query . add_filter 'name' , '~' , [ name ]
end
if group_id = params [ :group_id ] . presence
@query . add_filter 'is_member_of_group' , '=' , [ group_id ]
end
end
2022-09-20 03:16:05 +00:00
if @query . valid?
scope = @query . results_scope
@user_count = scope . count
respond_to do | format |
format . html do
@limit = per_page_option
@user_pages = Paginator . new @user_count , @limit , params [ 'page' ]
@offset || = @user_pages . offset
@users = scope . limit ( @limit ) . offset ( @offset ) . to_a
render :layout = > ! request . xhr?
end
format . csv do
# Export all entries
@entries = scope . to_a
2023-03-01 08:47:28 +00:00
send_data ( query_to_csv ( @entries , @query , params ) , :type = > 'text/csv; header=present' , :filename = > " #{ filename_for_export ( @query , 'users' ) } .csv " )
2022-09-20 03:16:05 +00:00
end
format . api do
@offset , @limit = api_offset_and_limit
@users = scope . limit ( @limit ) . offset ( @offset ) . to_a
end
2022-01-22 08:53:41 +00:00
end
2022-09-20 03:16:05 +00:00
else
respond_to do | format |
format . html { render :layout = > ! request . xhr? }
format . csv { head :unprocessable_entity }
format . api { render_validation_errors ( @query ) }
2020-11-08 13:02:26 +00:00
end
2013-02-17 10:15:44 +00:00
end
2006-07-09 16:30:01 +00:00
end
2011-08-31 08:42:38 +00:00
2009-10-29 18:37:00 +00:00
def show
2014-11-11 13:08:52 +00:00
unless @user . visible?
render_404
return
end
2010-08-10 23:07:44 +00:00
# show projects based on current user visibility
2017-01-07 11:40:09 +00:00
@memberships = @user . memberships . preload ( :roles , :project ) . where ( Project . visible_condition ( User . current ) ) . to_a
2011-08-31 08:42:38 +00:00
2019-02-01 23:46:05 +00:00
@issue_counts = { }
@issue_counts [ :assigned ] = {
:total = > Issue . visible . assigned_to ( @user ) . count ,
:open = > Issue . visible . open . assigned_to ( @user ) . count
}
@issue_counts [ :reported ] = {
:total = > Issue . visible . where ( :author_id = > @user . id ) . count ,
:open = > Issue . visible . open . where ( :author_id = > @user . id ) . count
}
2010-12-03 09:39:56 +00:00
respond_to do | format |
2020-11-08 13:02:26 +00:00
format . html do
2014-11-11 13:28:41 +00:00
events = Redmine :: Activity :: Fetcher . new ( User . current , :author = > @user ) . events ( nil , nil , :limit = > 10 )
2017-01-04 21:21:15 +00:00
@events_by_day = events . group_by { | event | User . current . time_to_date ( event . event_datetime ) }
2014-11-11 13:28:41 +00:00
render :layout = > 'base'
2020-11-08 13:02:26 +00:00
end
2010-12-04 17:43:39 +00:00
format . api
2010-12-03 09:39:56 +00:00
end
2009-10-29 18:37:00 +00:00
end
2006-06-28 18:11:03 +00:00
2010-09-29 16:00:45 +00:00
def new
2020-12-09 14:12:31 +00:00
@user = User . new ( :language = > Setting . default_language ,
:mail_notification = > Setting . default_notification_option )
2013-02-23 16:50:07 +00:00
@user . safe_attributes = params [ :user ]
2012-12-02 19:09:42 +00:00
@auth_sources = AuthSource . all
2010-09-28 15:28:50 +00:00
end
2011-08-31 08:42:38 +00:00
2010-09-28 15:28:50 +00:00
def create
2020-12-09 14:12:31 +00:00
@user = User . new ( :language = > Setting . default_language ,
:mail_notification = > Setting . default_notification_option ,
:admin = > false )
2010-12-12 13:19:07 +00:00
@user . safe_attributes = params [ :user ]
2020-12-09 14:12:31 +00:00
unless @user . auth_source_id
@user . password = params [ :user ] [ :password ]
@user . password_confirmation = params [ :user ] [ :password_confirmation ]
end
2016-07-17 06:43:12 +00:00
@user . pref . safe_attributes = params [ :pref ]
2010-09-28 22:13:06 +00:00
2010-09-28 15:28:50 +00:00
if @user . save
2018-10-10 17:13:09 +00:00
Mailer . deliver_account_information ( @user , @user . password ) if params [ :send_information ]
2011-08-31 08:42:38 +00:00
2010-12-03 09:39:56 +00:00
respond_to do | format |
2020-11-08 13:02:26 +00:00
format . html do
2020-12-09 14:12:31 +00:00
flash [ :notice ] =
l ( :notice_user_successful_create ,
:id = > view_context . link_to ( @user . login , user_path ( @user ) ) )
2012-12-11 19:39:47 +00:00
if params [ :continue ]
2020-11-16 12:22:02 +00:00
attrs = { :generate_password = > @user . generate_password }
2013-02-23 16:50:07 +00:00
redirect_to new_user_path ( :user = > attrs )
2012-12-11 19:39:47 +00:00
else
redirect_to edit_user_path ( @user )
end
2020-11-08 13:02:26 +00:00
end
2020-11-16 12:22:02 +00:00
format . api { render :action = > 'show' , :status = > :created , :location = > user_url ( @user ) }
2010-12-03 09:39:56 +00:00
end
2006-07-09 16:30:01 +00:00
else
2012-12-02 19:09:42 +00:00
@auth_sources = AuthSource . all
2010-12-12 13:39:55 +00:00
# Clear password input
@user . password = @user . password_confirmation = nil
2010-09-28 22:13:06 +00:00
2010-12-03 09:39:56 +00:00
respond_to do | format |
2020-11-16 12:22:02 +00:00
format . html { render :action = > 'new' }
format . api { render_validation_errors ( @user ) }
2010-12-03 09:39:56 +00:00
end
2007-03-12 17:59:02 +00:00
end
2006-07-09 16:30:01 +00:00
end
2006-06-28 18:11:03 +00:00
2006-07-09 16:30:01 +00:00
def edit
2012-12-02 19:09:42 +00:00
@auth_sources = AuthSource . all
2007-03-12 17:59:02 +00:00
@membership || = Member . new
2010-09-30 18:22:46 +00:00
end
2011-08-31 08:42:38 +00:00
2010-09-30 18:22:46 +00:00
def update
2021-05-24 06:28:23 +00:00
is_updating_password = params [ :user ] [ :password ] . present? && ( @user . auth_source_id . nil? || params [ :user ] [ :auth_source_id ] . blank? )
if is_updating_password
2010-12-12 13:39:55 +00:00
@user . password , @user . password_confirmation = params [ :user ] [ :password ] , params [ :user ] [ :password_confirmation ]
2010-09-30 18:22:46 +00:00
end
2010-12-12 13:19:07 +00:00
@user . safe_attributes = params [ :user ]
2010-09-30 18:22:46 +00:00
# Was the account actived ? (do it before User#save clears the change)
was_activated = ( @user . status_change == [ User :: STATUS_REGISTERED , User :: STATUS_ACTIVE ] )
# TODO: Similar to My#account
2016-07-21 17:56:26 +00:00
@user . pref . safe_attributes = params [ :pref ]
2010-09-30 18:22:46 +00:00
if @user . save
@user . pref . save
2021-05-24 06:28:23 +00:00
Mailer . deliver_password_updated ( @user , User . current ) if is_updating_password
2010-09-30 18:22:46 +00:00
if was_activated
2018-10-10 17:13:09 +00:00
Mailer . deliver_account_activated ( @user )
2017-04-03 10:48:59 +00:00
elsif @user . active? && params [ :send_information ] && @user != User . current
2018-10-10 17:13:09 +00:00
Mailer . deliver_account_information ( @user , @user . password )
2010-09-30 18:22:46 +00:00
end
2011-08-31 08:42:38 +00:00
2010-12-03 09:39:56 +00:00
respond_to do | format |
2020-11-08 13:02:26 +00:00
format . html do
2010-12-03 09:39:56 +00:00
flash [ :notice ] = l ( :notice_successful_update )
2012-04-06 16:51:10 +00:00
redirect_to_referer_or edit_user_path ( @user )
2020-11-08 13:02:26 +00:00
end
2020-11-16 12:22:02 +00:00
format . api { render_api_ok }
2010-12-03 09:39:56 +00:00
end
2010-09-30 18:22:46 +00:00
else
2012-12-02 19:09:42 +00:00
@auth_sources = AuthSource . all
2010-09-30 18:22:46 +00:00
@membership || = Member . new
2010-12-12 13:39:55 +00:00
# Clear password input
@user . password = @user . password_confirmation = nil
2010-09-30 18:22:46 +00:00
2010-12-03 09:39:56 +00:00
respond_to do | format |
2020-11-16 12:22:02 +00:00
format . html { render :action = > :edit }
format . api { render_validation_errors ( @user ) }
2010-12-03 09:39:56 +00:00
end
2010-09-30 18:22:46 +00:00
end
2007-03-12 17:59:02 +00:00
end
2010-09-30 18:22:46 +00:00
2011-01-16 15:23:11 +00:00
def destroy
2021-03-13 07:20:57 +00:00
return render_error status : 422 if @user == User . current && ! @user . own_account_deletable?
2020-12-10 00:57:38 +00:00
if api_request? || params [ :lock ] || params [ :confirm ] == @user . login
if params [ :lock ]
@user . update_attribute :status , User :: STATUS_LOCKED
2022-09-20 03:37:26 +00:00
flash [ :notice ] = l ( :notice_successful_update )
2020-12-10 00:57:38 +00:00
else
@user . destroy
2022-09-20 03:37:26 +00:00
flash [ :notice ] = l ( :notice_successful_delete )
2020-12-10 00:57:38 +00:00
end
respond_to do | format |
format . html { redirect_back_or_default ( users_path ) }
format . api { render_api_ok }
end
2011-01-16 15:23:11 +00:00
end
end
2022-09-20 03:36:40 +00:00
def bulk_destroy
@users = User . logged . where ( id : params [ :ids ] ) . where . not ( id : User . current )
( render_404 ; return ) unless @users . any?
if params [ :lock ]
@users . update_all status : User :: STATUS_LOCKED
flash [ :notice ] = l ( :notice_successful_update )
redirect_to users_path
elsif params [ :confirm ] == I18n . t ( :general_text_Yes )
@users . destroy_all
flash [ :notice ] = l ( :notice_successful_delete )
redirect_to users_path
end
end
2010-12-20 17:45:09 +00:00
private
2011-08-31 08:42:38 +00:00
2017-04-03 12:59:55 +00:00
def find_user ( logged = true )
2010-12-20 17:45:09 +00:00
if params [ :id ] == 'current'
require_login || return
@user = User . current
2017-04-03 12:59:55 +00:00
elsif logged
@user = User . logged . find ( params [ :id ] )
2010-12-20 17:45:09 +00:00
else
@user = User . find ( params [ :id ] )
end
rescue ActiveRecord :: RecordNotFound
render_404
end
2006-06-28 18:11:03 +00:00
end