orcid 0.8.2 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +4 -1
- data/README.md +34 -0
- data/Rakefile +10 -0
- data/config/application.yml.example +0 -1
- data/lib/orcid/configuration/provider.rb +1 -1
- data/lib/orcid/spec_support.rb +84 -17
- data/lib/orcid/version.rb +1 -1
- data/orcid.gemspec +2 -2
- data/spec/features/non_ui_based_interactions_spec.rb +64 -31
- metadata +18 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c138546f55044cf0a5a24bc027071c4a825f9aa5
|
4
|
+
data.tar.gz: e376ae1a6e011f2c74ef68c12c4aceede22240e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8ca33ed888b474c53ca7d36ec9a9b73e3449fbe285ca19ac2a1fd92a2b10255c7eb108231b130b6970ceeffde234880d39fb78756641acb10f6a28c36c74bf8
|
7
|
+
data.tar.gz: 2e690ffa69dd81e14ec8ae6820289789781c8f5d3ff8960bc2d79bf4898e3d94573414504612190e8bf73016daaea1a1f69783e699979a8925a07f550c6ce5e6
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -69,6 +69,23 @@ $ rails generate orcid:install
|
|
69
69
|
|
70
70
|
*Note: It will prompt you for your Orcid application secrets.*
|
71
71
|
|
72
|
+
|
73
|
+
### Caveat
|
74
|
+
|
75
|
+
You will also need to **update your devise configuration** in your routes.
|
76
|
+
|
77
|
+
From something like this:
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
devise_for :users
|
81
|
+
```
|
82
|
+
|
83
|
+
To:
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
devise_for :users, controllers: { omniauth_callbacks: 'devise/multi_auth/omniauth_callbacks' }
|
87
|
+
```
|
88
|
+
|
72
89
|
You may find it helpful to review the help text, as there are a few options for the generator.
|
73
90
|
|
74
91
|
```console
|
@@ -156,6 +173,23 @@ Run the online tests with
|
|
156
173
|
$ rake spec:online
|
157
174
|
```
|
158
175
|
|
176
|
+
### Running ALL of the Tests
|
177
|
+
|
178
|
+
Not all of the tests run. There are a few very long running tests that run.
|
179
|
+
|
180
|
+
```console
|
181
|
+
$ ORCID_APP_ID=<YOUR ORCID APP ID> \
|
182
|
+
ORCID_APP_SECRET=<YOUR ORCID APP SECRET> \
|
183
|
+
MAILINATOR_API_KEY=<YOUR MAILINATOR KEY> \
|
184
|
+
ORCID_CLAIMED_PROFILE_ID=<AN ORCID PROFILE YOUR APP HAS ALREADY CLAIMED> \
|
185
|
+
ORCID_CLAIMED_PROFILE_PASSWORD=<THE PASSWORD FOR THE ALREADY CLAIMED ORCID> \
|
186
|
+
bundle exec rake spec:jenkins
|
187
|
+
```
|
188
|
+
|
189
|
+
By setting all of the above environment variables, you will run tests that will:
|
190
|
+
|
191
|
+
* Create an Orcid, then claim it, and authenticate with your application via ORCID
|
192
|
+
|
159
193
|
## Versioning
|
160
194
|
|
161
195
|
**Orcid** uses [Semantic Versioning 2.0.0](http://semver.org/)
|
data/Rakefile
CHANGED
@@ -21,6 +21,7 @@ namespace :spec do
|
|
21
21
|
RSpec::Core::RakeTask.new(:all) do
|
22
22
|
ENV['COVERAGE'] = 'true'
|
23
23
|
end
|
24
|
+
|
24
25
|
desc 'Only run specs that do not require net connect'
|
25
26
|
RSpec::Core::RakeTask.new(:offline) do |t|
|
26
27
|
t.rspec_opts = '--tag ~requires_net_connect'
|
@@ -31,6 +32,15 @@ namespace :spec do
|
|
31
32
|
t.rspec_opts = '--tag requires_net_connect'
|
32
33
|
end
|
33
34
|
|
35
|
+
desc 'Run the Jenkins CI specs'
|
36
|
+
task :jenkins do
|
37
|
+
ENV['RAILS_ENV'] = 'test'
|
38
|
+
ENV['SPEC_OPTS'] = '--profile 20'
|
39
|
+
Rake::Task['engine_cart:clean'].invoke
|
40
|
+
Rake::Task['engine_cart:generate'].invoke
|
41
|
+
Rake::Task['spec:all'].invoke
|
42
|
+
end
|
43
|
+
|
34
44
|
desc 'Run the Travis CI specs'
|
35
45
|
task :travis do
|
36
46
|
ENV['RAILS_ENV'] = 'test'
|
@@ -17,7 +17,7 @@ module Orcid
|
|
17
17
|
def authentication_scope
|
18
18
|
@authentication_scope ||=
|
19
19
|
store.fetch('ORCID_APP_AUTHENTICATION_SCOPE') do
|
20
|
-
'/authenticate /orcid-works/create /orcid-works/update
|
20
|
+
'/authenticate /orcid-works/create /orcid-works/update'
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
data/lib/orcid/spec_support.rb
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
require 'rest_client'
|
2
|
+
|
3
|
+
# This follows the instructions from:
|
4
|
+
# http://support.orcid.org/knowledgebase/articles/179969-methods-to-generate-an-access-token-for-testing#curl
|
2
5
|
class RequestSandboxAuthorizationCode
|
3
6
|
|
4
|
-
def self.call(options = {}
|
5
|
-
new(
|
7
|
+
def self.call(options = {})
|
8
|
+
new(options).call
|
6
9
|
end
|
7
10
|
|
8
11
|
attr_reader :cookies, :access_scope, :authorize_url, :login_url
|
9
12
|
attr_reader :oauth_redirect_uri, :orcid_client_id, :authorization_code, :orcid_client_secret
|
13
|
+
attr_reader :orcid_profile_id, :password
|
10
14
|
|
11
15
|
def initialize(options = {})
|
12
16
|
@orcid_client_id = options.fetch(:orcid_client_id) { Orcid.provider.id }
|
@@ -15,13 +19,13 @@ class RequestSandboxAuthorizationCode
|
|
15
19
|
@authorize_url = options.fetch(:authorize_url) { Orcid.provider.authorize_url }
|
16
20
|
@oauth_redirect_uri = options.fetch(:oauth_redirect_uri) { 'https://developers.google.com/oauthplayground' }
|
17
21
|
@access_scope = options.fetch(:scope) { Orcid.provider.authentication_scope }
|
22
|
+
@orcid_profile_id = options.fetch(:orcid_profile_id) { ENV['ORCID_CLAIMED_PROFILE_ID'] }
|
23
|
+
@password = options.fetch(:password) { ENV['ORCID_CLAIMED_PROFILE_PASSWORD'] }
|
18
24
|
end
|
19
25
|
|
20
|
-
def call
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
login_to_orcid(orcid_profile_id, password)
|
26
|
+
def call
|
27
|
+
puts "Attempting to login to orcid { PROFILE_ID: '#{orcid_profile_id}', PASSWORD: '#{password}' }"
|
28
|
+
login_to_orcid
|
25
29
|
request_authorization
|
26
30
|
request_authorization_code
|
27
31
|
end
|
@@ -31,10 +35,19 @@ class RequestSandboxAuthorizationCode
|
|
31
35
|
|
32
36
|
private
|
33
37
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
+
def custom_authorization_url
|
39
|
+
authorize_url.sub('oauth/authorize', 'oauth/custom/authorize.json')
|
40
|
+
end
|
41
|
+
|
42
|
+
def resource_options
|
43
|
+
{ ssl_version: :SSLv23 }.tap {|options|
|
44
|
+
options[:headers] = { cookies: cookies } if cookies
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def login_to_orcid
|
49
|
+
resource = RestClient::Resource.new(login_url, resource_options)
|
50
|
+
response = resource.post({ userId: orcid_profile_id, password: password })
|
38
51
|
if JSON.parse(response)['success']
|
39
52
|
self.cookies = response.cookies
|
40
53
|
else
|
@@ -49,16 +62,70 @@ class RequestSandboxAuthorizationCode
|
|
49
62
|
scope: access_scope,
|
50
63
|
redirect_uri: oauth_redirect_uri
|
51
64
|
}
|
52
|
-
RestClient.
|
65
|
+
resource = RestClient::Resource.new("#{authorize_url}?#{parameters.to_query}", resource_options)
|
66
|
+
response = resource.get
|
67
|
+
response
|
53
68
|
end
|
54
69
|
|
55
70
|
def request_authorization_code
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
71
|
+
options = resource_options
|
72
|
+
options[:headers] ||= {}
|
73
|
+
options[:headers][:content_type] = :json
|
74
|
+
options[:headers][:accept] = :json
|
75
|
+
resource = RestClient::Resource.new(custom_authorization_url, options)
|
76
|
+
response = resource.post(authorization_code_payload.to_json)
|
77
|
+
json = JSON.parse(response)
|
78
|
+
redirected_to = json.fetch('redirectUri').fetch('value')
|
79
|
+
uri = URI.parse(redirected_to)
|
61
80
|
CGI.parse(uri.query).fetch('code').first
|
81
|
+
rescue RestClient::Exception => e
|
82
|
+
File.open("/Users/jfriesen/Desktop/orcid.html", 'w+') {|f| f.puts e.response.body.force_encoding('UTF-8') }
|
83
|
+
$stderr.puts "Response Code: #{e.response.code}\n\tCookies: #{cookies.inspect}\n\tAuthorizeURL: #{authorize_url.inspect}"
|
84
|
+
raise e
|
85
|
+
end
|
86
|
+
|
87
|
+
def authorization_code_payload
|
88
|
+
{
|
89
|
+
"errors" => [],
|
90
|
+
"userName" => {
|
91
|
+
"errors" => [],
|
92
|
+
"value" => "",
|
93
|
+
"required" => true,
|
94
|
+
"getRequiredMessage" => nil
|
95
|
+
},
|
96
|
+
"password" => {
|
97
|
+
"errors" => [],
|
98
|
+
"value" => "",
|
99
|
+
"required" => true,
|
100
|
+
"getRequiredMessage" => nil
|
101
|
+
},
|
102
|
+
"clientId" => {
|
103
|
+
"errors" => [],
|
104
|
+
"value" => "#{orcid_client_id}",
|
105
|
+
"required" => true,
|
106
|
+
"getRequiredMessage" => nil
|
107
|
+
},
|
108
|
+
"redirectUri" => {
|
109
|
+
"errors" => [],
|
110
|
+
"value" => "=#{URI.escape(oauth_redirect_uri)}",
|
111
|
+
"required" => true,
|
112
|
+
"getRequiredMessage" => nil
|
113
|
+
},
|
114
|
+
"scope" => {
|
115
|
+
"errors" => [],
|
116
|
+
"value" => "#{access_scope}",
|
117
|
+
"required" => true,
|
118
|
+
"getRequiredMessage" => nil
|
119
|
+
},
|
120
|
+
"responseType" => {
|
121
|
+
"errors" => [],
|
122
|
+
"value" => "code",
|
123
|
+
"required" => true,
|
124
|
+
"getRequiredMessage" => nil
|
125
|
+
},
|
126
|
+
"approved" => true,
|
127
|
+
"persistentTokenEnabled" => false
|
128
|
+
}
|
62
129
|
end
|
63
130
|
|
64
131
|
end
|
data/lib/orcid/version.rb
CHANGED
data/orcid.gemspec
CHANGED
@@ -31,10 +31,10 @@ Gem::Specification.new do |s|
|
|
31
31
|
s.require_paths = ['lib']
|
32
32
|
|
33
33
|
s.add_dependency 'rails', '~> 4.0.3'
|
34
|
-
s.add_dependency 'mappy', '~> 0.1.0'
|
35
34
|
s.add_dependency 'figaro'
|
36
|
-
s.add_dependency 'devise-multi_auth', '~> 0.1
|
35
|
+
s.add_dependency 'devise-multi_auth', '~> 0.1'
|
37
36
|
s.add_dependency 'omniauth-orcid'
|
37
|
+
s.add_dependency 'mappy'
|
38
38
|
s.add_dependency 'virtus'
|
39
39
|
s.add_dependency 'email_validator'
|
40
40
|
s.add_dependency 'simple_form'
|
@@ -28,23 +28,25 @@ describe 'non-UI based interactions' , requires_net_connect: true do
|
|
28
28
|
expect(profile_request.orcid_profile_id).to be_nil
|
29
29
|
end
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
if ENV['MAILINATOR_API_KEY']
|
32
|
+
it 'creates a profile' do
|
33
|
+
profile_request_coordinator.call
|
34
|
+
profile_request.reload
|
34
35
|
|
35
|
-
|
36
|
+
orcid_profile_id = profile_request.orcid_profile_id
|
36
37
|
|
37
|
-
|
38
|
+
expect(orcid_profile_id).to match(/\w{4}-\w{4}-\w{4}-\w{4}/)
|
38
39
|
|
39
|
-
|
40
|
+
claim_the_orcid!(random_valid_email_prefix)
|
40
41
|
|
41
|
-
|
42
|
+
authenticate_the_orcid!(orcid_profile_id, orcid_profile_password)
|
42
43
|
|
43
|
-
|
44
|
+
orcid_profile = Orcid::Profile.new(orcid_profile_id)
|
44
45
|
|
45
|
-
|
46
|
+
orcid_profile.append_new_work(work)
|
46
47
|
|
47
|
-
|
48
|
+
expect(orcid_profile.remote_works(force: true).count).to eq(1)
|
49
|
+
end
|
48
50
|
end
|
49
51
|
|
50
52
|
end
|
@@ -55,11 +57,11 @@ describe 'non-UI based interactions' , requires_net_connect: true do
|
|
55
57
|
|
56
58
|
before(:each) do
|
57
59
|
expect(work).to be_valid
|
58
|
-
authenticate_the_orcid!(orcid_profile_id, orcid_profile_password)
|
59
60
|
end
|
60
61
|
|
61
62
|
subject { Orcid::Profile.new(orcid_profile_id) }
|
62
63
|
it 'should increment orcid works' do
|
64
|
+
authenticate_the_orcid!(orcid_profile_id, orcid_profile_password)
|
63
65
|
replacement_work = Orcid::Work.new(title: "Test Driven Orcid Integration", work_type: 'test')
|
64
66
|
appended_work = Orcid::Work.new(title: "Another Test Drive", work_type: 'test')
|
65
67
|
|
@@ -80,32 +82,41 @@ describe 'non-UI based interactions' , requires_net_connect: true do
|
|
80
82
|
Devise::MultiAuth::CaptureSuccessfulExternalAuthentication.call(user, normalized_token)
|
81
83
|
end
|
82
84
|
|
83
|
-
# Achtung, this is going to be fragile
|
84
85
|
def claim_the_orcid!(email_prefix)
|
85
|
-
|
86
|
-
|
87
|
-
Capybara.run_server = false
|
86
|
+
$stdout.puts "Claiming an ORCID. This could take a while."
|
87
|
+
api_token = ENV.fetch('MAILINATOR_API_KEY')
|
88
88
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
rescue Capybara::ElementNotFound => e
|
96
|
-
filename = Rails.root.join('tmp/claim_orcid_failure.png')
|
97
|
-
page.save_screenshot(filename, full: true)
|
98
|
-
`open #{filename}`
|
99
|
-
raise e
|
89
|
+
mailbox_uri = "https://api.mailinator.com/api/inbox?to=#{email_prefix}&token=#{api_token}"
|
90
|
+
|
91
|
+
orcid_messages = []
|
92
|
+
mailinator_requests(mailbox_uri) do |response|
|
93
|
+
orcid_messages = response['messages'].select {|m| m['from'] =~ /\.orcid\.org\Z/ }
|
94
|
+
!!orcid_messages.first
|
100
95
|
end
|
101
96
|
|
102
|
-
|
103
|
-
|
97
|
+
orcid_message = orcid_messages.first
|
98
|
+
raise "Unable to retrieve email for #{email_prefix}@mailinator.com" unless orcid_message
|
99
|
+
|
100
|
+
message_uri = "https://api.mailinator.com/api/email?msgid=#{orcid_message.fetch('id')}&token=#{api_token}"
|
101
|
+
claim_uri = nil
|
102
|
+
mailinator_requests(message_uri) do |response|
|
103
|
+
bodies = response.fetch('data').fetch('parts').map { |part| part.fetch('body') }
|
104
|
+
bodies.each do |body|
|
105
|
+
if body =~ %r{(https://sandbox.orcid.org/claim/[\w\?=]+)}
|
106
|
+
claim_uri = $1.strip
|
107
|
+
break
|
108
|
+
end
|
109
|
+
end
|
110
|
+
claim_uri
|
111
|
+
end
|
104
112
|
|
105
|
-
|
113
|
+
# I have the href for the claim
|
114
|
+
uri = URI.parse(claim_uri)
|
115
|
+
Capybara.current_driver = :webkit
|
116
|
+
Capybara.run_server = false
|
106
117
|
Capybara.app_host = "#{uri.scheme}://#{uri.host}"
|
107
118
|
|
108
|
-
visit(uri.path)
|
119
|
+
visit("#{uri.path}?#{uri.query}")
|
109
120
|
page.all('input').each do |input|
|
110
121
|
case input[:name]
|
111
122
|
when 'password' then input.set(orcid_profile_password)
|
@@ -114,6 +125,28 @@ describe 'non-UI based interactions' , requires_net_connect: true do
|
|
114
125
|
end
|
115
126
|
end
|
116
127
|
page.all('button').find {|i| i.text == 'Claim' }.click
|
117
|
-
sleep(
|
128
|
+
sleep(5) # Because claiming your orcid could be slow
|
129
|
+
end
|
130
|
+
|
131
|
+
def mailinator_requests(uri)
|
132
|
+
base_sleep_duration = ENV.fetch('MAILINATOR_SECONDS_TO_RETRY', 120).to_i
|
133
|
+
retry_attempts = ENV.fetch('MAILINATOR_RETRY_ATTEMPTS', 6).to_i
|
134
|
+
(0...retry_attempts).each do |attempt|
|
135
|
+
sleep_duration = base_sleep_duration * (attempt +1)
|
136
|
+
$stdout.print "\n=-=-= Connecting to Mailinator. Attempt #{attempt+1}\n\tWaiting #{sleep_duration} seconds to connect: "
|
137
|
+
$stdout.flush
|
138
|
+
(0...sleep_duration).each do |second|
|
139
|
+
$stdout.print 'z' if (second % 5 == 0)
|
140
|
+
$stdout.flush
|
141
|
+
sleep(1)
|
142
|
+
end
|
143
|
+
resource = RestClient::Resource.new(uri, ssl_version: :SSLv23)
|
144
|
+
response = JSON.parse(resource.get(format: :json))
|
145
|
+
if yield(response)
|
146
|
+
$stdout.print "\n=-=-= Success on attempt #{attempt+1}. Moving on."
|
147
|
+
$stdout.flush
|
148
|
+
break
|
149
|
+
end
|
150
|
+
end
|
118
151
|
end
|
119
152
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: orcid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Friesen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 4.0.3
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: mappy
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 0.1.0
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 0.1.0
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: figaro
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,14 +44,14 @@ dependencies:
|
|
58
44
|
requirements:
|
59
45
|
- - "~>"
|
60
46
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.1
|
47
|
+
version: '0.1'
|
62
48
|
type: :runtime
|
63
49
|
prerelease: false
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
65
51
|
requirements:
|
66
52
|
- - "~>"
|
67
53
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.1
|
54
|
+
version: '0.1'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: omniauth-orcid
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +66,20 @@ dependencies:
|
|
80
66
|
- - ">="
|
81
67
|
- !ruby/object:Gem::Version
|
82
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: mappy
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: virtus
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|