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 +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
|