Revise the :read_job_artifacts capability in the build_policy to depend solely on the job artifacts accessibility attribute.

This issue is a blocker for Rollout of non_public_aritfacts - #294503 (comment 1608645832)

The feature flag non_public_artifacts is disabled on SaaS for the non-performant reason.

We made the following improvements:

  1. MR - Persist artifacts:public to Ci::JobArtifact table
  2. MR - Fix artifacts:public accessiblity parameter

The main goal of improvements is to persist aritfacts:public in DB and avoid expensive deep calls to options in order to read the expected access level.

Retaining the 'read_job_artifacts' policy on the build/job level still allows for resource-intensive deep calls and blocks non_public_artifacts rollout.

All the references for :read_job_artifacts on build/job level:

We have the following references for the BuildPolicy on :read_job_artifacts ability in our codebase:

  1. on the BuildDetailsEntity serializer
    expose :artifact, if: -> (*) { can?(current_user, :read_job_artifacts, build) } do
       expose :download_path
       ...
       expose :browse_path
       ...
       expose :keep_path
       ...
       expose :expire_at
       ...
       expose :expired
       ...
       expose :locked 
       ...
   end

BuildDetailsEntity serializer used only in one place:

Projects/JobsController#show

represented:

      format.json do
        Gitlab::PollingInterval.set_header(response, interval: 10_000)

        render json: Ci::JobSerializer
          .new(project: @project, current_user: @current_user)
          .represent(@build.present(current_user: current_user), {}, BuildDetailsEntity)
      end
  1. JobArtifacts API:

      get ':id/jobs/artifacts/:ref_name/download',
             urgency: :low,
             requirements: { ref_name: /.+/ } do
           authorize_download_artifacts!
    
           latest_build = user_project.latest_successful_build_for_ref!(params[:job], params[:ref_name])
           authorize_read_job_artifacts!(latest_build)
           ...
      end
      get ':id/jobs/artifacts/:ref_name/raw/*artifact_path',
            urgency: :low,
            format: false,
            requirements: { ref_name: /.+/ } do
          authorize_download_artifacts!
    
          build = user_project.latest_successful_build_for_ref!(params[:job], params[:ref_name])
          authorize_read_job_artifacts!(build)
          ...
        get ':id/jobs/:job_id/artifacts', urgency: :low do
          authorize_download_artifacts!
    
          build = find_build!(params[:job_id])
          authorize_read_job_artifacts!(build)
    
          present_artifacts_file!(build.artifacts_file)
        end
       get ':id/jobs/:job_id/artifacts/*artifact_path', urgency: :low, format: false do
         authorize_download_artifacts!
    
         build = find_build!(params[:job_id])
         authorize_read_job_artifacts!(build)
         ...

For every API request where we still have authorize_read_job_artifacts

   def authorize_read_job_artifacts!(build)
      authorize! :read_job_artifacts, build
    end