globus_client 0.2.0 → 0.3.0

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: 77e44f70f4c6ee02299ac4718e8ed5d1c2c88d58c71a4ba2c3bfbe970e2bb5df
4
- data.tar.gz: b74fbc9c11f7b9c9fdadac074fe8709711f0065d03ab01fcecb159374446bb9b
3
+ metadata.gz: 7a4c2d5c57d5c7439a64bf4a0c9da297422987a026ff9eafdb38722df11de72c
4
+ data.tar.gz: 48b723cfdcad41ccd033dcb57ea2e09ad1da8ec139f7a98cf36a6c264565898c
5
5
  SHA512:
6
- metadata.gz: 26d0923724fc1301b344b190d347abd25a1c6e17c57214f424df46d3739fc64ead270e9ae8eb3eddecdfc6700d6c52bc935cda654aef8109a01b45a5d187ca39
7
- data.tar.gz: a5c9e21ec3917f8c560ed34eaefb38af1253cddd582223e1986a78d165301443b689875a20a96f24ef1eb514aca19fbc7994af52c1f441b5db60d9428592cd0b
6
+ metadata.gz: fc74c6a8123ff04756bffcb06e6f0765eba0aaa18c634dd1d4481767392f320aa57bf0dec54904b92d92d88c6fa239dff417fec6c372f0b5af7293f61dc00dcd
7
+ data.tar.gz: 1b0b02bcbfe3964fb4f8e526af347403654a93441ddebe8fb3ea3ea8bd5cde326a3327c026114a2309f6650d029f0c4c3484bd8a831a2b55867b1d67436fc5f4
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- globus_client (0.1.0)
4
+ globus_client (0.2.1)
5
5
  activesupport (>= 4.2, < 8)
6
6
  faraday
7
7
  zeitwerk
@@ -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.2.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.23.0)
67
+ rubocop-ast (1.24.0)
67
68
  parser (>= 3.1.1.0)
68
- rubocop-performance (1.15.0)
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.18.0)
82
+ standard (1.19.0)
83
+ language_server-protocol (= 3.17.0.1)
82
84
  rubocop (= 1.39.0)
83
- rubocop-performance (= 1.15.0)
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
@@ -106,4 +109,4 @@ DEPENDENCIES
106
109
  webmock
107
110
 
108
111
  BUNDLED WITH
109
- 2.3.19
112
+ 2.3.26
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,22 +15,32 @@ module Globus
15
15
  @work_version = work_version
16
16
  end
17
17
 
18
- # This is a temporary method to show parsing of data returned.
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
26
29
  paths.each do |path|
27
- response = call_mkdir(path)
30
+ response = connection.post("#{transfer_path}/mkdir") do |req|
31
+ req.headers["Content-Type"] = "application/json"
32
+ req.body = {
33
+ DATA_TYPE: "mkdir",
34
+ path:
35
+ }.to_json
36
+ end
37
+
28
38
  next if response.success?
29
39
 
30
- # if directory already exists
40
+ # Ignore error if directory already exists
31
41
  if response.status == 502
32
42
  error = JSON.parse(response.body)
33
- next if error["code"] == "ExternalError.MkdirFailedExists"
43
+ next if error["code"] == "ExternalError.MkdirFailed.Exists"
34
44
  end
35
45
 
36
46
  UnexpectedResponse.call(response)
@@ -38,11 +48,13 @@ module Globus
38
48
  end
39
49
 
40
50
  # Assign a user read/write permissions for a directory https://docs.globus.org/api/transfer/acl/#rest_access_create
41
- def set_permissions
42
- path = "#{config.uploads_directory}/#{user_id}/work#{work_id}/version#{work_version}/"
43
- identity = Globus::Client::Identity.new(config)
44
- id = identity.get_identity_id(user_id)
45
- call_access(path:, id:, user_id:)
51
+ def allow_writes
52
+ access_request(permissions: "rw")
53
+ end
54
+
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")
46
58
  end
47
59
 
48
60
  private
@@ -57,6 +69,10 @@ module Globus
57
69
  )
58
70
  end
59
71
 
