orcid 0.8.2 → 0.8.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: be9ad04a8c327b62e782d442e012920e824e3054
4
- data.tar.gz: fad8d6daf69492a8cf851257e8879562f6219876
3
+ metadata.gz: c138546f55044cf0a5a24bc027071c4a825f9aa5
4
+ data.tar.gz: e376ae1a6e011f2c74ef68c12c4aceede22240e4
5
5
  SHA512:
6
- metadata.gz: 8ddfbeef40f5ec7c9a810f4ecea25b6d8b968e6e36c7a70b2454728e40c6d13e312e8eb12136b9b3dcfa769a91d3302e66b4a3015b2ec6da6ae19666897428e1
7
- data.tar.gz: c734a55b50001f919d674b2f70c9f7dd7e2f12b413b1b6c44c00f27f3507296a5ef9c6a6319d8fb94508d9d76996287ca4ac9e9cac0223c6ba27149d811d6b38
6
+ metadata.gz: d8ca33ed888b474c53ca7d36ec9a9b73e3449fbe285ca19ac2a1fd92a2b10255c7eb108231b130b6970ceeffde234880d39fb78756641acb10f6a28c36c74bf8
7
+ data.tar.gz: 2e690ffa69dd81e14ec8ae6820289789781c8f5d3ff8960bc2d79bf4898e3d94573414504612190e8bf73016daaea1a1f69783e699979a8925a07f550c6ce5e6
data/Gemfile CHANGED
@@ -12,4 +12,7 @@ gemspec
12
12
 
13
13
  # To use debugger
14
14
  # gem 'debugger'
15
- gem 'coveralls', require: false
15
+ gem 'coveralls', require: false
16
+ gem 'execjs'
17
+ gem 'therubyracer', platforms: :ruby
18
+ gem 'byebug', require: false
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'
@@ -12,4 +12,3 @@ ORCID_APP_SECRET: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
12
12
 
13
13
  ORCID_CLAIMED_PROFILE_ID: 0000-0000-0000-0000
14
14
  ORCID_CLAIMED_PROFILE_PASSWORD: password1A
15
- ORCID_CLAIMED_PROFILE_EMAIL: cwksfxyqkmrudrfrdxvlzjxl@mailinator.com
@@ -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 /read-public'
20
+ '/authenticate /orcid-works/create /orcid-works/update'
21
21
  end
22
22
  end
23
23
 
@@ -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 = {}, config = {})
5
- new(config).call(options)
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(options = {})
21
- orcid_profile_id = options.fetch(:orcid_profile_id) { ENV['ORCID_CLAIMED_PROFILE_ID'] }
22
- password = options.fetch(:password) { ENV['ORCID_CLAIMED_PROFILE_PASSWORD'] }
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 login_to_orcid(orcid_profile_id, password)
35
- response = RestClient.post(
36
- login_url, userId: orcid_profile_id, password: password
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.get(authorize_url, { params: parameters, cookies: cookies })
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
- RestClient.post(
57
- authorize_url, { user_oauth_approval: true }, { cookies: cookies }
58
- )
59
- rescue RestClient::Found => e
60
- uri = URI.parse(e.response.headers.fetch(:location))
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
@@ -1,3 +1,3 @@
1
1
  module Orcid
2
- VERSION = '0.8.2'
2
+ VERSION = '0.8.3'
3
3
  end
@@ -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.0'
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
- it 'creates a profile' do
32
- profile_request_coordinator.call
33
- profile_request.reload
31
+ if ENV['MAILINATOR_API_KEY']
32
+ it 'creates a profile' do
33
+ profile_request_coordinator.call
34
+ profile_request.reload
34
35
 
35
- orcid_profile_id = profile_request.orcid_profile_id
36
+ orcid_profile_id = profile_request.orcid_profile_id
36
37
 
37
- expect(orcid_profile_id).to match(/\w{4}-\w{4}-\w{4}-\w{4}/)
38
+ expect(orcid_profile_id).to match(/\w{4}-\w{4}-\w{4}-\w{4}/)
38
39
 
39
- claim_the_orcid!(random_valid_email_prefix)
40
+ claim_the_orcid!(random_valid_email_prefix)
40
41
 
41
- authenticate_the_orcid!(orcid_profile_id, orcid_profile_password)
42
+ authenticate_the_orcid!(orcid_profile_id, orcid_profile_password)
42
43
 
43
- orcid_profile = Orcid::Profile.new(orcid_profile_id)
44
+ orcid_profile = Orcid::Profile.new(orcid_profile_id)
44
45
 
45
- orcid_profile.append_new_work(work)
46
+ orcid_profile.append_new_work(work)
46
47
 
47
- expect(orcid_profile.remote_works(force: true).count).to eq(1)
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
- Capybara.current_driver = :webkit
86
- Capybara.app_host = 'http://mailinator.com'
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
- sleep(2) # Because Orcid may not have delivered the mail just yet
90
-
91
- visit("/inbox.jsp?to=#{email_prefix}")
92
- sleep(2) # Because mailinator might be slow
93
- begin
94
- page.find('#mailcontainer a').click
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
- sleep(2) # Because mailinator might be slow
103
- href = page.all('.mailview a').collect { |a| a[:href] }.find {|href| href = /\/claim\//}
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
- uri = URI.parse(href)
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(2) # Because claiming your orcid could be slowe
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.2
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-09-24 00:00:00.000000000 Z
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.0
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.0
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