handle-system-rest 0.1.1 → 0.1.2

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
  SHA256:
3
- metadata.gz: 80560da22c69f15df93fe8e75c12627751d4a67d2737d872677d7e6acca7eb3c
4
- data.tar.gz: fc09852264bb245a026acfa8efe66fed8c6e85d71140064e120bda81a54326b8
3
+ metadata.gz: ed36556bd087f406808b48bfe9b178baf67601df43e0217edd92d82048248d95
4
+ data.tar.gz: 1a7720a452974ac4be21b59ef237f753e0b06b3a5f2c73bba6dff158e8a45c8f
5
5
  SHA512:
6
- metadata.gz: 518f266900d680dcc2b826042187109fc7addd8f73a5395500e854be76619ec04d6e0c987737b322b0f4dd083ecc029cc7ce438141f0ae011d1d39cf1842884f
7
- data.tar.gz: f29c169459e00f9374b8172f82337b9d1f5a6b220a4238ae1d384be2d72b1bf3c6e1d7097502adab74989ce82c84a9e15cc83bf88fa4c443521aa192a909b0ed
6
+ metadata.gz: a4658e4ce5b7cf369ae604ae99eb2ccee86eeba41cc2a88ea8b2fada1ae0b973ebcdf57c3d5100978abc08196c728b330ace29b7a04f1db01dd355e1ba9f1fe9
7
+ data.tar.gz: c4a250a09db5ce4a183b13ca90e8efaadf7db4ceb02647d95d1275c25e5c0b7ef317c6bc69af49bc338453b92f902b673a58ff6590787723b632f380724d8cfe
data/README.md CHANGED
@@ -10,7 +10,7 @@ This library works with Handle System version 8 or higher. For older versions o
10
10
 
11
11
  Before you start using the library, you need to convert your Handle server's private key into PEM format. The Handle Server distribution directory (e.g., `/hs/handle-9.2.0`) has a utility, `hdl-convert-key`, for doing this. Your private key (`admpriv.bin`) is in the server directory (e.g., `/hs/svr_1`).
12
12
 
13
- On the Handle server, Run this command to convert the file:
13
+ On the Handle server, run this command to convert the file:
14
14
 
