# frozen_string_literal: true # API Controller for resources of type User with role 'member' class API::MembersController < API::ApiController before_action :authenticate_user!, except: [:last_subscribed] before_action :set_member, only: %i[update destroy merge complete_tour update_role validate] respond_to :json def index @requested_attributes = params[:requested_attributes] @query = policy_scope(User) @query = @query.page(params[:page].to_i).per(params[:size].to_i) unless params[:page].nil? && params[:size].nil? # remove unmerged profiles from list @members = @query.to_a @members.delete_if(&:need_completion?) end def last_subscribed @query = User.active.with_role(:member) .includes(:statistic_profile, profile: [:user_avatar]) .where('is_allow_contact = true AND confirmed_at IS NOT NULL') .order('created_at desc') .limit(params[:last]) # remove unmerged profiles from list @members = @query.to_a @members.delete_if(&:need_completion?) @requested_attributes = ['profile'] render :index end def show @member = User.friendly.find(params[:id]) authorize @member end def create authorize :user, :create_member? @member = User.new(user_params.permit!) members_service = Members::MembersService.new(@member) if members_service.create(current_user, user_params) render :show, status: :created, location: member_path(@member) else render json: @member.errors, status: :unprocessable_entity end end def update authorize @member members_service = Members::MembersService.new(@member) if members_service.update(user_params) # Update password without logging out bypass_sign_in(@member) unless current_user.id != params[:id].to_i render :show, status: :ok, location: member_path(@member) else render json: @member.errors, status: :unprocessable_entity end end def destroy authorize @member @member.destroy sign_out(@member) if @member.id == current_user.id head :no_content end # export subscriptions def export_subscriptions authorize :export export = Export.where(category: 'users', export_type: 'subscriptions') .where('created_at > ?', Subscription.maximum('updated_at')) .last if export.nil? || !FileTest.exist?(export.file) @export = Export.new(category: 'users', export_type: 'subscriptions', user: current_user) if @export.save render json: { export_id: @export.id }, status: :ok else render json: @export.errors, status: :unprocessable_entity end else send_file File.join(Rails.root, export.file), type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', disposition: 'attachment' end end # export reservations def export_reservations authorize :export export = Export.where(category: 'users', export_type: 'reservations') .where('created_at > ?', Reservation.maximum('updated_at')) .last if export.nil? || !FileTest.exist?(export.file) @export = Export.new(category: 'users', export_type: 'reservations', user: current_user) if @export.save render json: { export_id: @export.id }, status: :ok else render json: @export.errors, status: :unprocessable_entity end else send_file File.join(Rails.root, export.file), type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', disposition: 'attachment' end end def export_members authorize :export last_update = [ User.members.maximum('updated_at'), Profile.where(user_id: User.members).maximum('updated_at'), InvoicingProfile.where(user_id: User.members).maximum('updated_at'), StatisticProfile.where(user_id: User.members).maximum('updated_at'), Subscription.maximum('updated_at') || DateTime.current ].max export = Export.where(category: 'users', export_type: 'members') .where('created_at > ?', last_update) .last if export.nil? || !FileTest.exist?(export.file) @export = Export.new(category: 'users', export_type: 'members', user: current_user) if @export.save render json: { export_id: @export.id }, status: :ok else render json: @export.errors, status: :unprocessable_entity end else send_file File.join(Rails.root, export.file), type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', disposition: 'attachment' end end # the user is querying to be mapped to his already existing account def merge authorize @member token = token_param @account = User.find_by(auth_token: token) if @account members_service = Members::MembersService.new(@account) begin if members_service.merge_from_sso(@member) @member = @account # finally, log on the real account sign_in(@member, bypass: true) render :show, status: :ok, location: member_path(@member) else render json: @member.errors, status: :unprocessable_entity end rescue DuplicateIndexError => error render json: { error: t('members.please_input_the_authentication_code_sent_to_the_address', EMAIL: error.message) }, status: :unprocessable_entity end else render json: { error: t('members.your_authentication_code_is_not_valid') }, status: :unprocessable_entity end end def list authorize User render json: { error: 'page must be an integer' }, status: :unprocessable_entity and return unless query_params[:page].is_a? Integer render json: { error: 'size must be an integer' }, status: :unprocessable_entity and return unless query_params[:size].is_a? Integer query = Members::ListService.list(query_params) @max_members = query.except(:offset, :limit, :order).count @members = query.to_a end def search @members = Members::ListService.search(current_user, params[:query], params[:subscription], params[:include_admins]) end def mapping authorize User @members = User.includes(:profile) end def complete_tour authorize @member if Setting.get('feature_tour_display') == 'session' render json: { tours: [params[:tour]] } else tours = "#{@member.profile.tours} #{params[:tour]}" @member.profile.update_attributes(tours: tours.strip) render json: { tours: @member.profile.tours.split } end end def update_role authorize @member # we do not allow dismissing a user to a lower role if params[:role] == 'member' render 403 and return if @member.role == 'admin' || @member.role == 'manager' elsif params[:role] == 'manager' render 403 and return if @member.role == 'admin' end # do nothing if the role does not change render json: @member and return if params[:role] == @member.role ex_role = @member.role.to_sym @member.remove_role ex_role @member.add_role params[:role] # if the new role is 'admin', then change the group to the admins group @member.update_attributes(group_id: Group.find_by(slug: 'admins').id) if params[:role] == 'admin' NotificationCenter.call type: 'notify_user_role_update', receiver: @member, attached_object: @member NotificationCenter.call type: 'notify_admins_role_update', receiver: User.admins_and_managers, attached_object: @member, meta_data: { ex_role: ex_role } render json: @member end def current @member = current_user authorize @member render json: @member end def validate authorize @member members_service = Members::MembersService.new(@member) uparams = params.require(:user).permit(:validated_at) if members_service.validate(uparams[:validated_at].present?) render :show, status: :ok, location: member_path(@member) else render json: @member.errors, status: :unprocessable_entity end end private def set_member @member = User.find(params[:id]) end def user_params if current_user.id == params[:id].to_i params.require(:user).permit(:username, :email, :password, :password_confirmation, :group_id, :is_allow_contact, :is_allow_newsletter, profile_attributes: [:id, :first_name, :last_name, :phone, :interest, :software_mastered, :website, :job, :facebook, :twitter, :google_plus, :viadeo, :linkedin, :instagram, :youtube, :vimeo, :dailymotion, :github, :echosciences, :pinterest, :lastfm, :flickr, user_avatar_attributes: %i[id attachment destroy]], invoicing_profile_attributes: [ :id, :organization, address_attributes: %i[id address], organization_attributes: [:id, :name, address_attributes: %i[id address]], user_profile_custom_fields_attributes: %i[id value invoicing_profile_id profile_custom_field_id] ], statistic_profile_attributes: %i[id gender birthday]) elsif current_user.admin? || current_user.manager? params.require(:user).permit(:username, :email, :password, :password_confirmation, :is_allow_contact, :is_allow_newsletter, :group_id, tag_ids: [], profile_attributes: [:id, :first_name, :last_name, :phone, :interest, :software_mastered, :website, :job, :facebook, :twitter, :google_plus, :viadeo, :linkedin, :instagram, :youtube, :vimeo, :dailymotion, :github, :echosciences, :pinterest, :lastfm, :flickr, user_avatar_attributes: %i[id attachment destroy]], invoicing_profile_attributes: [ :id, :organization, address_attributes: %i[id address], organization_attributes: [:id, :name, address_attributes: %i[id address]], user_profile_custom_fields_attributes: %i[id value invoicing_profile_id profile_custom_field_id] ], statistic_profile_attributes: [:id, :gender, :birthday, training_ids: []]) end end def token_param params.require(:user).permit(:auth_token)[:auth_token] end def query_params params.require(:query).permit(:search, :filter, :order_by, :page, :size) end end