72
+ def user
73
+ Identity.new(config).get_identity_id(user_id)
74
+ end
75
+
60
76
  # Builds up a path from a list of path elements. E.g., input would look like:
61
77
  # ["mjgiarlo", "work123", "version1"]
62
78
  # And this method returns:
@@ -67,52 +83,79 @@ module Globus
67
83
  end
68
84
  end
69
85
 
86
+ # @see #paths
87
+ def full_path
88
+ paths.last
89
+ end
90
+
70
91
  def path_segments
71
92
  [user_id, "work#{work_id}", "version#{work_version}"]
72
93
  end
73
94
 
74
- def endpoint
75
- "/v0.10/operation/endpoint/#{config.transfer_endpoint_id}"
95
+ def objects
96
+ # List files at an endpoint https://docs.globus.org/api/transfer/file_operations/#list_directory_contents
97
+ response = connection.get("#{transfer_path}/ls?path=#{full_path}")
98
+ return JSON.parse(response.body) if response.success?
99
+
100
+ UnexpectedResponse.call(response)
76
101
  end
77
102
 
78
- # @return [Faraday::Response]
79
- def call_mkdir(path)
80
- connection.post("#{endpoint}/mkdir") do |req|
81
- req.headers["Content-Type"] = "application/json"
82
- req.body = {
83
- DATA_TYPE: "mkdir",
84
- path:
85
- }.to_json
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
86
128
  end
129
+
130
+ return response if response.success?
131
+
132
+ UnexpectedResponse.call(response)
87
133
  end
88
134
 
89
- # Makes the API call to Globus to set permissions
90
- # @param path [String] the directory on the globus endpoint
91
- # @param id [String] globus identifier associated with the user_id email
92
- # @param user_id [String] user_id, not email address
93
- # @return [Faraday::Response]
94
- def call_access(path:, id:, user_id:)
95
- response = connection.post("#{endpoint}/access") do |req|
96
- req.body = {
97
- DATA_TYPE: "access",
98
- principal_type: "identity",
99
- principal: id,
100
- path:,
101
- permissions: "rw",
102
- notify_email: "#{user_id}@stanford.edu"
103
- }.to_json
135
+ def access_rule
136
+ response = connection.get(access_list_path) do |req|
104
137
  req.headers["Content-Type"] = "application/json"
105
138
  end
106
- UnexpectedResponse.call(response) unless response.success?
107
139
 
108
- response
140
+ JSON
141
+ .parse(response.body)["DATA"]
142
+ .find { |acl| acl["path"] == full_path }
109
143
  end
110
144
 
111
- def objects
112
- # List files at an endpoint https://docs.globus.org/api/transfer/file_operations/#list_directory_contents
113
- response = connection.get("#{endpoint}/ls")
114
- UnexpectedResponse.call(response) unless response.success?
115
- JSON.parse(response.body)
145
+ def access_rule_id
146
+ access_rule&.fetch("id")
147
+ end
148
+
149
+ def transfer_path
150
+ "/v0.10/operation/endpoint/#{config.transfer_endpoint_id}"
151
+ end
152
+
153
+ def access_path
154
+ "/v0.10/endpoint/#{config.transfer_endpoint_id}/access"
155
+ end
156
+
157
+ def access_list_path
158
+ "/v0.10/endpoint/#{config.transfer_endpoint_id}/access_list"
116
159
  end
117
160
  end
118
161
  end
@@ -18,6 +18,13 @@ module Globus
18
18
  extract_id(data)
19
19
  end
20
20
 
21
+ def exists?(sunetid)
22
+ get_identity_id(sunetid)
23
+ true
24
+ rescue
25
+ false
26
+ end
27
+
21
28
  private
22
29
 
23
30
  attr_reader :config
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Globus
4
4
  class Client
5
- VERSION = "0.2.0"
5
+ VERSION = "0.3.0"
6
6
  end
7
7
  end
data/lib/globus/client.rb CHANGED
@@ -36,7 +36,7 @@ module Globus
36
36
  self
37
37
  end
38
38
 
39
- delegate :mkdir, :config, to: :instance
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.set_permissions
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.2.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-11-21 00:00:00.000000000 Z
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