15
15
  ```
16
16
  /hs/handle-9.2.0/bin/hdl-convert-key /hs/svr_1/admpriv.bin -o /hs/svr_1/admpriv.pem
@@ -9,12 +9,12 @@ Gem::Specification.new do |spec|
9
9
  spec.email = ['dwalker@calstate.edu']
10
10
 
11
11
  spec.summary = 'A library for interfacing with the Handle System JSON REST API.'
12
- spec.description = spec.summary + ' This gem works with Handle System ' +
13
- 'version 8 or higher. For older versions of the ' +
14
- "Handle System, which didn't have a JSON API, " +
15
- 'consider using the handle-system gem'
12
+ spec.description = spec.summary + ' This gem works with Handle System ' +
13
+ 'version 8 or higher. For older versions of the ' +
14
+ "Handle System, which didn't have a JSON API, " +
15
+ 'consider using the handle-system gem.'
16
16
  spec.homepage = 'https://github.com/csuscholarworks/handle-system'
17
- spec.license = 'APACHE'
17
+ spec.license = 'Apache-2.0'
18
18
  spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
19
19
 
20
20
  spec.metadata['homepage_uri'] = spec.homepage
@@ -13,9 +13,10 @@ module HandleSystem
13
13
  # @param [String] server ip_address:port, e.g., 123.456.78.9:8000
14
14
  # @param [String] hs_admin handle administrator
15
15
  # @param [String] priv_key_path file path to private key
16
+ # @param [String] pass_phrase [optional] pass phrase for private key
16
17
  #
17
- def initialize(server, hs_admin, priv_key_path)
18
- @http_client = HttpClient.new(server, hs_admin, priv_key_path)
18
+ def initialize(server, hs_admin, priv_key_path, pass_phrase = nil)
19
+ @http_client = HttpClient.new(server, hs_admin, priv_key_path, pass_phrase)
19
20
  @handle_base = 'http://hdl.handle.net/'
20
21
  end
21
22
 
@@ -24,29 +25,40 @@ module HandleSystem
24
25
  #
25
26
  # @param [String] handle e.g., 20.500.12345/876
26
27
  # @param [String] url the url we want to register
27
- # @param [String] email [optional] email address to add to record
28
- # @param [String] hs_admin [optional] handle administrator to add to record
28
+ # @param [String] email [optional] email address
29
+ # @param [String] hs_admin [optional] handle administrator
29
30
  #
30
31
  # @return [string] the new handle url at hdl.handle.net
31
32
  #
32
33
  def create(handle, url, email = nil, hs_admin = nil)
33
- body = Record.new.from_values(handle, url, email, hs_admin).json
34
- json = @http_client.put_it('/handles/' + handle, body)
35
- @handle_base + json['handle']
34
+ set_record(handle, url, email, hs_admin, false)
36
35
  end
37
36
 
38
- # creating and updating handle records is the same thing
39
- alias update create
37
+ #
38
+ # Update an existing handle
39
+ #
40
+ # Will create a new handle if no record already exists
41
+ #
42
+ # @param [String] handle e.g., 20.500.12345/876
43
+ # @param [String] url the url we want to register
44
+ # @param [String] email [optional] email address
45
+ # @param [String] hs_admin [optional] handle administrator
46
+ #
47
+ # @return [string] the new handle url at hdl.handle.net
48
+ #
49
+ def update(handle, url, email = nil, hs_admin = nil)
50
+ set_record(handle, url, email, hs_admin, true)
51
+ end
40
52
 
41
53
  #
42
54
  # Return the full record for a handle
43
55
  #
44
56
  # @param [String] handle handle identifier
45
57
  #
46
- # @return [<JSON>] the handle record
58
+ # @return [HandleSystem::Record] the handle record
47
59
  #
48
60
  def get(handle)
49
- json = @http_client.get_it('/handles/' + handle)
61
+ json = @http_client.get('/handles/' + handle)
50
62
  Record.new.from_json(json)
51
63
  end
52
64
 
@@ -58,8 +70,29 @@ module HandleSystem
58
70
  # @return [Boolean] true if we deleted the record
59
71
  #
60
72
  def delete(handle)
61
- json = @http_client.delete_it('/handles/' + handle)
73
+ json = @http_client.delete('/handles/' + handle)
62
74
  return true if json['responseCode'] == 1
63
75
  end
76
+
77
+ protected
78
+
79
+ #
80
+ # Create or update a handle
81
+ #
82
+ # @param [String] handle e.g., 20.500.12345/876
83
+ # @param [String] url the url we want to register
84
+ # @param [String] email [optional] email address to add to record
85
+ # @param [String] hs_admin [optional] handle administrator
86
+ # @param [Boolean] overwrite [optional] overwrite any existing record?
87
+ # default: false
88
+ #
89
+ # @return [string] the new handle url at hdl.handle.net
90
+ #
91
+ def set_record(handle, url, email = nil, hs_admin = nil, overwrite = false)
92
+ body = Record.new.from_values(handle, url, email, hs_admin).json
93
+ url = '/handles/' + handle + '?overwrite=' + overwrite.to_s
94
+ json = @http_client.put(url, body)
95
+ @handle_base + json['handle']
96
+ end
64
97
  end
65
98
  end
@@ -11,20 +11,40 @@ module HandleSystem
11
11
  attr_reader :response_code
12
12
 
13
13
  # @return [String] the handle specified in the request
14
- attr_reader :handle
14
+ attr_accessor :handle
15
+
16
+ # @return [String] the URL we sent that produced the error
17
+ attr_accessor :url
15
18
 
16
19
  #
17
20
  # New Handle server Error
18
21
  #
19
- # @param [Integer] code handle protocol response code for the message
20
- # @param [String] handle the handle specified in the request
21
- # @param [String] message error message
22
+ # @param [Integer] response_code handle protocol response code for the message
23
+ # @param [String] message error message
22
24
  #
23
- def initialize(code, handle, message)
24
- @response_code = code.to_int unless code.nil?
25
- @handle = handle
25
+ def initialize(response_code, message)
26
+ @response_code = response_code.to_int unless response_code.nil?
26
27
  super(message)
27
28
  end
29
+
30
+ #
31
+ # Handle server response codes / description
32
+ #
33
+ # @return [Hash] in the form of code => description
34
+ #
35
+ def self.response_codes
36
+ {
37
+ 2 => 'An unexpected error on the server',
38
+ 100 => 'Handle not found',
39
+ 101 => 'Handle already exists',
40
+ 102 => 'Invalid handle',
41
+ 200 => 'Values not found',
42
+ 201 => 'Value already exists',
43
+ 202 => 'Invalid value',
44
+ 301 => 'Server not responsible for handle',
45
+ 402 => 'Authentication needed'
46
+ }
47
+ end
28
48
  end
29
49
 
30
50
  #
@@ -23,10 +23,12 @@ module HandleSystem
23
23
  # @param [String] server ip_address:port, e.g., 123.456.78.9:8000
24
24
  # @param [String] hs_admin handle administrator
25
25
  # @param [String] priv_key_path file path to private key
26
+ # @param [String] pass_phrase [optional] pass phrase for private key
26
27
  #
27
- def initialize(server, hs_admin, priv_key_path)
28
+ def initialize(server, hs_admin, priv_key_path, pass_phrase = nil)
28
29
  @hs_admin = hs_admin
29
30
  @private_key_path = priv_key_path
31
+ @pass_phrase = pass_phrase
30
32
  @base_url = 'https://' + server + '/api'
31
33
  @session_id = initialize_session
32
34
  end
@@ -39,11 +41,10 @@ module HandleSystem
39
41
  # @raise HandleSystem::Error if we got an error from the server
40
42
  # @return [JSON] parsed json response from handle server
41
43
  #
42
- def get_it(path)
44
+ def get(path)
43
45
  url = @base_url + path
44
- json = self.class.get(url, options).parsed_response
45
- check_errors(json)
46
- json
46
+ response = self.class.get(url, options)
47
+ process_response(url, response)
47
48
  end
48
49
 
49
50
  #
@@ -55,11 +56,10 @@ module HandleSystem
55
56
  # @raise HandleSystem::Error if we got an error from the server
56
57
  # @return [JSON] parsed json response from handle server
57
58
  #
58
- def put_it(path, body)
59
+ def put(path, body)
59
60
  url = @base_url + path
60
- json = self.class.put(url, body: body, **options).parsed_response
61
- check_errors(json)
62
- json
61
+ response = self.class.put(url, body: body, **options)
62
+ process_response(url, response)
63
63
  end
64
64
 
65
65
  #
@@ -70,19 +70,47 @@ module HandleSystem
70
70
  # @raise HandleSystem::Error if we got an error from the server
71
71
  # @return [JSON] parsed json response from handle server
72
72
  #
73
- def delete_it(path)
73
+ def delete(path)
74
74
  url = @base_url + path
75
- json = self.class.delete(url, options).parsed_response
76
- check_errors(json)
77
- json
75
+ response = self.class.delete(url, options)
76
+ process_response(url, response)
78
77
  end
79
78
 
80
79
  private
81
80
 
81
+ #
82
+ # Extract JSON from response, throw any errors we found
83
+ #
84
+ # @param [String] url the URL we sent
85
+ # @param [HttParty::Response] response
86
+ #
87
+ # @return [JSON] the json response from the server
88
+ #
89
+ def process_response(url, response)
90
+ json = response.parsed_response
91
+ response_code = json['responseCode']
92
+ return json unless response_code != 1
93
+
94
+ # we got an error response from the handle server, so convert it into
95
+ # an actual exception and throw it here
96
+
97
+ message = if json['message']
98
+ json['message']
99
+ elsif Error.response_codes.include? response_code
100
+ Error.response_codes[response_code]
101
+ else
102
+ 'Unexpected error'
103
+ end
104
+
105
+ error = Error.new(response_code, message)
106
+ error.handle = json['handle']
107
+ error.url = url
108
+ raise error
109
+ end
110
+
82
111
  #
83
112
  # Header and connection options
84
113
  #
85
- # @raise HandleSystem::Error
86
114
  # @return [Hash]
87
115
  #
88
116
  def options
@@ -95,19 +123,6 @@ module HandleSystem
95
123
  }
96
124
  end
97
125
 
98
- #
99
- # If we got an error message from the handle server, convert it into
100
- # an actual exception and throw it here
101
- #
102
- # @param [JSON] json handle server json response
103
- # @raise HandleSystem::Error
104
- #
105
- def check_errors(json)
106
- return unless json['message']
107
-
108
- raise Error.new(json['responseCode'], json['handle'], json['message'])
109
- end
110
-
111
126
  #
112
127
  # Initialize a new session with the handle server using its
113
128
  # challenge-response framework
@@ -152,16 +167,17 @@ module HandleSystem
152
167
  combined_nonce = server_nonce + client_nonce
153
168
 
154
169
  # create combined nonce digest and sign with private key
155
- private_key = OpenSSL::PKey::RSA.new(File.read(@private_key_path))
170
+ key_file = File.read(@private_key_path)
171
+ private_key = OpenSSL::PKey::RSA.new(key_file, @pass_phrase)
156
172
  signature = private_key.sign(OpenSSL::Digest::SHA256.new, combined_nonce)
157
173
 
158
174
  # build the authorization header
159
175
  header = 'Handle sessionId="' + session_id + '", ' \
160
- 'id="' + CGI.escape(@hs_admin) + '", ' \
161
- 'type="HS_PUBKEY", ' \
162
- 'cnonce="' + Base64.encode64(client_nonce) + '", ' \
163
- 'alg="SHA256", ' \
164
- 'signature="' + Base64.encode64(signature) + '"'
176
+ 'id="' + CGI.escape(@hs_admin) + '", ' \
177
+ 'type="HS_PUBKEY", ' \
178
+ 'cnonce="' + Base64.encode64(client_nonce) + '", ' \
179
+ 'alg="SHA256", ' \
180
+ 'signature="' + Base64.encode64(signature) + '"'
165
181
  header.gsub("\n", '')
166
182
  end
167
183
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HandleSystem
4
- VERSION = '0.1.1'
4
+ VERSION = '0.1.2'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: handle-system-rest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Walker
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-18 00:00:00.000000000 Z
11
+ date: 2020-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -40,7 +40,7 @@ dependencies:
40
40
  version: '0'
41
41
  description: A library for interfacing with the Handle System JSON REST API. This
42
42
  gem works with Handle System version 8 or higher. For older versions of the Handle
43
- System, which didn't have a JSON API, consider using the handle-system gem
43
+ System, which didn't have a JSON API, consider using the handle-system gem.
44
44
  email:
45
45
  - dwalker@calstate.edu
46
46
  executables: []
@@ -65,7 +65,7 @@ files:
65
65
  - lib/handle_system/version.rb
66
66
  homepage: https://github.com/csuscholarworks/handle-system
67
67
  licenses:
68
- - APACHE
68
+ - Apache-2.0
69
69
  metadata:
70
70
  homepage_uri: https://github.com/csuscholarworks/handle-system
71
71
  source_code_uri: https://github.com/csuscholarworks/handle-system