class Users::SettingsController < ApplicationController include UsersGenerator before_action :load_user, only: [ :preferences, :update_preferences, :organizations, :organization, :create_organization, :organization_users_datatable, :tutorial, :reset_tutorial ] before_action :check_organization_permission, only: [ :organization, :update_organization, :destroy_organization, :organization_name, :organization_description, :search_organization_users, :organization_users_datatable, :create_user_and_user_organization ] before_action :check_create_user_organization_permission, only: [ :create_user_organization ] before_action :check_user_organization_permission, only: [ :update_user_organization, :leave_user_organization_html, :destroy_user_organization_html, :destroy_user_organization ] def preferences end def update_preferences respond_to do |format| if @user.update(update_preferences_params) flash[:notice] = t("users.settings.preferences.update_flash") format.json { flash.keep render json: { status: :ok } } else format.json { render json: @user.errors, status: :unprocessable_entity } end end end def organizations @user_orgs = @user .user_organizations .includes(organization: :users) .order(created_at: :asc) @member_of = @user_orgs.count end def organization @user_org = UserOrganization.find_by(user: @user, organization: @org) end def update_organization respond_to do |format| if @org.update(update_organization_params) @org.update(last_modified_by: current_user) format.json { render json: { status: :ok, description_label: render_to_string( partial: "users/settings/organizations/description_label.html.erb", locals: { org: @org } ) } } else format.json { render json: @org.errors, status: :unprocessable_entity } end end end def organization_name respond_to do |format| format.json { render json: { html: render_to_string({ partial: "users/settings/organizations/name_modal_body.html.erb", locals: { org: @org } }) } } end end def organization_description respond_to do |format| format.json { render json: { html: render_to_string({ partial: "users/settings/organizations/description_modal_body.html.erb", locals: { org: @org } }) } } end end def search_organization_users respond_to do |format| format.json { if params.include? :existing_query and (query = params[:existing_query].strip()).present? if query.length < 3 render json: { "existing_query": [ I18n.t("users.settings.organizations.edit.modal_add_user.existing_query_too_short") ]}, status: :unprocessable_entity else # Okay, query exists and is non-blank, find users nr_of_results = User.search(true, query, @org).count users = User.search(false, query, @org).limit(5) nr_of_members = User.organization_search(false, query, @org).count render json: { html: render_to_string({ partial: "users/settings/organizations/existing_users_search_results.html.erb", locals: { users: users, nr_of_results: nr_of_results, nr_of_members: nr_of_members, org: @org, query: query } }) } end else render json: { "existing_query": [ I18n.t("users.settings.organizations.edit.modal_add_user.existing_query_blank") ]}, status: :unprocessable_entity end } end end def organization_users_datatable respond_to do |format| format.json { render json: ::OrganizationUsersDatatable.new(view_context, @org, @user) } end end def new_organization @new_org = Organization.new end def create_organization @new_org = Organization.new(create_organization_params) @new_org.created_by = @user if @new_org.save # Okay, organization is created, now # add the current user as admin UserOrganization.create( user: @user, organization: @new_org, role: 2 ) # Redirect to new organization page redirect_to action: :organization, organization_id: @new_org.id else render :new_organization end end def destroy_organization @org.destroy flash[:notice] = I18n.t( "users.settings.organizations.edit.modal_destroy_organization.flash_success", org: @org.name ) # Redirect back to all organizations page redirect_to action: :organizations end def create_user_organization @new_user_org = UserOrganization.new(create_user_organization_params) # Check if such association doesn't exist already if !UserOrganization.where( user: @new_user_org.user, organization: @new_user_org.organization ).exists? && @new_user_org.save AppMailer.delay.invitation_to_organization(@new_user_org.user, @user_organization.user, @new_user_org.organization) flash[:notice] = I18n.t( "users.settings.organizations.edit.modal_add_user.existing_flash_success", user: @new_user_org.user.full_name, role: @new_user_org.role_str ) else flash[:alert] = I18n.t("users.settings.organizations.edit.modal_add_user.existing_flash_error") end # Either way, redirect back to organization page redirect_to action: :organization, organization_id: @new_user_org.organization_id end def create_user_and_user_organization respond_to do |format| # User & organization # parameters are already taken care of, # so only role needs to be verified if !params.include? :role or !UserOrganization.roles.keys.include? params[:role] format.json { render json: "Invalid role provided", status: :unprocessable_entity } else password = generate_user_password user_params = create_user_params full_name = user_params[:full_name] email = user_params[:email] # Validate the user data errors = validate_user(full_name, email, password) if errors.count == 0 @user = User.invite!( full_name: full_name, email: email, initials: full_name.split(" ").map{|w| w[0].upcase}.join[0..3], skip_invitation: true ) # Sending email invitation is done in background job to prevent # issues with email delivery. Also invite method must be call # with :skip_invitation attribute set to true - see above. @user.delay.deliver_invitation # Also generate user organization relation @user_org = UserOrganization.new( user: @user, organization: @org, role: params[:role] ) @user_org.save # Flash message flash[:notice] = t( "users.settings.organizations.edit.modal_add_user.new_flash_success", user: @user.full_name, role: @user_org.role_str, email: @user.email ) flash.keep # Return success! format.json { render json: { status: :ok } } else format.json { render json: errors, status: :unprocessable_entity } end end end end def update_user_organization respond_to do |format| if @user_org.update(update_user_organization_params) format.json { render json: { status: :ok } } else format.json { render json: @user_org.errors, status: :unprocessable_entity } end end end def leave_user_organization_html respond_to do |format| format.json { render json: { html: render_to_string({ partial: "users/settings/organizations/leave_user_organization_modal_body.html.erb", locals: { user_organization: @user_org } }), heading: I18n.t( "users.settings.organizations.index.leave_uo_heading", org: @user_org.organization.name ) } } end end def destroy_user_organization_html respond_to do |format| format.json { render json: { html: render_to_string({ partial: "users/settings/organizations/destroy_user_organization_modal_body.html.erb", locals: { user_organization: @user_org } }), heading: I18n.t( "users.settings.organizations.edit.destroy_uo_heading", user: @user_org.user.full_name, org: @user_org.organization.name ) } } end end def destroy_user_organization respond_to do |format| # If user is last administrator of organization, # he/she cannot be deleted from it. invalid = @user_org.admin? && @user_org .organization .user_organizations .where(role: 2) .count <= 1 if !invalid then begin UserOrganization.transaction do # If user leaves on his/her own accord, # new owner for projects is the first # administrator of organization if params[:leave] new_owner = @user_org .organization .user_organizations .where(role: 2) .where.not(id: @user_org.id) .first .user else # Otherwise, the new owner for projects is # the current user (= an administrator removing # the user from the organization) new_owner = current_user end @user_org.destroy(new_owner) end rescue Exception invalid = true end end if !invalid if params[:leave] then flash[:notice] = I18n.t( "users.settings.organizations.index.leave_flash", org: @user_org.organization.name ) flash.keep(:notice) end format.json { render json: { status: :ok } } else format.json { render json: @user_org.errors, status: :unprocessable_entity } end end end def tutorial @orgs = @user .user_organizations .includes(organization: :users) .where(role: 1..2) .order(created_at: :asc) .map { |uo| uo.organization } @member_of = @orgs.count respond_to do |format| format.json { render json: { status: :ok, html: render_to_string({ partial: "users/settings/repeat_tutorial_modal_body.html.erb" }) } } end end def reset_tutorial if @user.update(tutorial_status: 0) && params[:org][:id] cookies.delete :tutorial_data cookies.delete :current_tutorial_step cookies[:repeat_tutorial_org_id] = { value: params[:org][:id], expires: 1.day.from_now } flash[:notice] = t("users.settings.preferences.tutorial.tutorial_reset_flash") redirect_to root_path else flash[:alert] = t("users.settings.preferences.tutorial.tutorial_reset_error") redirect_to :back end end private def load_user @user = current_user end def check_organization_permission @org = Organization.find_by_id(params[:organization_id]) unless is_admin_of_organization(@org) render_403 end end def check_create_user_organization_permission @org = Organization.find_by_id(params[:user_organization][:organization_id]) unless is_admin_of_organization(@org) render_403 end end def check_user_organization_permission @user_org = UserOrganization.find_by_id(params[:user_organization_id]) @org = @user_org.organization # Don't allow the user to modify UserOrganization-s if he's not admin, # unless he/she is modifying his/her UserOrganization if current_user != @user_org.user and !is_admin_of_organization(@user_org.organization) render_403 end end def update_preferences_params params.require(:user).permit( :time_zone ) end def create_organization_params params.require(:organization).permit( :name, :description ) end def update_organization_params params.require(:organization).permit( :name, :description ) end def create_user_params params.require(:user).permit( :full_name, :email ) end def create_user_organization_params params.require(:user_organization).permit( :user_id, :organization_id, :role ) end def update_user_organization_params params.require(:user_organization).permit( :role ) end end