From 0a02621bd4791f2c01e2d357eb2d02267fafb91b Mon Sep 17 00:00:00 2001 From: Bryceson Laing Date: Fri, 25 Jul 2025 18:54:37 -0500 Subject: [PATCH 01/10] Reapply "add ORCID client id for testing" This reverts commit 9faddd2a7b1e8d7bd2ae86e7da68a8b3b68b74de. --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ff9d8eda..de3232aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -85,6 +85,8 @@ jobs: MEMCACHE_SERVERS: localhost:${{ job.services.memcached.ports[11211] }} REDIS_URL: redis://localhost:${{ job.services.redis.ports[6379] }} ORCID_CLIENT_ID: ${{ secrets.ORCID_CLIENT_ID_FOR_TESTING }} + ORCID_AUTO_UPDATE_CLIENT_ID: ${{ secrets.ORCID_CLIENT_ID_FOR_TESTING }} + ORCID_SEARCH_AND_LINK_CLIENT_ID: ${{ secrets.ORCID_CLIENT_ID_FOR_TESTING }} ORCID_TOKEN: ${{ secrets.ORCID_TOKEN_FOR_TESTING }} run: | bundle exec rubocop From 66942a09e8e00bda47c547a4530d3087b12b10cd Mon Sep 17 00:00:00 2001 From: Bryceson Laing Date: Fri, 25 Jul 2025 18:57:52 -0500 Subject: [PATCH 02/10] Reapply "fix failing tests" This reverts commit 2bc782232b8cc3371c88ec79aa0840ed2c2e376b. --- app/models/user.rb | 3 ++- spec/factories/default.rb | 4 ++++ spec/models/claim_spec.rb | 40 ++++++++++++++++++++++++++++++++++----- spec/models/user_spec.rb | 2 +- 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 5130c9e6..176dc938 100755 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -363,7 +363,8 @@ def get_data(options = {}) Array.wrap(works).select do |work| work.extend Hashie::Extensions::DeepFetch - work.deep_fetch("work-summary", 0, "source", "source-client-id", "path") { nil } == ENV["ORCID_CLIENT_ID"] + source_client_id = work.deep_fetch("work-summary", 0, "source", "source-client-id", "path") { nil } + source_client_id == ENV["ORCID_AUTO_UPDATE_CLIENT_ID"] || source_client_id == ENV["ORCID_SEARCH_AND_LINK_CLIENT_ID"] end end diff --git a/spec/factories/default.rb b/spec/factories/default.rb index fa66a491..dd704c0c 100644 --- a/spec/factories/default.rb +++ b/spec/factories/default.rb @@ -25,11 +25,15 @@ factory :valid_user do uid { "0000-0001-6528-2027" } orcid_token { ENV["ORCID_TOKEN"] } + orcid_auto_update_access_token { "TEST_AUTO_UPDATE_TOKEN" } + orcid_search_and_link_access_token { "TEST_SEARCH_AND_LINK_TOKEN" } end factory :invalid_user do uid { "0000-0001-6528-2027" } orcid_token { nil } + orcid_auto_update_access_token { nil } + orcid_search_and_link_access_token { nil } end initialize_with { User.where(uid: uid).first_or_initialize } diff --git a/spec/models/claim_spec.rb b/spec/models/claim_spec.rb index c4bac540..592d6274 100644 --- a/spec/models/claim_spec.rb +++ b/spec/models/claim_spec.rb @@ -111,11 +111,41 @@ # expect(subject.state).to eq("failed") # end - it "no permission for auto-update" do - user = FactoryBot.create(:valid_user, auto_update: false) - subject = FactoryBot.create(:claim, user: user, orcid: "0000-0001-6528-2027", doi: "10.14454/j6gr-cf48", source_id: "orcid_update") - expect(subject.process_data).to be true - expect(subject.state).to eq("failed") # This used to be 'ignored' but the code is correctly returning an error struct and thus setting it to failed + ## This test is no longer necessary as the auto_update flag has been replaced by presence of auto_update token + # it "no permission for auto-update" do + # user = FactoryBot.create(:valid_user, auto_update: false) + # subject = FactoryBot.create(:claim, user: user, orcid: "0000-0001-6528-2027", doi: "10.14454/v6e2-yc93", source_id: "orcid_update") + # response = subject.collect_data + # expect(response.body).to eq({ "errors" => [{ "title" => "No auto-update permission" }] }) + # end + + it "missing token" do + user = FactoryBot.create(:invalid_user) + subject = FactoryBot.create(:claim, user: user, orcid: "0000-0003-1419-240x", doi: "10.14454/v6e2-yc93", source_id: source) + response = subject.collect_data + expect(response.body).to eq({ "errors" => [{ "title" => "No user and/or ORCID token" }] }) + end + + it "expired token" do + user = FactoryBot.create(:valid_user, orcid_auto_update_expires_at: Time.zone.now - 7.days, orcid_search_and_link_expires_at: Time.zone.now - 7.days) + subject = FactoryBot.create(:claim, user: user, orcid: "0000-0001-6528-2027", doi: "10.14454/1X4X-9056", source_id: source) + response = subject.collect_data + expect(response.body).to eq("errors" => [{ "status" => 401, "title" => "token has expired." }]) + end + + # TODO + # it "invalid token" do + # user = FactoryBot.create(:invalid_user, orcid_token: "123") + # subject = FactoryBot.create(:claim, user: user, orcid: "0000-0003-1419-240x", doi: "10.14454/v6e2-yc93", source_id: "orcid_update") + # response = subject.collect_data + # expect(response.body).to eq("errors"=>[{"title"=>"Missing data"}]) + # end + + it "no user" do + subject = FactoryBot.create(:claim, orcid: "0000-0001-6528-2027", doi: "10.14454/v6e2-yc93") + response = subject.collect_data + expect(response.body).to eq("errors" => [{ "title" => "No user and/or ORCID token" }]) + end end it "invalid token" do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index ce46af59..ce230422 100755 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -74,7 +74,7 @@ expect(result.length).to eq(23) work = result.first path = work.fetch("work-summary", [{}]).first.fetch("source", {}).fetch("source-client-id", {}).fetch("path", nil) - expect(path).to eq(ENV["ORCID_CLIENT_ID"]) + expect(path).to eq(ENV["ORCID_AUTO_UPDATE_CLIENT_ID"]) end it "parse data" do From edb99d9befe4837f7b6593def18ee0bcdc762551 Mon Sep 17 00:00:00 2001 From: Bryceson Laing Date: Fri, 25 Jul 2025 18:58:26 -0500 Subject: [PATCH 03/10] Reapply "fix incorrect capitalization" This reverts commit 0fd9393981825ba8f7388cd835d64347dd0f5583. --- app/controllers/users/orcid_controller.rb | 207 ++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 app/controllers/users/orcid_controller.rb diff --git a/app/controllers/users/orcid_controller.rb b/app/controllers/users/orcid_controller.rb new file mode 100644 index 00000000..0e9dc926 --- /dev/null +++ b/app/controllers/users/orcid_controller.rb @@ -0,0 +1,207 @@ +# frozen_string_literal: true + +require "faraday" +require "json" + +module Users + class OrcidController < ApplicationController + BASE_URL = "#{ENV["ORCID_URL"]}/oauth" + SCOPES_AUTO_UPDATE = ["/activities/update", "/person/update", "/read-limited"].freeze + SCOPES_SEARCH_AND_LINK = ["/activities/update", "/person/update", "/read-limited"].freeze + + before_action :load_user + + # Auto-update methods + def auto_update_auth + auth_url = build_auth_url(ENV["ORCID_AUTO_UPDATE_CLIENT_ID"], + ENV["ORCID_AUTO_UPDATE_REDIRECT_URI"], + SCOPES_AUTO_UPDATE.join(" ")) + + redirect_to auth_url + end + + + def auto_update_callback + tokens = callback(ENV["ORCID_AUTO_UPDATE_CLIENT_ID"], + ENV["ORCID_AUTO_UPDATE_CLIENT_SECRET"], + params[:code]) + + @user.update(orcid_auto_update_access_token: tokens[:access_token], + orcid_auto_update_refresh_token: tokens[:refresh_token], + orcid_auto_update_expires_at: tokens[:expires_at]) + + redirect_to stored_location_for(:user) || setting_path("me") + end + + + def auto_update_refresh + tokens = refresh(ENV["ORCID_AUTO_UPDATE_CLIENT_ID"], + ENV["ORCID_AUTO_UPDATE_CLIENT_SECRET"], + @user.orcid_auto_update_refresh_token) + + @user.update(orcid_auto_update_access_token: tokens[:access_token], + orcid_auto_update_refresh_token: tokens[:refresh_token], + orcid_auto_update_expires_at: tokens[:expires_at]) + + redirect_to stored_location_for(:user) || setting_path("me") + end + + + def auto_update_revoke + revoke(ENV["ORCID_AUTO_UPDATE_CLIENT_ID"], + ENV["ORCID_AUTO_UPDATE_CLIENT_SECRET"], + @user.orcid_auto_update_access_token) + + @user.update(orcid_auto_update_access_token: nil, + orcid_auto_update_refresh_token: nil, + orcid_auto_update_expires_at: nil) + + redirect_to stored_location_for(:user) || setting_path("me") + end + + + # Search and Link methods + def search_and_link_auth + auth_url = build_auth_url(ENV["ORCID_SEARCH_AND_LINK_CLIENT_ID"], + ENV["ORCID_SEARCH_AND_LINK_REDIRECT_URI"] + "?redirect_to_commons=false", + SCOPES_SEARCH_AND_LINK.join(" ")) + + redirect_to auth_url + end + + + def search_and_link_callback + tokens = callback(ENV["ORCID_SEARCH_AND_LINK_CLIENT_ID"], + ENV["ORCID_SEARCH_AND_LINK_CLIENT_SECRET"], + params[:code]) + + @user.update(orcid_search_and_link_access_token: tokens[:access_token], + orcid_search_and_link_refresh_token: tokens[:refresh_token], + orcid_search_and_link_expires_at: tokens[:expires_at]) + + # Redirect to Commons if the flag isn't explicitly false. Otherwise redirect to profile settings + if params["redirect_to_commons"] != "false" + redirect_to "#{ENV['COMMONS_URL']}/orcid.org/#{current_user.orcid}" + else + redirect_to stored_location_for(:user) || setting_path("me") + end + end + + + def search_and_link_refresh + tokens = refresh(ENV["ORCID_SEARCH_AND_LINK_CLIENT_ID"], + ENV["ORCID_SEARCH_AND_LINK_CLIENT_SECRET"], + @user.orcid_search_and_link_refresh_token) + + @user.update(orcid_search_and_link_access_token: tokens[:access_token], + orcid_search_and_link_refresh_token: tokens[:refresh_token], + orcid_search_and_link_expires_at: tokens[:expires_at]) + + redirect_to stored_location_for(:user) || setting_path("me") + end + + + def search_and_link_revoke + revoke(ENV["ORCID_SEARCH_AND_LINK_CLIENT_ID"], + ENV["ORCID_SEARCH_AND_LINK_CLIENT_SECRET"], + @user.orcid_search_and_link_access_token) + + @user.update(orcid_search_and_link_access_token: nil, + orcid_search_and_link_refresh_token: nil, + orcid_search_and_link_expires_at: nil) + + redirect_to stored_location_for(:user) || setting_path("me") + end + + + def load_user + if user_signed_in? + @user = current_user + else + fail CanCan::AccessDenied.new("Please sign in first.", :read, User) + end + end + + private + def build_auth_url(client_id, redirect_uri, scope) + response_type = "code" + "#{BASE_URL}/authorize?client_id=#{client_id}&response_type=#{response_type}&scope=#{scope}&redirect_uri=#{redirect_uri}" + end + + + def callback(client_id, client_secret, code) + conn = Faraday.new(BASE_URL + "/token") + + body = { + client_id: client_id, + client_secret: client_secret, + grant_type: "authorization_code", + code: code, + } + + response = conn.post do |req| + req.headers["Accept"] = "application/json" + req.body = body + end + + unless response.success? + raise "Error exchanging code for tokens: #{response.status} - #{response.body}" + end + + parse_tokens(response.body) + end + + + def refresh(client_id, client_secret, refresh_token) + conn = Faraday.new(BASE_URL + "/token") + + body = { + client_id: client_id, + client_secret: client_secret, + refresh_token: refresh_token, + grant_type: "refresh_token", + } + + response = conn.post do |req| + req.body = body + end + + unless response.success? + raise "Error refreshing tokens: #{response.status} - #{response.body}" + end + + parse_tokens(response.body) + end + + + def revoke(client_id, client_secret, access_token) + conn = Faraday.new(BASE_URL + "/revoke") + + body = { + client_id: client_id, + client_secret: client_secret, + token: access_token, + } + + response = conn.post do |req| + req.body = body + end + + unless response.success? + raise "Error revoking tokens: #{response.status} - #{response.body}" + end + end + + + def parse_tokens(body) + tokens = JSON.parse(body) + expires_at = Time.now.utc + tokens["expires_in"].seconds + + { + access_token: tokens["access_token"], + refresh_token: tokens["refresh_token"], + expires_at: expires_at + } + end + end +end From c3be7da30c8f11dd184e6fa63d65cfc141c9f08c Mon Sep 17 00:00:00 2001 From: Bryceson Laing Date: Fri, 25 Jul 2025 18:59:28 -0500 Subject: [PATCH 04/10] Reapply "use correct expires_at" This reverts commit 87efff467d04d0708beafbd3685529b4ba1553a1. --- app/models/claim.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/models/claim.rb b/app/models/claim.rb index 6f1bcf78..d5e10a45 100644 --- a/app/models/claim.rb +++ b/app/models/claim.rb @@ -280,6 +280,15 @@ def create_uuid write_attribute(:uuid, SecureRandom.uuid) if uuid.blank? end + def orcid_token + source_id == "orcid_search" ? user.orcid_search_and_link_access_token : user.orcid_auto_update_access_token + end + + def orcid_token_expired + expires_at = source_id == "orcid_search" ? user.orcid_search_and_link_expires_at : user.orcid_auto_update_expires_at + (Date.new(1970, 1, 2).beginning_of_day..Date.today.end_of_day) === expires_at + end + def work sandbox = ENV["SANDBOX"].present? || (ENV["ORCID_URL"] == "https://sandbox.orcid.org") # Note that if this is ever intended in future to support claiming for non datacite dois From b099ec837228ecb010a32148dcc068ae9f4ddbfd Mon Sep 17 00:00:00 2001 From: Bryceson Laing Date: Fri, 25 Jul 2025 19:05:26 -0500 Subject: [PATCH 05/10] Reapply "use new orcid_auto_update_access_token" This reverts commit 5851c8ea3e0a4145d5a9e95d030435dcbe8339f4. --- spec/factories/default.rb | 4 +- spec/models/claim_spec.rb | 177 ++++++++++++++++++-------------------- 2 files changed, 85 insertions(+), 96 deletions(-) diff --git a/spec/factories/default.rb b/spec/factories/default.rb index dd704c0c..6f6f9760 100644 --- a/spec/factories/default.rb +++ b/spec/factories/default.rb @@ -24,14 +24,12 @@ factory :valid_user do uid { "0000-0001-6528-2027" } - orcid_token { ENV["ORCID_TOKEN"] } - orcid_auto_update_access_token { "TEST_AUTO_UPDATE_TOKEN" } + orcid_auto_update_access_token { ENV["ORCID_TOKEN"] } orcid_search_and_link_access_token { "TEST_SEARCH_AND_LINK_TOKEN" } end factory :invalid_user do uid { "0000-0001-6528-2027" } - orcid_token { nil } orcid_auto_update_access_token { nil } orcid_search_and_link_access_token { nil } end diff --git a/spec/models/claim_spec.rb b/spec/models/claim_spec.rb index 592d6274..e2803ecc 100644 --- a/spec/models/claim_spec.rb +++ b/spec/models/claim_spec.rb @@ -19,97 +19,50 @@ # end # end - describe "collect_data", order: :defined do + describe "claim uses correct token" do let(:user) { FactoryBot.create(:valid_user) } - let(:put_code) { 1069293 } - - subject { FactoryBot.create(:claim, user: user, orcid: "0000-0001-6528-2027", doi: "10.14454/1X4X-9056") } - - # it 'no errors' do - # response = subject.collect_data - # expect(response.body["errors"]).to eq([{"title"=>"Missing data"}]) - # expect(response.body["put_code"]).to be_nil - # expect(response.status).to eq(201) - # end - - # TODO - # it "already exists" do - # FactoryBot.create(:claim, user: user, orcid: "0000-0001-6528-2027", doi: "10.14454/1X4X-9056", claim_action: "create", put_code: put_code) - # expect(subject.collect_data.body).to eq("reason" => "already claimed.", "skip" => true) - # end - - # it 'delete claim' do - # user = FactoryBot.create(:valid_user) - # subject = FactoryBot.create(:claim, user: user, orcid: "0000-0001-6528-2027", doi: "10.14454/1X4X-9056", claim_action: "delete", claimed_at: Time.zone.now, put_code: put_code) - # response = subject.collect_data - # expect(response.body["data"]).to be_blank - # expect(response.body["errors"]).to eq([{"title"=>"Missing data"}]) - # end - - it "no permission for auto-update" do + + it "uses the auto update token" do user = FactoryBot.create(:valid_user, auto_update: false) - subject = FactoryBot.create(:claim, user: user, orcid: "0000-0001-6528-2027", doi: "10.14454/v6e2-yc93", source_id: "orcid_update") - response = subject.collect_data - expect(response.body).to eq({ "errors" => [{ "title" => "No auto-update permission" }] }) + subject = FactoryBot.create(:claim, user: user, source_id: "orcid_update") + expect(subject.orcid_token).to eq(user.orcid_auto_update_access_token) end - it "missing token" do - user = FactoryBot.create(:invalid_user) - subject = FactoryBot.create(:claim, user: user, orcid: "0000-0003-1419-240x", doi: "10.14454/v6e2-yc93", source_id: "orcid_update") - response = subject.collect_data - expect(response.body).to eq({ "errors" => [{ "title" => "No user and/or ORCID token" }] }) + it "uses the search and link token" do + user = FactoryBot.create(:valid_user, auto_update: false) + subject = FactoryBot.create(:claim, user: user, source_id: "orcid_search") + expect(subject.orcid_token).to eq(user.orcid_search_and_link_access_token) end + end - it "expired token" do - user = FactoryBot.create(:valid_user, orcid_expires_at: Time.zone.now - 7.days) - subject = FactoryBot.create(:claim, user: user, orcid: "0000-0001-6528-2027", doi: "10.14454/1X4X-9056", source_id: "orcid_update") - response = subject.collect_data - expect(response.body).to eq("errors" => [{ "status" => 401, "title" => "token has expired." }]) - end + sources = [ "orcid_search", "orcid_update" ] + sources.each do |source| + describe "collect_data with source #{source}", order: :defined do + let(:user) { FactoryBot.create(:valid_user) } + let(:put_code) { 1069293 } - # TODO - # it "invalid token" do - # user = FactoryBot.create(:invalid_user, orcid_token: "123") - # subject = FactoryBot.create(:claim, user: user, orcid: "0000-0003-1419-240x", doi: "10.14454/v6e2-yc93", source_id: "orcid_update") - # response = subject.collect_data - # expect(response.body).to eq("errors"=>[{"title"=>"Missing data"}]) - # end - - it "no user" do - subject = FactoryBot.create(:claim, orcid: "0000-0001-6528-2027", doi: "10.14454/v6e2-yc93") - response = subject.collect_data - expect(response.body).to eq("errors" => [{ "title" => "No user and/or ORCID token" }]) - end - end + subject { FactoryBot.create(:claim, user: user, orcid: "0000-0001-6528-2027", doi: "10.14454/1X4X-9056") } - describe "process_data", order: :defined do - let(:user) { FactoryBot.create(:valid_user) } - let(:put_code) { 1069294 } - - subject { FactoryBot.create(:claim, user: user, orcid: "0000-0001-6528-2027", doi: "10.14454/j6gr-cf48") } - - # it 'no errors' do - # expect(subject.process_data).to be true - # expect(subject.put_code).to be_blank - # expect(subject.claimed_at).to be_blank - # expect(subject.state).to eq("failed") - # end - - # TODO - # it "already exists" do - # FactoryBot.create(:claim, user: user, orcid: "0000-0001-6528-2027", doi: "10.14454/j6gr-cf48", claim_action: "create", put_code: put_code) - # expect(subject.process_data).to be true - # expect(subject.state).to eq("done") - # end - - # it 'delete claim' do - # user = FactoryBot.create(:valid_user) - # subject = FactoryBot.create(:claim, user: user, orcid: "0000-0001-6528-2027", doi: "10.14454/j6gr-cf48", claim_action: "delete", put_code: put_code) - # expect(subject.process_data).to be true - # expect(subject.put_code).to eq(1069294) - # expect(subject.claimed_at).to be_blank - # expect(subject.state).to eq("failed") - # end + # it 'no errors' do + # response = subject.collect_data + # expect(response.body["errors"]).to eq([{"title"=>"Missing data"}]) + # expect(response.body["put_code"]).to be_nil + # expect(response.status).to eq(201) + # end + + # TODO + # it "already exists" do + # FactoryBot.create(:claim, user: user, orcid: "0000-0001-6528-2027", doi: "10.14454/1X4X-9056", claim_action: "create", put_code: put_code) + # expect(subject.collect_data.body).to eq("reason" => "already claimed.", "skip" => true) + # end + + # it 'delete claim' do + # user = FactoryBot.create(:valid_user) + # subject = FactoryBot.create(:claim, user: user, orcid: "0000-0001-6528-2027", doi: "10.14454/1X4X-9056", claim_action: "delete", claimed_at: Time.zone.now, put_code: put_code) + # response = subject.collect_data + # expect(response.body["data"]).to be_blank + # expect(response.body["errors"]).to eq([{"title"=>"Missing data"}]) + # end ## This test is no longer necessary as the auto_update flag has been replaced by presence of auto_update token # it "no permission for auto-update" do @@ -148,17 +101,55 @@ end end - it "invalid token" do - user = FactoryBot.create(:invalid_user) - subject = FactoryBot.create(:claim, user: user, orcid: "0000-0001-6528-2027", doi: "10.14454/j6gr-cf48", source_id: "orcid_update") - expect(subject.process_data).to be true - expect(subject.state).to eq("failed") # This used to be 'ignored' but the code is correctly returning an error struct and thus setting it to failed - end + describe "process_data with source #{source}", order: :defined do + let(:user) { FactoryBot.create(:valid_user) } + let(:put_code) { 1069294 } + + subject { FactoryBot.create(:claim, user: user, orcid: "0000-0001-6528-2027", doi: "10.14454/j6gr-cf48") } - it "no user" do - subject = FactoryBot.build(:claim, user: nil, orcid: "0000-0001-6528-2027", doi: "10.14454/j6gr-cf48") - expect(subject.valid?).to be false - expect(subject.errors[:user]).to include("must exist") + # it 'no errors' do + # expect(subject.process_data).to be true + # expect(subject.put_code).to be_blank + # expect(subject.claimed_at).to be_blank + # expect(subject.state).to eq("failed") + # end + + # TODO + # it "already exists" do + # FactoryBot.create(:claim, user: user, orcid: "0000-0001-6528-2027", doi: "10.14454/j6gr-cf48", claim_action: "create", put_code: put_code) + # expect(subject.process_data).to be true + # expect(subject.state).to eq("done") + # end + + # it 'delete claim' do + # user = FactoryBot.create(:valid_user) + # subject = FactoryBot.create(:claim, user: user, orcid: "0000-0001-6528-2027", doi: "10.14454/j6gr-cf48", claim_action: "delete", put_code: put_code) + # expect(subject.process_data).to be true + # expect(subject.put_code).to eq(1069294) + # expect(subject.claimed_at).to be_blank + # expect(subject.state).to eq("failed") + # end + + ## This test is no longer necessary as the auto_update flag has been replaced by presence of auto_update token + # it "no permission for auto-update" do + # user = FactoryBot.create(:valid_user, auto_update: false) + # subject = FactoryBot.create(:claim, user: user, orcid: "0000-0001-6528-2027", doi: "10.14454/j6gr-cf48", source_id: source) + # expect(subject.process_data).to be true + # expect(subject.state).to eq("failed") # This used to be 'ignored' but the code is correctly returning an error struct and thus setting it to failed + # end + + it "invalid token" do + user = FactoryBot.create(:invalid_user) + subject = FactoryBot.create(:claim, user: user, orcid: "0000-0001-6528-2027", doi: "10.14454/j6gr-cf48", source_id: source) + expect(subject.process_data).to be true + expect(subject.state).to eq("failed") # This used to be 'ignored' but the code is correctly returning an error struct and thus setting it to failed + end + + it "no user" do + subject = FactoryBot.build(:claim, user: nil, orcid: "0000-0001-6528-2027", doi: "10.14454/j6gr-cf48") + expect(subject.valid?).to be false + expect(subject.errors[:user]).to include("must exist") + end end end end From 16d8ff10a53540ade67b0b34683627a8f9e9f13a Mon Sep 17 00:00:00 2001 From: Bryceson Laing Date: Fri, 25 Jul 2025 19:06:40 -0500 Subject: [PATCH 06/10] Reapply "index new auto-update tokens" This reverts commit edc59d77908a9cfcd865843537552fdcd97126ff. --- app/models/user.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/models/user.rb b/app/models/user.rb index 176dc938..04d27814 100755 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -75,6 +75,12 @@ class User < ApplicationRecord indexes :role_id, type: :keyword indexes :role_name, type: :keyword indexes :orcid_token, type: :keyword + indexes :orcid_auto_update_access_token, type: :keyword + indexes :orcid_auto_update_refresh_token, type: :keyword + indexes :orcid_auto_update_expires_at, type: :date + indexes :orcid_search_and_link_access_token, type: :keyword + indexes :orcid_search_and_link_refresh_token, type: :keyword + indexes :orcid_search_and_link_expires_at, type: :date indexes :created, type: :date indexes :updated, type: :date indexes :orcid_expires_at, type: :date @@ -106,6 +112,12 @@ def as_indexed_json(_options = {}) "is_active" => is_active, "orcid_token" => orcid_token, "orcid_expires_at" => orcid_expires_at, + "orcid_auto_update_access_token" => orcid_auto_update_access_token, + "orcid_auto_update_refresh_token" => orcid_auto_update_refresh_token, + "orcid_auto_update_expires_at" => orcid_auto_update_expires_at, + "orcid_search_and_link_access_token" => orcid_search_and_link_access_token, + "orcid_search_and_link_refresh_token" => orcid_search_and_link_refresh_token, + "orcid_search_and_link_expires_at" => orcid_search_and_link_expires_at, "claims_count" => claims_count, } end From ed46c8b541e0930faa6c180a030997d2cf27da90 Mon Sep 17 00:00:00 2001 From: Bryceson Laing Date: Fri, 25 Jul 2025 19:08:48 -0500 Subject: [PATCH 07/10] Reapply "add auto-update token fetching" This reverts commit c0ab78406fca868cf6700150de4d2e7e2a0d7126. --- app/views/settings/_show.html.erb | 26 ++++++++++++++++++++------ config/routes.rb | 9 +++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/app/views/settings/_show.html.erb b/app/views/settings/_show.html.erb index f005612a..8e4cb79b 100644 --- a/app/views/settings/_show.html.erb +++ b/app/views/settings/_show.html.erb @@ -75,14 +75,28 @@
-
ORCID Permissions
+
Link Works to ORCID
- <% if @user.orcid_expires_at && Time.zone.now < @user.orcid_expires_at %> -

