<commit_before>class Api::CanvasAccountUsersController < Api::ApiApplicationController
  include Concerns::CanvasSupport

  before_action :validate_token
  before_action :validate_current_user_lti_admin
  before_action :fetch_original_user, only: [:update]
  before_action :validate_user_is_in_account, only: [:update]

  # This action only lists users who are members of the Canvas account given in the LTI launch.
  # Users from sub-accounts of that account are also included.
  def index
    canvas_response = search_for_users_on_canvas(params[:search_term], params[:page])

    render(
      json: {
        matching_users: canvas_response.parsed_response,
        previous_page_available: previous_page_available?(canvas_response),
        next_page_available: next_page_available?(canvas_response),
      },
      status: :ok,
    )
  end

  # This action can only update users who are members of the Canvas account given in the LTI launch.
  # Users from sub-accounts of that account can also be updated.
  def update
    begin
      edit_user_response = edit_user_on_canvas
    rescue LMS::Canvas::CanvasException => e
      log_user_change(failed_attrs: [:name, :email, :login_id, :password, :sis_user_id])
      render_update_user_exception(:edit_user, e)
      return
    end

    begin
      # This ID is the ID of the login record; it's different from the user's login ID.
      numeric_login_id = find_canvas_user_login["id"]

      edit_user_login_response = edit_user_login_on_canvas(numeric_login_id)
    rescue LMS::Canvas::CanvasException => e
      log_user_change(failed_attrs: [:login_id, :password, :sis_user_id])
      render_update_user_exception(:edit_user_login, e)
      return
    end

    log_user_change

    render(
      json: {
        id: params[:id],
        name: edit_user_response["name"],
        login_id: edit_user_login_response["unique_id"],
        sis_user_id: edit_user_login_response["sis_user_id"],
        email: edit_user_response["email"],
      },
      status: :ok,
    )
  end

  private

  def validate_current_user_lti_admin
    unless current_user.lti_admin?(jwt_context_id)
      user_not_authorized "Only account admins are authorized to use this application."
    end
  end

  def fetch_original_user<commit_msg>refactor: Ensure logging user changes always happens<commit_after>class Api::CanvasAccountUsersController < Api::ApiApplicationController
  include Concerns::CanvasSupport

  before_action :validate_token
  before_action :validate_current_user_lti_admin
  before_action :fetch_original_user, only: [:update]
  before_action :validate_user_is_in_account, only: [:update]

  # This action only lists users who are members of the Canvas account given in the LTI launch.
  # Users from sub-accounts of that account are also included.
  def index
    canvas_response = search_for_users_on_canvas(params[:search_term], params[:page])

    render(
      json: {
        matching_users: canvas_response.parsed_response,
        previous_page_available: previous_page_available?(canvas_response),
        next_page_available: next_page_available?(canvas_response),
      },
      status: :ok,
    )
  end

  # This action can only update users who are members of the Canvas account given in the LTI launch.
  # Users from sub-accounts of that account can also be updated.
  def update
    pending_attrs = [:name, :email, :login_id, :password, :sis_user_id]

    begin
      edit_user_response = edit_user_on_canvas
      pending_attrs = [:login_id, :password, :sis_user_id] # We updated name and email.
    rescue LMS::Canvas::CanvasException => e
      render_update_user_exception(:edit_user, e)
      return
    end

    begin
      # This ID is the ID of the login record; it's different from the user's login ID.
      numeric_login_id = find_canvas_user_login["id"]
      edit_user_login_response = edit_user_login_on_canvas(numeric_login_id)
      pending_attrs = [] # We updated login_id, password and sis_user_id.
    rescue LMS::Canvas::CanvasException => e
      render_update_user_exception(:edit_user_login, e)
      return
    end

    render(
      json: {
        id: params[:id],
        name: edit_user_response["name"],
        login_id: edit_user_login_response["unique_id"],
        sis_user_id: edit_user_login_response["sis_user_id"],
        email: edit_user_response["email"],
      },
      status: :ok,
    )
  ensure
    log_user_change(failed_attrs: pending_attrs)
  end

  private

  def validate_current_user_lti_admin
    unless current_user.lti_admin?(jwt_context_id)
      user_not_authorized "Only account admins are authorized to use this application."
    end
  end

  def fetch_original_user
{'fraction_non_alphanumeric': 0.07372682718943106, 'fraction_numerical': 0.0, 'mean_word_length': 3.8592132505175982, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1457614', 'n_tokens_mistral': 1422, 'n_tokens_neox': 1406, 'n_words': 363}