handle-system-rest 0.1.1 → 0.1.2
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/README.md +1 -1
- data/handle_system.gemspec +5 -5
- data/lib/handle_system/client.rb +45 -12
- data/lib/handle_system/exceptions.rb +27 -7
- data/lib/handle_system/http_client.rb +49 -33
- data/lib/handle_system/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed36556bd087f406808b48bfe9b178baf67601df43e0217edd92d82048248d95
|
4
|
+
data.tar.gz: 1a7720a452974ac4be21b59ef237f753e0b06b3a5f2c73bba6dff158e8a45c8f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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,
|
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
|
data/handle_system.gemspec
CHANGED
@@ -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 =
|
13
|
-
|
14
|
-
|
15
|
-
|
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 = '
|
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
|
data/lib/handle_system/client.rb
CHANGED
@@ -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
|
28
|
-
# @param [String] hs_admin [optional] handle administrator
|
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
|
-
|
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
|
-
#
|
39
|
-
|
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 [
|
58
|
+
# @return [HandleSystem::Record] the handle record
|
47
59
|
#
|
48
60
|
def get(handle)
|
49
|
-
json = @http_client.
|
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.
|
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
|
-
|
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]
|
20
|
-
# @param [String]
|
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(
|
24
|
-
@response_code =
|
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
|
44
|
+
def get(path)
|
43
45
|
url = @base_url + path
|
44
|
-
|
45
|
-
|
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
|
59
|
+
def put(path, body)
|
59
60
|
url = @base_url + path
|
60
|
-
|
61
|
-
|
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
|
73
|
+
def delete(path)
|
74
74
|
url = @base_url + path
|
75
|
-
|
76
|
-
|
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
|
-
|
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
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
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
|
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.
|
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-
|
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
|
-
-
|
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
|