Delete ORCID token to no longer allow DataCite to update your ORCID record.

- <%= link_to "\"ORCID Delete ORCID Token".html_safe, setting_path("me", user: { orcid_token: nil, orcid_expires_at: Time.zone.now }), { method: :put, remote: true, class: 'btn btn-social btn-orcid btn-fill' } %> + <% if @user.orcid_search_and_link_access_token %> +

Revoke access for DataCite to link DataCite DOIs to you ORCID record using the "Add to ORCID Record" button in DataCite Commons

+ <%= link_to "\"ORCID Click to Disable".html_safe, :orcid_search_and_link_revoke, method: :get, :id => "orcid-search-and-link-disable", class: 'btn btn-social btn-orcid btn-fill' %> <% else %> -

Get ORCID token to allow DataCite to update your ORCID record.

- <%= link_to "\"ORCID Get ORCID Token".html_safe, user_orcid_omniauth_authorize_path(redirect_to_commons: false), method: :post, :id => "sign-in-orcid", class: 'btn btn-social btn-orcid btn-fill' %> +

Allow DataCite to link DataCite DOIs to you ORCID record using the "Add to ORCID Record" button in DataCite Commons

+ <%= link_to "\"ORCID Click to Enable".html_safe, :orcid_search_and_link_auth, method: :get, :id => "orcid-search-and-link-enable", class: 'btn btn-social btn-orcid btn-fill' %> + <% end %> +
+
+
+
+
+
ORCID Auto-Update
+
+ <% if @user.orcid_auto_update_access_token %> +

