openSUSE/open-build-service

View on GitHub
src/api/app/controllers/source_project_config_controller.rb

Summary

Maintainability
A
0 mins
Test Coverage
A
93%
class SourceProjectConfigController < SourceController
  # GET /source/:project/_config
  before_action :ensure_project_exist, only: %i[show update]

  def show
    config = get_config(@project)

    sliced_params = slice_and_permit(params, [:rev])

    return if forward_from_backend(config.full_path(sliced_params))

    content = config.content(sliced_params)

    unless content
      render_404(config.errors.full_messages.to_sentence)
      return
    end
    send_config(content, config.response[:type])
  end

  # PUT /source/:project/_config
  def update
    # necessary to pass the policy_class here
    # if its remote prj is a string
    authorize @project, :update?, policy_class: ProjectPolicy

    params[:user] = User.session!.login
    @project.config.file = request.body

    response = @project.config.save(slice_and_permit(params, %i[user comment]))

    unless response
      render_404(@project.config.errors.full_messages.to_sentence)
      return
    end

    send_config(response.body, response.fetch('content-type'))
  end

  def slice_and_permit(params, needed_params)
    sliced_params = params.slice(*needed_params)
    sliced_params.permit!
    sliced_params.to_h
  end

  def get_config(project)
    project.is_a?(String) ? ProjectConfigFile.new(project_name: project) : project.config
  end

  def send_config(content, content_type)
    send_data(content, type: content_type, disposition: :inline)
  end

  def render_404(message)
    render_error status: 404, message: message
  end

  def ensure_project_exist
    # 'project' can be a local Project in database or a
    #  String that's the name of a remote project, or even raise exceptions
    @project = Project.get_by_name(params[:project])
  rescue Project::ReadAccessError, Project::UnknownObjectError => e
    render_404(e)
  end
end