globus_client 0.2.1 → 0.3.0
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.lock +8 -5
- data/README.md +24 -3
- data/api_test.rb +37 -0
- data/lib/globus/client/endpoint.rb +69 -26
- data/lib/globus/client/identity.rb +7 -0
- data/lib/globus/client/version.rb +1 -1
- data/lib/globus/client.rb +22 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a4c2d5c57d5c7439a64bf4a0c9da297422987a026ff9eafdb38722df11de72c
|
4
|
+
data.tar.gz: 48b723cfdcad41ccd033dcb57ea2e09ad1da8ec139f7a98cf36a6c264565898c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc74c6a8123ff04756bffcb06e6f0765eba0aaa18c634dd1d4481767392f320aa57bf0dec54904b92d92d88c6fa239dff417fec6c372f0b5af7293f61dc00dcd
|
7
|
+
data.tar.gz: 1b0b02bcbfe3964fb4f8e526af347403654a93441ddebe8fb3ea3ea8bd5cde326a3327c026114a2309f6650d029f0c4c3484bd8a831a2b55867b1d67436fc5f4
|
data/Gemfile.lock
CHANGED
@@ -31,9 +31,10 @@ GEM
|
|
31
31
|
i18n (1.12.0)
|
32
32
|
concurrent-ruby (~> 1.0)
|
33
33
|
json (2.6.2)
|
34
|
+
language_server-protocol (3.17.0.1)
|
34
35
|
minitest (5.16.3)
|
35
36
|
parallel (1.22.1)
|
36
|
-
parser (3.1.
|
37
|
+
parser (3.1.3.0)
|
37
38
|
ast (~> 2.4.1)
|
38
39
|
public_suffix (5.0.0)
|
39
40
|
rainbow (3.1.1)
|
@@ -63,9 +64,9 @@ GEM
|
|
63
64
|
rubocop-ast (>= 1.23.0, < 2.0)
|
64
65
|
ruby-progressbar (~> 1.7)
|
65
66
|
unicode-display_width (>= 1.4.0, < 3.0)
|
66
|
-
rubocop-ast (1.
|
67
|
+
rubocop-ast (1.24.0)
|
67
68
|
parser (>= 3.1.1.0)
|
68
|
-
rubocop-performance (1.15.
|
69
|
+
rubocop-performance (1.15.1)
|
69
70
|
rubocop (>= 1.7.0, < 2.0)
|
70
71
|
rubocop-ast (>= 0.4.0)
|
71
72
|
rubocop-rspec (2.15.0)
|
@@ -78,9 +79,10 @@ GEM
|
|
78
79
|
simplecov_json_formatter (~> 0.1)
|
79
80
|
simplecov-html (0.12.3)
|
80
81
|
simplecov_json_formatter (0.1.4)
|
81
|
-
standard (1.
|
82
|
+
standard (1.19.0)
|
83
|
+
language_server-protocol (= 3.17.0.1)
|
82
84
|
rubocop (= 1.39.0)
|
83
|
-
rubocop-performance (= 1.15.
|
85
|
+
rubocop-performance (= 1.15.1)
|
84
86
|
tzinfo (2.0.5)
|
85
87
|
concurrent-ruby (~> 1.0)
|
86
88
|
unicode-display_width (2.3.0)
|
@@ -91,6 +93,7 @@ GEM
|
|
91
93
|
zeitwerk (2.6.6)
|
92
94
|
|
93
95
|
PLATFORMS
|
96
|
+
x86_64-darwin-19
|
94
97
|
x86_64-darwin-20
|
95
98
|
x86_64-darwin-21
|
96
99
|
x86_64-linux
|
data/README.md
CHANGED
@@ -32,6 +32,8 @@ client = Globus::Client.configure(
|
|
32
32
|
transfer_endpoint_id: Settings.globus.transfer_endpoint_id
|
33
33
|
)
|
34
34
|
client.mkdir(user_id: 'mjgiarlo', work_id: 1234, work_version: 1)
|
35
|
+
|
36
|
+
result = client.user_exists?('mjgiarlo')
|
35
37
|
```
|
36
38
|
|
37
39
|
You can also invoke methods directly on the client class, which is useful in a
|
@@ -58,12 +60,31 @@ end
|
|
58
60
|
|
59
61
|
## Development
|
60
62
|
|
61
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
62
|
-
`rake spec` to run the tests. You can also run `bin/console` for an interactive
|
63
|
-
prompt that will allow you to experiment.
|
63
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
64
64
|
|
65
65
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
66
66
|
|
67
|
+
### Integration Testing
|
68
|
+
|
69
|
+
To test that the gem works against the Globus APIs, run `api_test.rb` via:
|
70
|
+
|
71
|
+
```shell
|
72
|
+
# NOTE: This is bash syntax, YMMV
|
73
|
+
$ export GLOBUS_CLIENT_ID=$(vault kv get -field=content puppet/application/sdr/globus/{prod|qa|stage}/client_id)
|
74
|
+
$ export GLOBUS_CLIENT_SECRET=$(vault kv get -field=content puppet/application/sdr/globus/{prod|qa|stage}/client_secret)
|
75
|
+
$ export GLOBUS_ENDPOINT=$(vault kv get -field=content puppet/application/sdr/globus/{prod|qa|stage}/endpoint_uuid)
|
76
|
+
$ export GLOBUS_UPLOADS_DIRECTORY=from_shared_configs
|
77
|
+
# NOTE: The three args below are a user ID, a work ID, and a work version
|
78
|
+
$ ./api_test.rb mjgiarlo 987 1
|
79
|
+
|
80
|
+
Initial directory permissions: rw
|
81
|
+
Number of files in directory: 2
|
82
|
+
Total size of files in directory: 66669
|
83
|
+
Final directory permissions: r
|
84
|
+
```
|
85
|
+
|
86
|
+
Inspect the output and compare it to what you see in Globus Personal Connect to determine if behavior is correct.
|
87
|
+
|
67
88
|
## Contributing
|
68
89
|
|
69
90
|
Bug reports and pull requests are welcome on GitHub at https://github.com/sul-dlss/globus_client.
|
data/api_test.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "globus/client"
|
6
|
+
|
7
|
+
Globus::Client.configure(
|
8
|
+
client_id: ENV["GLOBUS_CLIENT_ID"],
|
9
|
+
client_secret: ENV["GLOBUS_CLIENT_SECRET"],
|
10
|
+
uploads_directory: ENV["GLOBUS_UPLOADS_DIRECTORY"],
|
11
|
+
transfer_endpoint_id: ENV["GLOBUS_ENDPOINT"]
|
12
|
+
)
|
13
|
+
|
14
|
+
user_id, work_id, work_version = *ARGV
|
15
|
+
|
16
|
+
# Test public API methods here.
|
17
|
+
Globus::Client.mkdir(user_id:, work_id:, work_version:)
|
18
|
+
|
19
|
+
user_exists = Globus::Client.user_exists?(user_id)
|
20
|
+
|
21
|
+
# Not part of the public API but this allows us to test access changes
|
22
|
+
before_permissions = Globus::Client::Endpoint.new(Globus::Client.config, user_id: user_id, work_id: work_id, work_version: work_version).send(:access_rule)["permissions"]
|
23
|
+
|
24
|
+
files_count = Globus::Client.file_count(user_id:, work_id:, work_version:)
|
25
|
+
|
26
|
+
total_size = Globus::Client.total_size(user_id:, work_id:, work_version:)
|
27
|
+
|
28
|
+
Globus::Client.disallow_writes(user_id:, work_id:, work_version:)
|
29
|
+
|
30
|
+
# Not part of the public API but this allows us to test access changes
|
31
|
+
after_permissions = Globus::Client::Endpoint.new(Globus::Client.config, user_id: user_id, work_id: work_id, work_version: work_version).send(:access_rule)["permissions"]
|
32
|
+
|
33
|
+
puts "User #{user_id} exists: #{user_exists}"
|
34
|
+
puts "Initial directory permissions: #{before_permissions}"
|
35
|
+
puts "Number of files in directory: #{files_count}"
|
36
|
+
puts "Total size of files in directory: #{total_size}"
|
37
|
+
puts "Final directory permissions: #{after_permissions}"
|
@@ -15,11 +15,14 @@ module Globus
|
|
15
15
|
@work_version = work_version
|
16
16
|
end
|
17
17
|
|
18
|
-
|
19
|
-
def length
|
18
|
+
def file_count
|
20
19
|
objects["total"]
|
21
20
|
end
|
22
21
|
|
22
|
+
def total_size
|
23
|
+
files.sum { |file| file["size"] }
|
24
|
+
end
|
25
|
+
|
23
26
|
# Create a directory https://docs.globus.org/api/transfer/file_operations/#make_directory
|
24
27
|
def mkdir
|
25
28
|
# transfer API does not support recursive directory creation
|
@@ -45,28 +48,13 @@ module Globus
|
|
45
48
|
end
|
46
49
|
|
47
50
|
# Assign a user read/write permissions for a directory https://docs.globus.org/api/transfer/acl/#rest_access_create
|
48
|
-
def
|
49
|
-
|
50
|
-
|
51
|
-
DATA_TYPE: "access",
|
52
|
-
principal_type: "identity",
|
53
|
-
principal: identity.get_identity_id(user_id),
|
54
|
-
path: paths.last,
|
55
|
-
permissions: "rw",
|
56
|
-
notify_email: "#{user_id}@stanford.edu"
|
57
|
-
}.to_json
|
58
|
-
req.headers["Content-Type"] = "application/json"
|
59
|
-
end
|
60
|
-
|
61
|
-
return response if response.success?
|
62
|
-
|
63
|
-
# Ignore error if permissions already set for identity
|
64
|
-
if response.status == 409
|
65
|
-
error = JSON.parse(response.body)
|
66
|
-
return if error["code"] == "Exists"
|
67
|
-
end
|
51
|
+
def allow_writes
|
52
|
+
access_request(permissions: "rw")
|
53
|
+
end
|
68
54
|
|
69
|
-
|
55
|
+
# Assign a user read-only permissions for a directory https://docs.globus.org/api/transfer/acl/#rest_access_create
|
56
|
+
def disallow_writes
|
57
|
+
access_request(permissions: "r")
|
70
58
|
end
|
71
59
|
|
72
60
|
private
|
@@ -81,8 +69,8 @@ module Globus
|
|
81
69
|
)
|
82
70
|
end
|
83
71
|
|
84
|
-
def
|
85
|
-
|
72
|
+
def user
|
73
|
+
Identity.new(config).get_identity_id(user_id)
|
86
74
|
end
|
87
75
|
|
88
76
|
# Builds up a path from a list of path elements. E.g., input would look like:
|
@@ -95,18 +83,69 @@ module Globus
|
|
95
83
|
end
|
96
84
|
end
|
97
85
|
|
86
|
+
# @see #paths
|
87
|
+
def full_path
|
88
|
+
paths.last
|
89
|
+
end
|
90
|
+
|
98
91
|
def path_segments
|
99
92
|
[user_id, "work#{work_id}", "version#{work_version}"]
|
100
93
|
end
|
101
94
|
|
102
95
|
def objects
|
103
96
|
# List files at an endpoint https://docs.globus.org/api/transfer/file_operations/#list_directory_contents
|
104
|
-
response = connection.get("#{transfer_path}/ls")
|
97
|
+
response = connection.get("#{transfer_path}/ls?path=#{full_path}")
|
105
98
|
return JSON.parse(response.body) if response.success?
|
106
99
|
|
107
100
|
UnexpectedResponse.call(response)
|
108
101
|
end
|
109
102
|
|
103
|
+
def files
|
104
|
+
objects["DATA"].select { |object| object["DATA_TYPE"] == "file" }
|
105
|
+
end
|
106
|
+
|
107
|
+
def access_request(permissions:)
|
108
|
+
response = if access_rule_id
|
109
|
+
connection.put("#{access_path}/#{access_rule_id}") do |req|
|
110
|
+
req.body = {
|
111
|
+
DATA_TYPE: "access",
|
112
|
+
permissions:
|
113
|
+
}.to_json
|
114
|
+
req.headers["Content-Type"] = "application/json"
|
115
|
+
end
|
116
|
+
else
|
117
|
+
connection.post(access_path) do |req|
|
118
|
+
req.body = {
|
119
|
+
DATA_TYPE: "access",
|
120
|
+
principal_type: "identity",
|
121
|
+
principal: user,
|
122
|
+
path: full_path,
|
123
|
+
permissions:,
|
124
|
+
notify_email: "#{user_id}@stanford.edu"
|
125
|
+
}.to_json
|
126
|
+
req.headers["Content-Type"] = "application/json"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
return response if response.success?
|
131
|
+
|
132
|
+
UnexpectedResponse.call(response)
|
133
|
+
end
|
134
|
+
|
135
|
+
def access_rule
|
136
|
+
response = connection.get(access_list_path) do |req|
|
137
|
+
req.headers["Content-Type"] = "application/json"
|
138
|
+
end
|
139
|
+
|
140
|
+
JSON
|
141
|
+
.parse(response.body)["DATA"]
|
142
|
+
.find { |acl| acl["path"] == full_path }
|
143
|
+
end
|
144
|
+
|
145
|
+
def access_rule_id
|
146
|
+
access_rule&.fetch("id")
|
147
|
+
end
|
148
|
+
|
110
149
|
def transfer_path
|
111
150
|
"/v0.10/operation/endpoint/#{config.transfer_endpoint_id}"
|
112
151
|
end
|
@@ -114,6 +153,10 @@ module Globus
|
|
114
153
|
def access_path
|
115
154
|
"/v0.10/endpoint/#{config.transfer_endpoint_id}/access"
|
116
155
|
end
|
156
|
+
|
157
|
+
def access_list_path
|
158
|
+
"/v0.10/endpoint/#{config.transfer_endpoint_id}/access_list"
|
159
|
+
end
|
117
160
|
end
|
118
161
|
end
|
119
162
|
end
|
data/lib/globus/client.rb
CHANGED
@@ -36,7 +36,7 @@ module Globus
|
|
36
36
|
self
|
37
37
|
end
|
38
38
|
|
39
|
-
delegate :mkdir, :
|
39
|
+
delegate :config, :disallow_writes, :file_count, :mkdir, :total_size, :user_exists?, to: :instance
|
40
40
|
|
41
41
|
def default_transfer_url
|
42
42
|
"https://transfer.api.globusonline.org"
|
@@ -52,7 +52,27 @@ module Globus
|
|
52
52
|
def mkdir(...)
|
53
53
|
endpoint = Globus::Client::Endpoint.new(config, ...)
|
54
54
|
endpoint.mkdir
|
55
|
-
endpoint.
|
55
|
+
endpoint.allow_writes
|
56
|
+
end
|
57
|
+
|
58
|
+
def disallow_writes(...)
|
59
|
+
endpoint = Globus::Client::Endpoint.new(config, ...)
|
60
|
+
endpoint.disallow_writes
|
61
|
+
end
|
62
|
+
|
63
|
+
def file_count(...)
|
64
|
+
endpoint = Globus::Client::Endpoint.new(config, ...)
|
65
|
+
endpoint.file_count
|
66
|
+
end
|
67
|
+
|
68
|
+
def total_size(...)
|
69
|
+
endpoint = Globus::Client::Endpoint.new(config, ...)
|
70
|
+
endpoint.total_size
|
71
|
+
end
|
72
|
+
|
73
|
+
def user_exists?(...)
|
74
|
+
identity = Globus::Client::Identity.new(config)
|
75
|
+
identity.exists?(...)
|
56
76
|
end
|
57
77
|
end
|
58
78
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: globus_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aaron Collier
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2022-
|
13
|
+
date: 2022-12-07 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -164,6 +164,7 @@ files:
|
|
164
164
|
- LICENSE
|
165
165
|
- README.md
|
166
166
|
- Rakefile
|
167
|
+
- api_test.rb
|
167
168
|
- globus_client.gemspec
|
168
169
|
- lib/globus/client.rb
|
169
170
|
- lib/globus/client/authenticator.rb
|