Revoke access DataCite to add Works to your ORCID record automatically when your ORCID is included as a creator in a DataCite DOI metadata

+ <%= link_to "\"ORCID Click to Disable".html_safe, :orcid_auto_update_revoke, method: :get, :id => "orcid-auto-update-disable", class: 'btn btn-social btn-orcid btn-fill' %> + <% else %> +

Allow DataCite to add Works to your ORCID record automatically when your ORCID is included as a creator in a DataCite DOI metadata

+ <%= link_to "\"ORCID Click to Enable".html_safe, :orcid_auto_update_auth, method: :get, :id => "orcid-auto-update-enable", class: 'btn btn-social btn-orcid btn-fill' %> <% end %>
diff --git a/config/routes.rb b/config/routes.rb index 071c5df4..1d567c4c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -14,6 +14,15 @@ get "link_orcid", to: "users/sessions#link_orcid", as: :link_orcid_session get "auth", to: "users/omniauth_callbacks#forward" + + get "orcid/auto_update/auth", to: "users/orcid#auto_update_auth", as: :orcid_auto_update_auth + get "orcid/auto_update/callback", to: "users/orcid#auto_update_callback", as: :orcid_auto_update_callback + get "orcid/auto_update/refresh", to: "users/orcid#auto_update_refresh", as: :orcid_auto_update_refresh + get "orcid/auto_update/revoke", to: "users/orcid#auto_update_revoke", as: :orcid_auto_update_revoke + get "orcid/search_and_link/auth", to: "users/orcid#search_and_link_auth", as: :orcid_search_and_link_auth + get "orcid/search_and_link/callback", to: "users/orcid#search_and_link_callback", as: :orcid_search_and_link_callback + get "orcid/search_and_link/refresh", to: "users/orcid#search_and_link_refresh", as: :orcid_search_and_link_refresh + get "orcid/search_and_link/revoke", to: "users/orcid#search_and_link_revoke", as: :orcid_search_and_link_revoke end # enable feature flags api From d1fd9b22ab27f7754075414c7de3ee918b43025a Mon Sep 17 00:00:00 2001 From: Bryceson Laing Date: Fri, 25 Jul 2025 19:09:02 -0500 Subject: [PATCH 08/10] Reapply "include ORCID auth in the auth hash" This reverts commit 467b2a3a16d6cbbb8ff9f071b27c824d0a0ca1bd. --- .../users/omniauth_callbacks_controller.rb | 16 +--------------- app/models/user.rb | 5 ++++- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb index 91cccfcc..9276fd0c 100644 --- a/app/controllers/users/omniauth_callbacks_controller.rb +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -107,7 +107,6 @@ def globus def orcid auth = request.env["omniauth.auth"] - omni_params = request.env["omniauth.params"] omniauth = flash[:omniauth] || {} if current_user.present? @@ -127,13 +126,6 @@ def orcid if @user.persisted? sign_in @user - # Refresh ORCID token if the flag isn't explicitly false - if omni_params["fetch_token"] != "false" - @user.update(orcid_expires_at: User.timestamp(auth.credentials), - orcid_token: auth.credentials.token) - flash[:notice] = "ORCID token successfully refreshed." - end - cookies[:_datacite] = encode_cookie(@user.jwt) if stored_location_for(:user) == ENV["BLOG_URL"] + "/admin/" @@ -150,13 +142,7 @@ def orcid netlify_response(token: token, content: content) else - - # Redirect to Commons if the flag isn't explicitly false. Otherwise redirect to profile settings - if omni_params["redirect_to_commons"] != "false" - redirect_to "#{ENV['COMMONS_URL']}/orcid.org/#{current_user.orcid}" - else - redirect_to stored_location_for(:user) || setting_path("me") - end + redirect_to stored_location_for(:user) || setting_path("me") end else flash[:alert] = @user.errors.map { |k, v| "#{k}: #{v}" }.join("
").html_safe || "Error signing in with #{provider}" diff --git a/app/models/user.rb b/app/models/user.rb index 04d27814..5bd3ea1d 100755 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -315,7 +315,10 @@ def self.get_auth_hash(auth, options = {}) github: options.fetch("github", nil), github_uid: options.fetch("github_uid", nil), github_token: options.fetch("github_token", nil), - email: auth.extra.id_info? ? auth.extra.id_info.email : nil }.compact + email: auth.extra.id_info? ? auth.extra.id_info.email : nil, + orcid_token: auth.credentials.token, + orcid_expires_at: User.timestamp(auth.credentials) + }.compact end def self.timestamp(credentials) From 3ceb6978b84a92ecc4ca89ee9068abd0fa7df2c1 Mon Sep 17 00:00:00 2001 From: Bryceson Laing Date: Fri, 25 Jul 2025 19:17:00 -0500 Subject: [PATCH 09/10] Reapply "use separate token for ORCID Search and Link claiming" This reverts commit 6ea975c6c6d9529c4cc4d3e5e2e1de75508d45e3. --- app/models/claim.rb | 2 +- spec/factories/default.rb | 4 +- .../expired_token.yml | 299 ++++++++++++++++++ .../expired_token.yml | 70 ++++ .../no_permission_for_auto-update.yml | 296 +++++++++++++++++ .../no_permission_for_auto-update.yml | 296 +++++++++++++++++ 6 files changed, 965 insertions(+), 2 deletions(-) create mode 100644 spec/fixtures/vcr_cassettes/Claim/collect_data_with_source_orcid_search/expired_token.yml create mode 100644 spec/fixtures/vcr_cassettes/Claim/collect_data_with_source_orcid_update/expired_token.yml create mode 100644 spec/fixtures/vcr_cassettes/Claim/process_data/no_permission_for_auto-update.yml create mode 100644 spec/fixtures/vcr_cassettes/Claim/process_data_with_source_orcid_search/no_permission_for_auto-update.yml diff --git a/app/models/claim.rb b/app/models/claim.rb index d5e10a45..a8c3498c 100644 --- a/app/models/claim.rb +++ b/app/models/claim.rb @@ -253,7 +253,7 @@ def collect_data(options = {}) return OpenStruct.new(body: { "errors" => [{ "title" => "Missing data" }] }) if work.data.nil? # orcid_token has expired, but is not default 1970-01-01 - return OpenStruct.new(body: { "errors" => [{ "status" => 401, "title" => "token has expired." }] }) if (Date.new(1970, 1, 2).beginning_of_day..Date.today.end_of_day) === user.orcid_expires_at + return OpenStruct.new(body: { "errors" => [{ "status" => 401, "title" => "token has expired." }] }) if orcid_token_expired # Don't go to orcid if we've got a claimed_at date but marked as still to create with no put_code # return OpenStruct.new(body: { "skip" => true, "reason" => "Already claimed." }) if to_be_created? && !put_code.present? && claimed_at.present? diff --git a/spec/factories/default.rb b/spec/factories/default.rb index 6f6f9760..dd704c0c 100644 --- a/spec/factories/default.rb +++ b/spec/factories/default.rb @@ -24,12 +24,14 @@ factory :valid_user do uid { "0000-0001-6528-2027" } - orcid_auto_update_access_token { ENV["ORCID_TOKEN"] } + orcid_token { ENV["ORCID_TOKEN"] } + orcid_auto_update_access_token { "TEST_AUTO_UPDATE_TOKEN" } orcid_search_and_link_access_token { "TEST_SEARCH_AND_LINK_TOKEN" } end factory :invalid_user do uid { "0000-0001-6528-2027" } + orcid_token { nil } orcid_auto_update_access_token { nil } orcid_search_and_link_access_token { nil } end diff --git a/spec/fixtures/vcr_cassettes/Claim/collect_data_with_source_orcid_search/expired_token.yml b/spec/fixtures/vcr_cassettes/Claim/collect_data_with_source_orcid_search/expired_token.yml new file mode 100644 index 00000000..52327410 --- /dev/null +++ b/spec/fixtures/vcr_cassettes/Claim/collect_data_with_source_orcid_search/expired_token.yml @@ -0,0 +1,299 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.stage.datacite.org/dois/10.14454/1x4x-9056?include=media,client + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; Maremma/5.0.0; mailto:info@datacite.org) + Accept: + - text/html,application/json,application/xml;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Accept-Encoding: + - gzip,deflate + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 05 Jun 2025 23:05:16 GMT + Content-Type: + - application/json; charset=utf-8 + Connection: + - keep-alive + Status: + - 200 OK + X-Anonymous-Consumer: + - 'true' + Cache-Control: + - max-age=0, private, must-revalidate + Vary: + - Accept-Encoding + Content-Encoding: + - gzip + Referrer-Policy: + - strict-origin-when-cross-origin + X-Permitted-Cross-Domain-Policies: + - none + X-Xss-Protection: + - '0' + X-Request-Id: + - 11141a19-afb8-4d76-a113-b494342791ef + Etag: + - W/"07b2805274bbc57630b9f044a27b0a5d" + X-Frame-Options: + - SAMEORIGIN + X-Runtime: + - '0.039572' + X-Content-Type-Options: + - nosniff + X-Powered-By: + - Phusion Passenger(R) 6.0.27 + Server: + - nginx/1.18.0 + Phusion Passenger(R) 6.0.27 + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Methods: + - GET, POST, PUT, PATCH, DELETE, OPTIONS + Access-Control-Allow-Headers: + - Accept,Access-Control-Allow-Origin,Access-Control-Expose-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With + Access-Control-Expose-Headers: + - Authorization + body: + encoding: ASCII-8BIT + string: !binary |- + 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 + recorded_at: Thu, 05 Jun 2025 23:05:15 GMT +- request: + method: get + uri: https://api.stage.datacite.org/dois/10.14454/1x4x-9056?include=media,client + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; Maremma/5.0.0; mailto:info@datacite.org) + Accept: + - text/html,application/json,application/xml;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Accept-Encoding: + - gzip,deflate + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 05 Jun 2025 23:05:16 GMT + Content-Type: + - application/json; charset=utf-8 + Connection: + - keep-alive + Status: + - 200 OK + X-Anonymous-Consumer: + - 'true' + Cache-Control: + - max-age=0, private, must-revalidate + Vary: + - Accept-Encoding + Content-Encoding: + - gzip + Referrer-Policy: + - strict-origin-when-cross-origin + X-Permitted-Cross-Domain-Policies: + - none + X-Xss-Protection: + - '0' + X-Request-Id: + - d5f83607-a04d-4320-8a2e-977efeb6f552 + Etag: + - W/"07b2805274bbc57630b9f044a27b0a5d" + X-Frame-Options: + - SAMEORIGIN + X-Runtime: + - '0.034096' + X-Content-Type-Options: + - nosniff + X-Powered-By: + - Phusion Passenger(R) 6.0.27 + Server: + - nginx/1.18.0 + Phusion Passenger(R) 6.0.27 + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Methods: + - GET, POST, PUT, PATCH, DELETE, OPTIONS + Access-Control-Allow-Headers: + - Accept,Access-Control-Allow-Origin,Access-Control-Expose-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With + Access-Control-Expose-Headers: + - Authorization + body: + encoding: ASCII-8BIT + string: !binary |- + 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 + recorded_at: Thu, 05 Jun 2025 23:05:16 GMT +- request: + method: get + uri: https://api.stage.datacite.org/dois/10.14454/1x4x-9056?include=media,client + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; Maremma/5.0.0; mailto:info@datacite.org) + Accept: + - text/html,application/json,application/xml;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Accept-Encoding: + - gzip,deflate + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 05 Jun 2025 23:05:17 GMT + Content-Type: + - application/json; charset=utf-8 + Connection: + - keep-alive + Status: + - 200 OK + X-Anonymous-Consumer: + - 'true' + Cache-Control: + - max-age=0, private, must-revalidate + Vary: + - Accept-Encoding + Content-Encoding: + - gzip + Referrer-Policy: + - strict-origin-when-cross-origin + X-Permitted-Cross-Domain-Policies: + - none + X-Xss-Protection: + - '0' + X-Request-Id: + - 2fb0f010-b5a7-406b-bf97-b10850a5e17c + Etag: + - W/"f3a84733999c13c0d05261115f78bf38" + X-Frame-Options: + - SAMEORIGIN + X-Runtime: + - '0.028995' + X-Content-Type-Options: + - nosniff + X-Powered-By: + - Phusion Passenger(R) 6.0.27 + Server: + - nginx/1.18.0 + Phusion Passenger(R) 6.0.27 + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Methods: + - GET, POST, PUT, PATCH, DELETE, OPTIONS + Access-Control-Allow-Headers: + - Accept,Access-Control-Allow-Origin,Access-Control-Expose-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With + Access-Control-Expose-Headers: + - Authorization + body: + encoding: ASCII-8BIT + string: !binary |- + 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 + recorded_at: Thu, 05 Jun 2025 23:05:17 GMT +- request: + method: post + uri: https://api.sandbox.orcid.org/v3.0/0000-0001-6528-2027/work + body: + encoding: UTF-8 + string: | + + + + Cool DOI's + + DataCite + In 1998 Tim Berners-Lee coined the term cool URIs (1998), that is URIs that don’t change. We know that URLs referenced in the scholarly literature are often not cool, leading to link rot (Klein et al., 2014) and making it hard or impossible to find... + other + + 2016 + 12 + 15 + + + + doi + 10.14454/1X4X-9056 + self + + + + + + https://orcid.org/0000-0003-1419-2405 + 0000-0003-1419-2405 + orcid.org + + Martin Fenner + + + + headers: + User-Agent: + - Mozilla/5.0 (compatible; Maremma/5.0.0; mailto:info@datacite.org) + Accept: + - text/html,application/json,application/xml;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Content-Type: + - application/vnd.orcid+xml + Authorization: + - Bearer TEST_SEARCH_AND_LINK_TOKEN + Accept-Encoding: + - gzip,deflate + response: + status: + code: 401 + message: Unauthorized + headers: + Date: + - Thu, 05 Jun 2025 23:05:17 GMT + Content-Type: + - application/json;charset=UTF-8 + Connection: + - keep-alive + Server: + - cloudflare + Cf-Ray: + - 94b3505b6b90e843-DFW + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Pragma: + - no-cache + Www-Authenticate: + - 'Bearer realm="ORCID T2 API", error="invalid_token", error_description="Invalid + access token: TEST_SEARCH_AND_LINK_TOKEN"' + Strict-Transport-Security: + - max-age=31536000 ; includeSubDomains + X-Xss-Protection: + - 1; mode=block + X-Frame-Options: + - DENY + X-Content-Type-Options: + - nosniff + Vary: + - accept-encoding + Content-Encoding: + - gzip + X-Target: + - reg-sbox-mapi-use2-a1 + X-Via: + - a1 + Cf-Cache-Status: + - DYNAMIC + body: + encoding: ASCII-8BIT + string: !binary |- + H4sIAAAAAAAAAKrmUlBQSi0qyi9SUrBSUMrMK0vMyUyJL8nPTs1T0oFLxqekFicXZRaUZObngRV6QhQqJCYnpxYXK4DVWymEuAaHxAe7OgY5e8Q7+rnE+3j6eceH+Hu7+ilx1QIAAAD//wMAZy+8J2sAAAA= + recorded_at: Thu, 05 Jun 2025 23:05:17 GMT +recorded_with: VCR 6.2.0 diff --git a/spec/fixtures/vcr_cassettes/Claim/collect_data_with_source_orcid_update/expired_token.yml b/spec/fixtures/vcr_cassettes/Claim/collect_data_with_source_orcid_update/expired_token.yml new file mode 100644 index 00000000..b3a64a09 --- /dev/null +++ b/spec/fixtures/vcr_cassettes/Claim/collect_data_with_source_orcid_update/expired_token.yml @@ -0,0 +1,70 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.stage.datacite.org/dois/10.14454/1x4x-9056?include=media,client + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; Maremma/5.0.0; mailto:info@datacite.org) + Accept: + - text/html,application/json,application/xml;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Accept-Encoding: + - gzip,deflate + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 05 Jun 2025 23:04:36 GMT + Content-Type: + - application/json; charset=utf-8 + Connection: + - keep-alive + Status: + - 200 OK + X-Anonymous-Consumer: + - 'true' + Cache-Control: + - max-age=0, private, must-revalidate + Vary: + - Accept-Encoding + Content-Encoding: + - gzip + Referrer-Policy: + - strict-origin-when-cross-origin + X-Permitted-Cross-Domain-Policies: + - none + X-Xss-Protection: + - '0' + X-Request-Id: + - 7414ab02-6e2b-4add-b88a-872567e31b69 + Etag: + - W/"31eb11e699648ce1bbfcbb8167f2741a" + X-Frame-Options: + - SAMEORIGIN + X-Runtime: + - '0.041709' + X-Content-Type-Options: + - nosniff + X-Powered-By: + - Phusion Passenger(R) 6.0.27 + Server: + - nginx/1.18.0 + Phusion Passenger(R) 6.0.27 + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Methods: + - GET, POST, PUT, PATCH, DELETE, OPTIONS + Access-Control-Allow-Headers: + - Accept,Access-Control-Allow-Origin,Access-Control-Expose-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With + Access-Control-Expose-Headers: + - Authorization + body: + encoding: ASCII-8BIT + string: !binary |- + H4sIAIQiQmgAA7RYWW/iyhL+K0e8XOnOkHjBMzjSfQATwAwQYryAR/PgpWMa2svxgjGj/Pdb7YUlITNzj3Qjodjl2rrqq+qu/tlyrdRqPfxsYbf10GKZO7bTETr37KFzaIuM8KX1uZUWEYJvbogTeLPSNMZ2lqKESgHxI7EoRi/4cPEVaEn2UtMuGLGLghS/YBSDyu8/wARJURxYKZLffnFiZKVh+fazFVg+9WuIggDFn/+aWXGKA9BH6Wrl8wIkw8AiQPXwHgXzSuTE+mL5mBTzS0W1gmvTP1uJs0E+0mK63E2aRsnD/X0YO9i9C2PvncwtpnsG/trw49tshxXbXIcR3gkuSzMg/qRI8qD1SqMBISPYSnEY0CBQUopTgiq/ykfgl8KQ/DV4kv+VlEJRZhOcbEpPBpBhCacIjDlhkFqYrhJyV+d1iWKMkqs8VEkTOny3cTq5ZqjDC/Zar7Uxp/RwjSyQ5hj2C022vUVOWseveqlwBEKXlBdIahYjt/SculgCLGySDgitF0ufgJ+qb7Ncm6Xxo7TaHTlJMqrl8285JYqj2iCxAi+zPCAHGSEV3Etsx4D3h5ayUFQQtrGdIopcCh2HlMGEmEZx6JyJ7W2YxRXcSrxYT4ANiLCzCYkVk6J3ko1RAqxO40+fhN4iTACU3puPIwTZAo0PLRUdUhrtGBHq+1uAlmTIwCkWC3Dq6aV1Q+CD9P7C7A0lVxB4Z15BLyhGgYOSDxxoyiPP87ucL+tjEYd7gFh8v0wLgu41Rf6FXU2Z/iO7tBnxX9n7OlN3URigO4ZlBU7gf7fMH+fvKfJrdCb4iOrHlzD2rbR+2UNiypJtsXcM1Yy9TZpMcZLWqEaJE+OI+l5LeCichlUZNQqzwAVIXCyqJB98mpjFQOzYRu65vl44HNnbWwbPlp1cxn1i+/O9OSKZeWSwriujqerhxbHzbTGeEIcTWcefE3m8Se2RcHwKNkdLZbA1VhhnEO6nvMu7hcDPCmHv+M5+tu3ls6W4VrWDuuY2xDYeU8sQju5omK05DTd6FstJ6I6V/Al3wfaQWRvzyB1pmc1Pgik/31ojPV0vxdhcTTLTyNO5JHtoPI+egvqbdtivuSFjGWL2v+vqn/gdbh6aBruZ+soGfNxaK4VMfbEwCzE1V8pmyqXE8QViSwwz5VgCPLs1pUMcTEn+JOGetxiRnWkI4IsZmSvZswyF2IESmT4hDlEEZ6SJ8k5ZLJfyp5nay2bqMzNXn/cz3WMMiRFmA41bSGJkjvTMHRHfMvRi4YWePDhsHV8Hv8TCgXzIUu+KVvJQmtTrrvkJAb/2zk7Y2Ibm2f4wNfXaNukTJ5jvgZbIW2EEvmbgZyI/shsH/LS3+f6NfLmu2l5grUxi13TVGBbgYwb+XtEv+P21wUb2mDzBf7LYAQ/EzwEbJvhkGQdBpb6p9XokGj+qQ59crl++QdOqXBHI90LbzSew6Xl1/oiuTyYNDpwj4JITizVHdlUu5U8lXsezL9NCBJzOI1Oq8ToAvEpMDv+PU/WRmam7dLZ9zudqvi9jqF3ltllnd8rNC9MYMjZfY0AS3+aqC34z9kg/NnlajBXA5QFiArngck95FCcTftad8jW9zHm+v5IbHHLXmCTWCtYJ9hWKb63EN8j12bV/iByoM2db2XTGOrZHZAu5jGxOMMHHYrGV85m6PvE3dWMY+uYk5+tHm9chZrqGVn2o93Pt62OSm5oLeYTvRg54UggaP+PFbpLYnPts83PQJwQQg8JczffuarKtsVfFZjwHuxFZ88pFLBra8ydzJEYge4R1/m0ac+YmD43tWIeYP8M6zvQ69ifZJva0D5ir2Slf5fuyT2u3Wg/0sOVqDnL6Tt52itngkYP8F/BjQV/Jd/JjRHuD5pU6mpraVfkHf3Ad33SmyvCDvHAl/y9t66vqnfaQp0DBa8BbyVfVRa3jhAGwdaDvu+VlbwnO64P8JaW+x+tedJs+KXMM9fKoMjtMc22PKkxcxOZ5vZowKrfGf4SF7WM+3WrM7Oida2o8P5aYuOX79tTPbn/H/dv0pp8SfalKp/VRrDdrWpqGCT1bh/1GP0K/O/eEN3uVNp7sXR/ispL3Gq8I9kjbl33k/+VztQf8gc+dw0yC39E5TLmI1lMGsc6ckZiZsGfPAKOzrfa72EKdVHk1DeWqj5760+ks0DlMt5TfpPsE+NWp9zUF8j4vrFW/xMbFHgQxm0O/Izno3Nu4f/1+Wu8QO7wCOJkzkIeJjXuHJ3XXkYew9mVfKvfj1eQ41Q4E6mNrc3AGMZ49d7SB/gO2fcZbc+Lelvq6tiNHWfJK+W/LnPJsXKkfOUX9bayE69Uz1KiYdULJhG+w7w8zk9MyeegSeZTCecBp5EDmcKS4hr4CMRS21K5ldGrb9MwgQo4mCVr2E3omcPwhA3kAPcMCfN2bAcQb90Hnc+1j7kHP3pTnqKLP2AXIGUIsU4xJvXDJHQjVb4KPNJdTqUd7DvNt2d/Y/rNnG8OY9lAZer8MPjqUxtOzBJtDfz1asAeAXaoXcijsprhD9+DruG9PveNd3q56s9r5D5wxs5hcHK1tGCru6HhPB5XyhO3AkNimc/x9PQvCKVejMvRU6aPUotx6c3DtfG3GmBOp1A2qr7RWPPc7mNkRaZdjfjlH0MnOsmOYDIdwMKbzY9JzUhjDWw9pnCFgS6sp7QUHrmXXc5GVUEPVKLbHKJfCLIAjM1O9JU9wrlYxHZHLQ3SYByS03DNTQ3nDGDdH6JqTLce38qx9lm0ob2QjGKTOTFE5Vp3V1Of8CzcrwomHqa8tkFsNpF06kPKMyn55ELoPfPcORjCzXLoHwwGKP+ATG75mtK/Z6A1KFrkn/RzMc0Kb66rMlweGeRDYSq4ZHOnyNjgqB1yHYEQ9/Hl9CXRKbvNwvgOqJJLWK53663HtQ/mzWMNaCfrIxdY7qV9dPVUSr68XeUzOCr5faPjFaHd5jfX64/Ui3ReqKJ1m+BYNhulbNt/N0e8M1Yh4q/MElCs6XSUOHJK5NKHf/zwnb6/m6uux5vbnLwVFYYLTsL7tSQrfDmm7GPTUniSrj3fNA3wsmmsc9uI2rromqyrzYnptSOd7lO8tVF6uxS16n1O6V4/REYpx6EJHoFckbuhbmEal9e+rNvX5BXvJxorRnRP6ZWHwVXQqO2GEAjek/lXvOEmCEkXwnzTEKMYU2S1W6Ajtr90uvf9BBDlpHAbYqT502iL7laeVUfbNSvCqVFlagsxXleUfOvxFCV7VG9tm+DYnqoz4AKXKCQ3Tdbe7VX//uIKgdSdhnOLMfyc6kD4Squ5jPygcCuJLwZqV3rA0LF9hXdwf8LC3eCiuf7z+FwAA//8DAIhCs+tuFgAA + recorded_at: Thu, 05 Jun 2025 23:04:36 GMT +recorded_with: VCR 6.2.0 diff --git a/spec/fixtures/vcr_cassettes/Claim/process_data/no_permission_for_auto-update.yml b/spec/fixtures/vcr_cassettes/Claim/process_data/no_permission_for_auto-update.yml new file mode 100644 index 00000000..239e515d --- /dev/null +++ b/spec/fixtures/vcr_cassettes/Claim/process_data/no_permission_for_auto-update.yml @@ -0,0 +1,296 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.stage.datacite.org/dois/10.14454/j6gr-cf48?include=media,client + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; Maremma/5.0.0; mailto:info@datacite.org) + Accept: + - text/html,application/json,application/xml;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Accept-Encoding: + - gzip,deflate + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 05 Jun 2025 23:03:17 GMT + Content-Type: + - application/json; charset=utf-8 + Connection: + - keep-alive + Status: + - 200 OK + X-Anonymous-Consumer: + - 'true' + Cache-Control: + - max-age=0, private, must-revalidate + Vary: + - Accept-Encoding + Content-Encoding: + - gzip + Referrer-Policy: + - strict-origin-when-cross-origin + X-Permitted-Cross-Domain-Policies: + - none + X-Xss-Protection: + - '0' + X-Request-Id: + - 7980f42e-43d0-4f48-98e6-0ff39fa756c4 + Etag: + - W/"48d3bab46a4b7f5d9d08e7e8dec0a24d" + X-Frame-Options: + - SAMEORIGIN + X-Runtime: + - '0.068123' + X-Content-Type-Options: + - nosniff + X-Powered-By: + - Phusion Passenger(R) 6.0.27 + Server: + - nginx/1.18.0 + Phusion Passenger(R) 6.0.27 + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Methods: + - GET, POST, PUT, PATCH, DELETE, OPTIONS + Access-Control-Allow-Headers: + - Accept,Access-Control-Allow-Origin,Access-Control-Expose-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With + Access-Control-Expose-Headers: + - Authorization + body: + encoding: ASCII-8BIT + string: !binary |- + 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 + recorded_at: Thu, 05 Jun 2025 23:03:17 GMT +- request: + method: get + uri: https://api.stage.datacite.org/dois/10.14454/j6gr-cf48?include=media,client + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; Maremma/5.0.0; mailto:info@datacite.org) + Accept: + - text/html,application/json,application/xml;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Accept-Encoding: + - gzip,deflate + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 05 Jun 2025 23:03:18 GMT + Content-Type: + - application/json; charset=utf-8 + Connection: + - keep-alive + Status: + - 200 OK + X-Anonymous-Consumer: + - 'true' + Cache-Control: + - max-age=0, private, must-revalidate + Vary: + - Accept-Encoding + Content-Encoding: + - gzip + Referrer-Policy: + - strict-origin-when-cross-origin + X-Permitted-Cross-Domain-Policies: + - none + X-Xss-Protection: + - '0' + X-Request-Id: + - f92cf51e-1f60-41f5-91a3-b285783bbf7b + Etag: + - W/"b5b6a6e64adf985b22b61732cdd22177" + X-Frame-Options: + - SAMEORIGIN + X-Runtime: + - '0.208397' + X-Content-Type-Options: + - nosniff + X-Powered-By: + - Phusion Passenger(R) 6.0.27 + Server: + - nginx/1.18.0 + Phusion Passenger(R) 6.0.27 + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Methods: + - GET, POST, PUT, PATCH, DELETE, OPTIONS + Access-Control-Allow-Headers: + - Accept,Access-Control-Allow-Origin,Access-Control-Expose-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With + Access-Control-Expose-Headers: + - Authorization + body: + encoding: ASCII-8BIT + string: !binary |- + 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 + recorded_at: Thu, 05 Jun 2025 23:03:18 GMT +- request: + method: get + uri: https://api.stage.datacite.org/dois/10.14454/j6gr-cf48?include=media,client + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; Maremma/5.0.0; mailto:info@datacite.org) + Accept: + - text/html,application/json,application/xml;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Accept-Encoding: + - gzip,deflate + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 05 Jun 2025 23:03:19 GMT + Content-Type: + - application/json; charset=utf-8 + Connection: + - keep-alive + Status: + - 200 OK + X-Anonymous-Consumer: + - 'true' + Cache-Control: + - max-age=0, private, must-revalidate + Vary: + - Accept-Encoding + Content-Encoding: + - gzip + Referrer-Policy: + - strict-origin-when-cross-origin + X-Permitted-Cross-Domain-Policies: + - none + X-Xss-Protection: + - '0' + X-Request-Id: + - cccf58d2-4da1-48bf-a325-898d2de5b5c8 + Etag: + - W/"d486a07904f4a553e84ab17e37160b94" + X-Frame-Options: + - SAMEORIGIN + X-Runtime: + - '0.200637' + X-Content-Type-Options: + - nosniff + X-Powered-By: + - Phusion Passenger(R) 6.0.27 + Server: + - nginx/1.18.0 + Phusion Passenger(R) 6.0.27 + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Methods: + - GET, POST, PUT, PATCH, DELETE, OPTIONS + Access-Control-Allow-Headers: + - Accept,Access-Control-Allow-Origin,Access-Control-Expose-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With + Access-Control-Expose-Headers: + - Authorization + body: + encoding: ASCII-8BIT + string: !binary |- + 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 + recorded_at: Thu, 05 Jun 2025 23:03:19 GMT +- request: + method: post + uri: https://api.sandbox.orcid.org/v3.0/0000-0001-6528-2027/work + body: + encoding: UTF-8 + string: | + + + + Test + + DataCite + other + + 2019 + + + + doi + 10.14454/j6gr-cf48 + self + + + + + + https://orcid.org/0000-0003-1419-2405 + 0000-0003-1419-2405 + orcid.org + + Martin Fenner + + + + headers: + User-Agent: + - Mozilla/5.0 (compatible; Maremma/5.0.0; mailto:info@datacite.org) + Accept: + - text/html,application/json,application/xml;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Content-Type: + - application/vnd.orcid+xml + Authorization: + - Bearer TEST_SEARCH_AND_LINK_TOKEN + Accept-Encoding: + - gzip,deflate + response: + status: + code: 401 + message: Unauthorized + headers: + Date: + - Thu, 05 Jun 2025 23:03:19 GMT + Content-Type: + - application/json;charset=UTF-8 + Connection: + - keep-alive + Server: + - cloudflare + Cf-Ray: + - 94b34d7b9f476b45-DFW + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Pragma: + - no-cache + Www-Authenticate: + - 'Bearer realm="ORCID T2 API", error="invalid_token", error_description="Invalid + access token: TEST_SEARCH_AND_LINK_TOKEN"' + Strict-Transport-Security: + - max-age=31536000 ; includeSubDomains + X-Xss-Protection: + - 1; mode=block + X-Frame-Options: + - DENY + X-Content-Type-Options: + - nosniff + Vary: + - accept-encoding + Content-Encoding: + - gzip + X-Target: + - reg-sbox-mapi-use2-a1 + X-Via: + - a1 + Cf-Cache-Status: + - DYNAMIC + body: + encoding: ASCII-8BIT + string: !binary |- + H4sIAAAAAAAAAKrmUlBQSi0qyi9SUrBSUMrMK0vMyUyJL8nPTs1T0oFLxqekFicXZRaUZObngRV6QhQqJCYnpxYXK4DVWymEuAaHxAe7OgY5e8Q7+rnE+3j6eceH+Hu7+ilx1QIAAAD//wMAZy+8J2sAAAA= + recorded_at: Thu, 05 Jun 2025 23:03:19 GMT +recorded_with: VCR 6.2.0 diff --git a/spec/fixtures/vcr_cassettes/Claim/process_data_with_source_orcid_search/no_permission_for_auto-update.yml b/spec/fixtures/vcr_cassettes/Claim/process_data_with_source_orcid_search/no_permission_for_auto-update.yml new file mode 100644 index 00000000..c37f7832 --- /dev/null +++ b/spec/fixtures/vcr_cassettes/Claim/process_data_with_source_orcid_search/no_permission_for_auto-update.yml @@ -0,0 +1,296 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.stage.datacite.org/dois/10.14454/j6gr-cf48?include=media,client + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; Maremma/5.0.0; mailto:info@datacite.org) + Accept: + - text/html,application/json,application/xml;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Accept-Encoding: + - gzip,deflate + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 05 Jun 2025 23:04:58 GMT + Content-Type: + - application/json; charset=utf-8 + Connection: + - keep-alive + Status: + - 200 OK + X-Anonymous-Consumer: + - 'true' + Cache-Control: + - max-age=0, private, must-revalidate + Vary: + - Accept-Encoding + Content-Encoding: + - gzip + Referrer-Policy: + - strict-origin-when-cross-origin + X-Permitted-Cross-Domain-Policies: + - none + X-Xss-Protection: + - '0' + X-Request-Id: + - 1e260712-3817-4594-9dcb-ee48426ddd61 + Etag: + - W/"2c7a93fdc326fb6c2cf4db54e9223257" + X-Frame-Options: + - SAMEORIGIN + X-Runtime: + - '0.039189' + X-Content-Type-Options: + - nosniff + X-Powered-By: + - Phusion Passenger(R) 6.0.27 + Server: + - nginx/1.18.0 + Phusion Passenger(R) 6.0.27 + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Methods: + - GET, POST, PUT, PATCH, DELETE, OPTIONS + Access-Control-Allow-Headers: + - Accept,Access-Control-Allow-Origin,Access-Control-Expose-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With + Access-Control-Expose-Headers: + - Authorization + body: + encoding: ASCII-8BIT + string: !binary |- + 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 + recorded_at: Thu, 05 Jun 2025 23:04:58 GMT +- request: + method: get + uri: https://api.stage.datacite.org/dois/10.14454/j6gr-cf48?include=media,client + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; Maremma/5.0.0; mailto:info@datacite.org) + Accept: + - text/html,application/json,application/xml;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Accept-Encoding: + - gzip,deflate + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 05 Jun 2025 23:04:59 GMT + Content-Type: + - application/json; charset=utf-8 + Connection: + - keep-alive + Status: + - 200 OK + X-Anonymous-Consumer: + - 'true' + Cache-Control: + - max-age=0, private, must-revalidate + Vary: + - Accept-Encoding + Content-Encoding: + - gzip + Referrer-Policy: + - strict-origin-when-cross-origin + X-Permitted-Cross-Domain-Policies: + - none + X-Xss-Protection: + - '0' + X-Request-Id: + - ddb993ab-cc00-44be-be7c-71e1f631d6a7 + Etag: + - W/"f9545ad0dc3c9d873e530ac9fe01acdc" + X-Frame-Options: + - SAMEORIGIN + X-Runtime: + - '0.120017' + X-Content-Type-Options: + - nosniff + X-Powered-By: + - Phusion Passenger(R) 6.0.27 + Server: + - nginx/1.18.0 + Phusion Passenger(R) 6.0.27 + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Methods: + - GET, POST, PUT, PATCH, DELETE, OPTIONS + Access-Control-Allow-Headers: + - Accept,Access-Control-Allow-Origin,Access-Control-Expose-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With + Access-Control-Expose-Headers: + - Authorization + body: + encoding: ASCII-8BIT + string: !binary |- + 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 + recorded_at: Thu, 05 Jun 2025 23:04:59 GMT +- request: + method: get + uri: https://api.stage.datacite.org/dois/10.14454/j6gr-cf48?include=media,client + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; Maremma/5.0.0; mailto:info@datacite.org) + Accept: + - text/html,application/json,application/xml;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Accept-Encoding: + - gzip,deflate + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 05 Jun 2025 23:05:00 GMT + Content-Type: + - application/json; charset=utf-8 + Connection: + - keep-alive + Status: + - 200 OK + X-Anonymous-Consumer: + - 'true' + Cache-Control: + - max-age=0, private, must-revalidate + Vary: + - Accept-Encoding + Content-Encoding: + - gzip + Referrer-Policy: + - strict-origin-when-cross-origin + X-Permitted-Cross-Domain-Policies: + - none + X-Xss-Protection: + - '0' + X-Request-Id: + - ebbb7b6a-ac8c-43b0-8fd2-a155280b3f50 + Etag: + - W/"c02777a7b5317e11c134118f0dd208d0" + X-Frame-Options: + - SAMEORIGIN + X-Runtime: + - '0.060334' + X-Content-Type-Options: + - nosniff + X-Powered-By: + - Phusion Passenger(R) 6.0.27 + Server: + - nginx/1.18.0 + Phusion Passenger(R) 6.0.27 + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Methods: + - GET, POST, PUT, PATCH, DELETE, OPTIONS + Access-Control-Allow-Headers: + - Accept,Access-Control-Allow-Origin,Access-Control-Expose-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With + Access-Control-Expose-Headers: + - Authorization + body: + encoding: ASCII-8BIT + string: !binary |- + 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 + recorded_at: Thu, 05 Jun 2025 23:05:00 GMT +- request: + method: post + uri: https://api.sandbox.orcid.org/v3.0/0000-0001-6528-2027/work + body: + encoding: UTF-8 + string: | + + + + Test + + DataCite + other + + 2019 + + + + doi + 10.14454/j6gr-cf48 + self + + + + + + https://orcid.org/0000-0003-1419-2405 + 0000-0003-1419-2405 + orcid.org + + Martin Fenner + + + + headers: + User-Agent: + - Mozilla/5.0 (compatible; Maremma/5.0.0; mailto:info@datacite.org) + Accept: + - text/html,application/json,application/xml;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Content-Type: + - application/vnd.orcid+xml + Authorization: + - Bearer TEST_SEARCH_AND_LINK_TOKEN + Accept-Encoding: + - gzip,deflate + response: + status: + code: 401 + message: Unauthorized + headers: + Date: + - Thu, 05 Jun 2025 23:05:00 GMT + Content-Type: + - application/json;charset=UTF-8 + Connection: + - keep-alive + Server: + - cloudflare + Cf-Ray: + - 94b34ff1ac796786-DFW + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Pragma: + - no-cache + Www-Authenticate: + - 'Bearer realm="ORCID T2 API", error="invalid_token", error_description="Invalid + access token: TEST_SEARCH_AND_LINK_TOKEN"' + Strict-Transport-Security: + - max-age=31536000 ; includeSubDomains + X-Xss-Protection: + - 1; mode=block + X-Frame-Options: + - DENY + X-Content-Type-Options: + - nosniff + Vary: + - accept-encoding + Content-Encoding: + - gzip + X-Target: + - reg-sbox-mapi-use2-a1 + X-Via: + - a1 + Cf-Cache-Status: + - DYNAMIC + body: + encoding: ASCII-8BIT + string: !binary |- + H4sIAAAAAAAAAKrmUlBQSi0qyi9SUrBSUMrMK0vMyUyJL8nPTs1T0oFLxqekFicXZRaUZObngRV6QhQqJCYnpxYXK4DVWymEuAaHxAe7OgY5e8Q7+rnE+3j6eceH+Hu7+ilx1QIAAAD//wMAZy+8J2sAAAA= + recorded_at: Thu, 05 Jun 2025 23:05:00 GMT +recorded_with: VCR 6.2.0 From 12f3622d0faf88dd46acf5d44ac3e501e067b0cc Mon Sep 17 00:00:00 2001 From: Bryceson Laing Date: Sun, 27 Jul 2025 17:46:38 -0500 Subject: [PATCH 10/10] fix bug where search & link from third party would fail if the user wasn't signed in to profiles --- app/controllers/users/orcid_controller.rb | 60 +++++++++++++---------- app/models/user.rb | 4 ++ config/initializers/devise.rb | 1 + 3 files changed, 38 insertions(+), 27 deletions(-) diff --git a/app/controllers/users/orcid_controller.rb b/app/controllers/users/orcid_controller.rb index 0e9dc926..c58729b4 100644 --- a/app/controllers/users/orcid_controller.rb +++ b/app/controllers/users/orcid_controller.rb @@ -6,10 +6,10 @@ module Users class OrcidController < ApplicationController BASE_URL = "#{ENV["ORCID_URL"]}/oauth" - SCOPES_AUTO_UPDATE = ["/activities/update", "/person/update", "/read-limited"].freeze - SCOPES_SEARCH_AND_LINK = ["/activities/update", "/person/update", "/read-limited"].freeze + SCOPES_AUTO_UPDATE = ["/activities/update", "/read-limited"].freeze + SCOPES_SEARCH_AND_LINK = ["/activities/update", "/read-limited"].freeze - before_action :load_user + before_action :load_user, only: [:auto_update_refresh, :auto_update_revoke, :search_and_link_refresh, :search_and_link_revoke] # Auto-update methods def auto_update_auth @@ -22,26 +22,28 @@ def auto_update_auth def auto_update_callback - tokens = callback(ENV["ORCID_AUTO_UPDATE_CLIENT_ID"], + response = callback(ENV["ORCID_AUTO_UPDATE_CLIENT_ID"], ENV["ORCID_AUTO_UPDATE_CLIENT_SECRET"], params[:code]) - @user.update(orcid_auto_update_access_token: tokens[:access_token], - orcid_auto_update_refresh_token: tokens[:refresh_token], - orcid_auto_update_expires_at: tokens[:expires_at]) + @user = User.from_orcid(response[:id]) + + @user.update(orcid_auto_update_access_token: response[:access_token], + orcid_auto_update_refresh_token: response[:refresh_token], + orcid_auto_update_expires_at: response[:expires_at]) redirect_to stored_location_for(:user) || setting_path("me") end def auto_update_refresh - tokens = refresh(ENV["ORCID_AUTO_UPDATE_CLIENT_ID"], + response = refresh(ENV["ORCID_AUTO_UPDATE_CLIENT_ID"], ENV["ORCID_AUTO_UPDATE_CLIENT_SECRET"], @user.orcid_auto_update_refresh_token) - @user.update(orcid_auto_update_access_token: tokens[:access_token], - orcid_auto_update_refresh_token: tokens[:refresh_token], - orcid_auto_update_expires_at: tokens[:expires_at]) + @user.update(orcid_auto_update_access_token: response[:access_token], + orcid_auto_update_refresh_token: response[:refresh_token], + orcid_auto_update_expires_at: response[:expires_at]) redirect_to stored_location_for(:user) || setting_path("me") end @@ -71,17 +73,20 @@ def search_and_link_auth def search_and_link_callback - tokens = callback(ENV["ORCID_SEARCH_AND_LINK_CLIENT_ID"], + response = callback(ENV["ORCID_SEARCH_AND_LINK_CLIENT_ID"], ENV["ORCID_SEARCH_AND_LINK_CLIENT_SECRET"], params[:code]) - @user.update(orcid_search_and_link_access_token: tokens[:access_token], - orcid_search_and_link_refresh_token: tokens[:refresh_token], - orcid_search_and_link_expires_at: tokens[:expires_at]) + + @user = User.from_orcid(response[:id]) + + @user.update(orcid_search_and_link_access_token: response[:access_token], + orcid_search_and_link_refresh_token: response[:refresh_token], + orcid_search_and_link_expires_at: response[:expires_at]) # Redirect to Commons if the flag isn't explicitly false. Otherwise redirect to profile settings if params["redirect_to_commons"] != "false" - redirect_to "#{ENV['COMMONS_URL']}/orcid.org/#{current_user.orcid}" + redirect_to "#{ENV['COMMONS_URL']}/orcid.org/#{@user.orcid}" else redirect_to stored_location_for(:user) || setting_path("me") end @@ -89,13 +94,13 @@ def search_and_link_callback def search_and_link_refresh - tokens = refresh(ENV["ORCID_SEARCH_AND_LINK_CLIENT_ID"], + response = refresh(ENV["ORCID_SEARCH_AND_LINK_CLIENT_ID"], ENV["ORCID_SEARCH_AND_LINK_CLIENT_SECRET"], @user.orcid_search_and_link_refresh_token) - @user.update(orcid_search_and_link_access_token: tokens[:access_token], - orcid_search_and_link_refresh_token: tokens[:refresh_token], - orcid_search_and_link_expires_at: tokens[:expires_at]) + @user.update(orcid_search_and_link_access_token: response[:access_token], + orcid_search_and_link_refresh_token: response[:refresh_token], + orcid_search_and_link_expires_at: response[:expires_at]) redirect_to stored_location_for(:user) || setting_path("me") end @@ -148,7 +153,7 @@ def callback(client_id, client_secret, code) raise "Error exchanging code for tokens: #{response.status} - #{response.body}" end - parse_tokens(response.body) + parse_body(response.body) end @@ -170,7 +175,7 @@ def refresh(client_id, client_secret, refresh_token) raise "Error refreshing tokens: #{response.status} - #{response.body}" end - parse_tokens(response.body) + parse_body(response.body) end @@ -193,13 +198,14 @@ def revoke(client_id, client_secret, access_token) end - def parse_tokens(body) - tokens = JSON.parse(body) - expires_at = Time.now.utc + tokens["expires_in"].seconds + def parse_body(json) + body = JSON.parse(json) + expires_at = Time.now.utc + body["expires_in"].seconds { - access_token: tokens["access_token"], - refresh_token: tokens["refresh_token"], + id: body["orcid"], + access_token: body["access_token"], + refresh_token: body["refresh_token"], expires_at: expires_at } end diff --git a/app/models/user.rb b/app/models/user.rb index 5bd3ea1d..f524b6b4 100755 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -133,6 +133,10 @@ def self.query_aggregations } end + def self.from_orcid(uid) + where(uid: uid).first_or_create + end + def self.from_omniauth(auth, options = {}) where(provider: options[:provider], uid: options[:uid] || auth.uid).first_or_create end diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 488de618..1dc592c2 100755 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -219,6 +219,7 @@ ENV["ORCID_CLIENT_SECRET"], member: ENV["ORCID_MEMBER"], sandbox: (ENV["ORCID_URL"] == "https://sandbox.orcid.org"), + scope: "/authenticate", provider_ignores_state: true config.omniauth :github, ENV["GITHUB_CLIENT_ID"],