diff --git a/.gitignore b/.gitignore index b08eac57a..9fcfc5cca 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,4 @@ doc/dependencies* !.env.example !.env.travis docker-compose.override.yml +.ruby-version \ No newline at end of file diff --git a/app/controllers/dois_controller.rb b/app/controllers/dois_controller.rb index a076bb1ae..a98a4107f 100644 --- a/app/controllers/dois_controller.rb +++ b/app/controllers/dois_controller.rb @@ -74,6 +74,9 @@ def index }.compact options[:include] = @include options[:is_collection] = true + options[:params] = { + :current_ability => current_ability, + } render json: DoiSerializer.new(@dois, options).serialized_json, status: :ok else @@ -168,6 +171,9 @@ def index }.compact options[:include] = @include options[:is_collection] = true + options[:params] = { + :current_ability => current_ability, + } render json: DoiSerializer.new(@dois, options).serialized_json, status: :ok end @@ -179,6 +185,9 @@ def show options = {} options[:include] = @include options[:is_collection] = false + options[:params] = { + :current_ability => current_ability, + } render json: DoiSerializer.new(@doi, options).serialized_json, status: :ok end @@ -199,6 +208,9 @@ def validate options = {} options[:include] = @include options[:is_collection] = false + options[:params] = { + :current_ability => current_ability, + } render json: DoiSerializer.new(@doi, options).serialized_json, status: :ok end @@ -220,6 +232,9 @@ def create options = {} options[:include] = @include options[:is_collection] = false + options[:params] = { + :current_ability => current_ability, + } render json: DoiSerializer.new(@doi, options).serialized_json, status: :created, location: @doi else @@ -261,6 +276,9 @@ def update options = {} options[:include] = @include options[:is_collection] = false + options[:params] = { + :current_ability => current_ability, + } render json: DoiSerializer.new(@doi, options).serialized_json, status: exists ? :ok : :created else diff --git a/app/models/ability.rb b/app/models/ability.rb index 0607f995a..fbbccc6a8 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -16,8 +16,10 @@ def initialize(user) cannot [:new, :create], Doi do |doi| doi.client.blank? || !doi.client.prefixes.where(prefix: doi.prefix).first end + can [:read_landing_page_results], Doi elsif user.role_id == "staff_user" can :read, :all + can [:read_landing_page_results], Doi elsif user.role_id == "provider_admin" && user.provider_id.present? can [:update, :read], Provider, :symbol => user.provider_id.upcase can [:manage], ProviderPrefix, :provider_id => user.provider_id @@ -30,22 +32,24 @@ def initialize(user) # can [:read, :update], Doi, :provider_id => user.provider_id # end can [:read, :transfer], Doi, :provider_id => user.provider_id - can [:read], Doi do |doi| + can [:read], Doi do |doi| doi.findable? end can [:read], User can [:read], Phrase + can [:read_landing_page_results], Doi, :provider_id => user.provider_id elsif user.role_id == "provider_user" && user.provider_id.present? can [:read], Provider, :symbol => user.provider_id.upcase can [:read], ProviderPrefix, :provider_id => user.provider_id can [:read], Client, :provider_id => user.provider_id can [:read], ClientPrefix#, :client_id => user.client_id can [:read], Doi, :provider_id => user.provider_id - can [:read], Doi do |doi| + can [:read], Doi do |doi| doi.findable? end can [:read], User can [:read], Phrase + can [:read_landing_page_results], Doi, :provider_id => user.provider_id elsif user.role_id == "client_admin" && user.client_id.present? can [:read, :update], Client, :symbol => user.client_id.upcase can [:read], ClientPrefix, :client_id => user.client_id @@ -64,6 +68,7 @@ def initialize(user) end can [:read], User can [:read], Phrase + can [:read_landing_page_results], Doi, :client_id => user.client_id elsif user.role_id == "client_user" && user.client_id.present? can [:read], Client, :symbol => user.client_id.upcase can [:read], ClientPrefix, :client_id => user.client_id @@ -73,11 +78,12 @@ def initialize(user) end can [:read], User can [:read], Phrase + can [:read_landing_page_results], Doi, :client_id => user.client_id elsif user.role_id == "user" can [:read, :update], Provider, :symbol => user.provider_id.upcase if user.provider_id.present? can [:read, :update], Client, :symbol => user.client_id.upcase if user.client_id.present? can [:read], Doi, :client_id => user.client_id if user.client_id.present? - can [:read], Doi do |doi| + can [:read], Doi do |doi| doi.findable? end can [:read], User, :id => user.id diff --git a/app/serializers/doi_serializer.rb b/app/serializers/doi_serializer.rb index b08309a41..880473178 100644 --- a/app/serializers/doi_serializer.rb +++ b/app/serializers/doi_serializer.rb @@ -42,10 +42,14 @@ class DoiSerializer object.xml_encoded end - attribute :landing_page do |object| + attribute :landing_page, if: Proc.new { + |object, params| + params[:current_ability] && params[:current_ability].can?(:read_landing_page_results, object) == true + } do |object| { status: object.last_landing_page_status, "content-type" => object.last_landing_page_content_type, checked: object.last_landing_page_status_check, "result" => object.try(:last_landing_page_status_result) } end + end diff --git a/spec/requests/dois_spec.rb b/spec/requests/dois_spec.rb index f6aadc013..1910982e6 100644 --- a/spec/requests/dois_spec.rb +++ b/spec/requests/dois_spec.rb @@ -1883,6 +1883,94 @@ end end + describe 'GET /dois/ linkcheck results' do + let(:last_landing_page_status_result) { { + "error" => nil, + "redirect-count" => 0, + "redirect-urls" => [], + "download-latency" => 200, + "has-schema-org" => true, + "schema-org-id" => "10.14454/10703", + "dc-identifier" => nil, + "citation-doi" => nil, + "body-has-pid" => true + } } + + # Setup an initial DOI with results will check permissions against. + let(:doi) { + create( + :doi, doi: "10.24425/2210181332", + client: client, + state: "findable", + event: 'publish', + last_landing_page_status_result: last_landing_page_status_result + ) + } + + # Create a different dummy client and a doi with entry associated + # This is so we can test clients accessing others information + let(:other_client) { create(:client, provider: provider, symbol: 'DATACITE.DOESNTEXIST', password: 'notarealpassword') } + let(:other_doi) { + create( + :doi, doi: "10.24425/2210181332", + client: other_client, + state: "findable", + event: 'publish', + last_landing_page_status_result: last_landing_page_status_result + ) + } + + context 'anonymous get' do + let(:headers) { { 'ACCEPT'=>'application/vnd.api+json', 'CONTENT_TYPE'=>'application/vnd.api+json' } } + before { get "/dois/#{doi.doi}", headers: headers} + + it 'returns without link_check_results' do + puts json + expect(json.dig('data', 'attributes', 'doi')).to eq(doi.doi) + expect(json.dig('data', 'attributes', 'landing-page', 'result')).to eq(nil) + end + end + + context 'client authorised get own dois' do + let(:bearer) { User.generate_token(role_id: "client_admin", client_id: client.symbol.downcase) } + let(:headers) { { 'ACCEPT'=>'application/vnd.api+json', 'CONTENT_TYPE'=>'application/vnd.api+json', 'Authorization' => 'Bearer ' + bearer } } + + before { get "/dois/#{doi.doi}", headers: headers } + + it 'returns with link_check_results' do + expect(json.dig('data', 'attributes', 'doi')).to eq(doi.doi) + expect(json.dig('data', 'attributes', 'landing-page', 'result')).to eq(last_landing_page_status_result) + end + end + + + context 'client authorised try get diff dois landing data' do + let(:bearer) { User.generate_token(role_id: "client_admin", client_id: client.symbol.downcase) } + let(:headers) { { 'ACCEPT'=>'application/vnd.api+json', 'CONTENT_TYPE'=>'application/vnd.api+json', 'Authorization' => 'Bearer ' + bearer } } + + before { get "/dois/#{other_doi.doi}", headers: headers } + + it 'returns with link_check_results' do + expect(json.dig('data', 'attributes', 'doi')).to eq(other_doi.doi) + expect(json.dig('data', 'attributes', 'landing-page', 'result')).to eq(nil) + end + end + + + context 'authorised staff admin read' do + let(:bearer) { User.generate_token(role_id: "client_admin", client_id: client.symbol.downcase) } + let(:headers) { { 'ACCEPT'=>'application/vnd.api+json', 'CONTENT_TYPE'=>'application/vnd.api+json', 'Authorization' => 'Bearer ' + admin_bearer } } + + before { get "/dois/#{doi.doi}", headers: headers } + + it 'returns with link_check_results' do + expect(json.dig('data', 'attributes', 'doi')).to eq(doi.doi) + expect(json.dig('data', 'attributes', 'landing-page', 'result')).to eq(last_landing_page_status_result) + end + end + + end + describe 'GET /dois/random?prefix' do before { get "/dois/random?prefix=#{prefix.prefix}", headers: headers }