artifactory 2.1.3 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +2 -2
- data/lib/artifactory.rb +14 -13
- data/lib/artifactory/client.rb +2 -1
- data/lib/artifactory/resources/artifact.rb +82 -0
- data/lib/artifactory/resources/permission_target.rb +206 -0
- data/lib/artifactory/resources/repository.rb +1 -1
- data/lib/artifactory/version.rb +1 -1
- data/spec/integration/resources/artifact_spec.rb +8 -0
- data/spec/integration/resources/permission_target_spec.rb +75 -0
- data/spec/support/api_server.rb +2 -0
- data/spec/support/api_server/artifact_endpoints.rb +14 -0
- data/spec/support/api_server/permission_target_endpoints.rb +53 -0
- data/spec/unit/resources/artifact_spec.rb +50 -0
- data/spec/unit/resources/permission_target_spec.rb +186 -0
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b89a0d205ba82632c1f9b538a50b84f69b67ac0f
|
4
|
+
data.tar.gz: 1484191f4caf8502ca9ec7519d97c67fe5cc51f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9d374065d88be5dc94f46fa9c4cf90694e8eb270ef1c92c6036a1e7941274735ca89e9ecc326d3d2d25d4a9170dd89217b0d6ee39cb2b616810817d756734249
|
7
|
+
data.tar.gz: dbe9986454583e5977d555d466a9163a535ae1a623b1d7916f258c1016315db1c32e09355f8e48303793a2c3189a3c9f5044b168217ecac6ca02d031aecbd042
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,12 @@ Artifactory Client CHANGELOG
|
|
3
3
|
This file is used to document the changes between releases of the Artifactory
|
4
4
|
Ruby client.
|
5
5
|
|
6
|
+
v2.2.0 (11-20-2014)
|
7
|
+
-------------------
|
8
|
+
- Add artifact usage search
|
9
|
+
- Add artifact creation search
|
10
|
+
- Add support for configuring permission targets
|
11
|
+
|
6
12
|
v2.1.3 (08-29-2014)
|
7
13
|
-------------------
|
8
14
|
- CGI escape matrix properties
|
data/README.md
CHANGED
@@ -31,14 +31,14 @@ This will given you "Rails-like" access to the top-level Artifactory resources l
|
|
31
31
|
|
32
32
|
```ruby
|
33
33
|
System.info
|
34
|
-
|
34
|
+
Repository.all
|
35
35
|
```
|
36
36
|
|
37
37
|
If you choose not to include the module (for namespacing reasons), you will need to specify the full module path to access resources:
|
38
38
|
|
39
39
|
```ruby
|
40
40
|
Artifactory::Resource::System.info
|
41
|
-
Artifactory::Resource::
|
41
|
+
Artifactory::Resource::Repository.all
|
42
42
|
```
|
43
43
|
|
44
44
|
### Create a connection
|
data/lib/artifactory.rb
CHANGED
@@ -30,19 +30,20 @@ module Artifactory
|
|
30
30
|
end
|
31
31
|
|
32
32
|
module Resource
|
33
|
-
autoload :Artifact,
|
34
|
-
autoload :Backup,
|
35
|
-
autoload :Base,
|
36
|
-
autoload :Build,
|
37
|
-
autoload :Group,
|
38
|
-
autoload :Layout,
|
39
|
-
autoload :LDAPSetting,
|
40
|
-
autoload :MailServer,
|
41
|
-
autoload :
|
42
|
-
autoload :
|
43
|
-
autoload :
|
44
|
-
autoload :
|
45
|
-
autoload :
|
33
|
+
autoload :Artifact, 'artifactory/resources/artifact'
|
34
|
+
autoload :Backup, 'artifactory/resources/backup'
|
35
|
+
autoload :Base, 'artifactory/resources/base'
|
36
|
+
autoload :Build, 'artifactory/resources/build'
|
37
|
+
autoload :Group, 'artifactory/resources/group'
|
38
|
+
autoload :Layout, 'artifactory/resources/layout'
|
39
|
+
autoload :LDAPSetting, 'artifactory/resources/ldap_setting'
|
40
|
+
autoload :MailServer, 'artifactory/resources/mail_server'
|
41
|
+
autoload :PermissionTarget, 'artifactory/resources/permission_target'
|
42
|
+
autoload :Plugin, 'artifactory/resources/plugin'
|
43
|
+
autoload :Repository, 'artifactory/resources/repository'
|
44
|
+
autoload :System, 'artifactory/resources/system'
|
45
|
+
autoload :URLBase, 'artifactory/resources/url_base'
|
46
|
+
autoload :User, 'artifactory/resources/user'
|
46
47
|
end
|
47
48
|
|
48
49
|
class << self
|
data/lib/artifactory/client.rb
CHANGED
@@ -52,10 +52,11 @@ module Artifactory
|
|
52
52
|
proxy Resource::Layout
|
53
53
|
proxy Resource::LDAPSetting
|
54
54
|
proxy Resource::MailServer
|
55
|
+
proxy Resource::PermissionTarget
|
55
56
|
proxy Resource::Repository
|
57
|
+
proxy Resource::System
|
56
58
|
proxy Resource::URLBase
|
57
59
|
proxy Resource::User
|
58
|
-
proxy Resource::System
|
59
60
|
|
60
61
|
#
|
61
62
|
# Create a new Artifactory Client with the given options. Any options
|
@@ -185,6 +185,88 @@ module Artifactory
|
|
185
185
|
end
|
186
186
|
end
|
187
187
|
|
188
|
+
#
|
189
|
+
# Search for an artifact by its usage
|
190
|
+
#
|
191
|
+
# @example Search for all repositories with the given usage statistics
|
192
|
+
# Artifact.usage_search(
|
193
|
+
# notUsedSince: 1388534400000,
|
194
|
+
# createdBefore: 1388534400000,
|
195
|
+
# )
|
196
|
+
#
|
197
|
+
# @example Search for all artifacts with the given usage statistics in a repo
|
198
|
+
# Artifact.usage_search(
|
199
|
+
# notUsedSince: 1388534400000,
|
200
|
+
# createdBefore: 1388534400000,
|
201
|
+
# repos: 'libs-release-local',
|
202
|
+
# )
|
203
|
+
#
|
204
|
+
# @param [Hash] options
|
205
|
+
# the list of options to search with
|
206
|
+
#
|
207
|
+
# @option options [Artifactory::Client] :client
|
208
|
+
# the client object to make the request with
|
209
|
+
# @option options [Long] :notUsedSince
|
210
|
+
# the last downloaded cutoff date of the artifact to search for (millis since epoch)
|
211
|
+
# @option options [Long] :createdBefore
|
212
|
+
# the creation cutoff date of the artifact to search for (millis since epoch)
|
213
|
+
# @option options [String, Array<String>] :repos
|
214
|
+
# the list of repos to search
|
215
|
+
#
|
216
|
+
# @return [Array<Resource::Artifact>]
|
217
|
+
# a list of artifacts that match the query
|
218
|
+
#
|
219
|
+
def usage_search(options = {})
|
220
|
+
client = extract_client!(options)
|
221
|
+
params = Util.slice(options, :notUsedSince, :createdBefore, :repos)
|
222
|
+
format_repos!(params)
|
223
|
+
|
224
|
+
client.get('/api/search/usage', params)['results'].map do |artifact|
|
225
|
+
from_url(artifact['uri'], client: client)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
#
|
230
|
+
# Search for an artifact by its creation date
|
231
|
+
#
|
232
|
+
# @example Search for all repositories with the given creation date range
|
233
|
+
# Artifact.usage_search(
|
234
|
+
# from : 1414800000000,
|
235
|
+
# to : 1414871200000,
|
236
|
+
# )
|
237
|
+
#
|
238
|
+
# @example Search for all artifacts with the given creation date range in a repo
|
239
|
+
# Artifact.usage_search(
|
240
|
+
# from : 1414800000000,
|
241
|
+
# to : 1414871200000,
|
242
|
+
# repos: 'libs-release-local',
|
243
|
+
# )
|
244
|
+
#
|
245
|
+
# @param [Hash] options
|
246
|
+
# the list of options to search with
|
247
|
+
#
|
248
|
+
# @option options [Artifactory::Client] :client
|
249
|
+
# the client object to make the request with
|
250
|
+
# @option options [Long] :from
|
251
|
+
# the creation start date of the artifact to search for (millis since epoch)
|
252
|
+
# @option options [Long] :to
|
253
|
+
# the creation end date of the artifact to search for (millis since epoch)
|
254
|
+
# @option options [String, Array<String>] :repos
|
255
|
+
# the list of repos to search
|
256
|
+
#
|
257
|
+
# @return [Array<Resource::Artifact>]
|
258
|
+
# a list of artifacts that match the query
|
259
|
+
#
|
260
|
+
def creation_search(options = {})
|
261
|
+
client = extract_client!(options)
|
262
|
+
params = Util.slice(options, :from, :to, :repos)
|
263
|
+
format_repos!(params)
|
264
|
+
|
265
|
+
client.get('/api/search/creation', params)['results'].map do |artifact|
|
266
|
+
from_url(artifact['uri'], client: client)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
188
270
|
#
|
189
271
|
# Get all versions of an artifact.
|
190
272
|
#
|
@@ -0,0 +1,206 @@
|
|
1
|
+
module Artifactory
|
2
|
+
class Resource::PermissionTarget < Resource::Base
|
3
|
+
VERBOSE_PERMS = {
|
4
|
+
'd' => 'delete',
|
5
|
+
'm' => 'admin',
|
6
|
+
'n' => 'annotate',
|
7
|
+
'r' => 'read',
|
8
|
+
'w' => 'deploy',
|
9
|
+
}
|
10
|
+
class << self
|
11
|
+
#
|
12
|
+
# Get a list of all PermissionTargets in the system.
|
13
|
+
#
|
14
|
+
# @param [Hash] options
|
15
|
+
# the list of options
|
16
|
+
#
|
17
|
+
# @option options [Artifactory::Client] :client
|
18
|
+
# the client object to make the request with
|
19
|
+
#
|
20
|
+
# @return [Array<Resource::PermissionTarget>]
|
21
|
+
# the list of PermissionTargets
|
22
|
+
#
|
23
|
+
def all(options = {})
|
24
|
+
client = extract_client!(options)
|
25
|
+
client.get('/api/security/permissions').map do |hash|
|
26
|
+
from_url(hash['uri'], client: client)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# Find (fetch) a permission target by its name.
|
32
|
+
#
|
33
|
+
# @example Find a permission target by its name
|
34
|
+
# PermissionTarget.find('readers') #=> #<PermissionTarget name: 'readers' ...>
|
35
|
+
#
|
36
|
+
# @param [String] name
|
37
|
+
# the name of the permission target to find
|
38
|
+
# @param [Hash] options
|
39
|
+
# the list of options
|
40
|
+
#
|
41
|
+
# @option options [Artifactory::Client] :client
|
42
|
+
# the client object to make the request with
|
43
|
+
#
|
44
|
+
# @return [Resource::PermissionTarget, nil]
|
45
|
+
# an instance of the permission target that matches the given name, or +nil+
|
46
|
+
# if one does not exist
|
47
|
+
#
|
48
|
+
def find(name, options = {})
|
49
|
+
client = extract_client!(options)
|
50
|
+
|
51
|
+
response = client.get("/api/security/permissions/#{url_safe(name)}")
|
52
|
+
from_hash(response, client: client)
|
53
|
+
rescue Error::HTTPError => e
|
54
|
+
raise unless e.code == 404
|
55
|
+
nil
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# @see Resource::Base.from_hash
|
60
|
+
# Additionally use verbose names for permissions (e.g. 'read' for 'r')
|
61
|
+
#
|
62
|
+
def from_hash(hash, options = {})
|
63
|
+
super.tap do |instance|
|
64
|
+
%w(users groups).each do |key|
|
65
|
+
if instance.principals[key] && !instance.principals[key].nil?
|
66
|
+
instance.principals[key] = Hash[instance.principals[key].map { |k, v| [k, verbose(v)] } ]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
#
|
75
|
+
# Replace an array of permissions with one using verbose permission names
|
76
|
+
#
|
77
|
+
def verbose(array)
|
78
|
+
array.map { |elt| VERBOSE_PERMS[elt] }.sort
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class Principal
|
83
|
+
attr_accessor :users, :groups
|
84
|
+
|
85
|
+
def initialize(users = {}, groups = {})
|
86
|
+
@users = users
|
87
|
+
@groups = groups
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# Converts the user-friendly form of the principals hash to one suitable
|
92
|
+
# for posting to Artifactory.
|
93
|
+
# @return [Hash]
|
94
|
+
#
|
95
|
+
def to_abbreviated
|
96
|
+
{ 'users' => abbreviate_principal(@users), 'groups' => abbreviate_principal(@groups) }
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
#
|
102
|
+
# Replace an array of verbose permission names with an equivalent array of abbreviated permission names.
|
103
|
+
#
|
104
|
+
def abbreviate_permissions(array)
|
105
|
+
inverse = VERBOSE_PERMS.invert
|
106
|
+
if (inverse.keys & array).sort != array.sort then
|
107
|
+
raise "One of your principals contains an invalid permission. Valid permissions are #{inverse.keys.join(', ')}"
|
108
|
+
end
|
109
|
+
array.map { |elt| inverse[elt] }.sort
|
110
|
+
end
|
111
|
+
|
112
|
+
#
|
113
|
+
# Replace a principal with verbose permissions with an equivalent one with abbreviated permissions.
|
114
|
+
#
|
115
|
+
def abbreviate_principal(principal_hash)
|
116
|
+
Hash[principal_hash.map { |k, v| [k, abbreviate_permissions(v)] } ]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
attribute :name, ->{ raise 'Name missing!' }
|
121
|
+
attribute :includes_pattern, '**'
|
122
|
+
attribute :excludes_pattern, ''
|
123
|
+
attribute :repositories
|
124
|
+
attribute :principals, { 'users' => {}, 'groups' => {} }
|
125
|
+
|
126
|
+
def client_principal
|
127
|
+
@client_principal ||= Principal.new(principals['users'], principals['groups'])
|
128
|
+
end
|
129
|
+
|
130
|
+
#
|
131
|
+
# Delete this PermissionTarget from artifactory, suppressing any +ResourceNotFound+
|
132
|
+
# exceptions might occur.
|
133
|
+
#
|
134
|
+
# @return [Boolean]
|
135
|
+
# true if the object was deleted successfully, false otherwise
|
136
|
+
#
|
137
|
+
def delete
|
138
|
+
client.delete(api_path)
|
139
|
+
true
|
140
|
+
rescue Error::HTTPError
|
141
|
+
false
|
142
|
+
end
|
143
|
+
|
144
|
+
#
|
145
|
+
# Save the PermissionTarget to the artifactory server.
|
146
|
+
# See http://bit.ly/1qMOw0L
|
147
|
+
#
|
148
|
+
# @return [Boolean]
|
149
|
+
#
|
150
|
+
def save
|
151
|
+
send("#{:principals}=", client_principal.to_abbreviated)
|
152
|
+
client.put(api_path, to_json, headers)
|
153
|
+
true
|
154
|
+
end
|
155
|
+
|
156
|
+
#
|
157
|
+
# Getter for groups
|
158
|
+
#
|
159
|
+
def groups
|
160
|
+
client_principal.groups
|
161
|
+
end
|
162
|
+
|
163
|
+
#
|
164
|
+
# Setter for groups (groups_hash expected to be friendly)
|
165
|
+
#
|
166
|
+
def groups=(groups_hash)
|
167
|
+
client_principal.groups = Hash[groups_hash.map { |k, v| [k, v.sort] } ]
|
168
|
+
end
|
169
|
+
|
170
|
+
#
|
171
|
+
# Getter for users
|
172
|
+
#
|
173
|
+
def users
|
174
|
+
client_principal.users
|
175
|
+
end
|
176
|
+
|
177
|
+
#
|
178
|
+
# Setter for users (expecting users_hash to be friendly)
|
179
|
+
#
|
180
|
+
def users=(users_hash)
|
181
|
+
client_principal.users = Hash[users_hash.map { |k, v| [k, v.sort] } ]
|
182
|
+
end
|
183
|
+
|
184
|
+
private
|
185
|
+
|
186
|
+
#
|
187
|
+
# The path to this PermissionTarget on the server.
|
188
|
+
#
|
189
|
+
# @return [String]
|
190
|
+
#
|
191
|
+
def api_path
|
192
|
+
@api_path ||= "/api/security/permissions/#{url_safe(name)}"
|
193
|
+
end
|
194
|
+
|
195
|
+
#
|
196
|
+
# The default headers for this object. This includes the +Content-Type+.
|
197
|
+
#
|
198
|
+
# @return [Hash]
|
199
|
+
#
|
200
|
+
def headers
|
201
|
+
@headers ||= {
|
202
|
+
'Content-Type' => 'application/vnd.org.jfrog.artifactory.security.PermissionTarget+json'
|
203
|
+
}
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
@@ -39,7 +39,7 @@ module Artifactory
|
|
39
39
|
#
|
40
40
|
# Find (fetch) a repository by name.
|
41
41
|
#
|
42
|
-
# @example Find a
|
42
|
+
# @example Find a repository by named key
|
43
43
|
# Repository.find(name: 'libs-release-local') #=> #<Resource::Artifact>
|
44
44
|
#
|
45
45
|
# @param [Hash] options
|
data/lib/artifactory/version.rb
CHANGED
@@ -52,6 +52,14 @@ module Artifactory
|
|
52
52
|
it_behaves_like 'an artifact search endpoint', :checksum_search, md5: 'abcd1234'
|
53
53
|
end
|
54
54
|
|
55
|
+
describe '.usage_search' do
|
56
|
+
it_behaves_like 'an artifact search endpoint', :usage_search, notUsedSince: '1414800000'
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '.creation_search' do
|
60
|
+
it_behaves_like 'an artifact search endpoint', :creation_search, from: '1414800000'
|
61
|
+
end
|
62
|
+
|
55
63
|
describe '.versions' do
|
56
64
|
it 'returns an array of versions' do
|
57
65
|
response = described_class.versions
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Artifactory
|
4
|
+
describe Resource::PermissionTarget, :integration do
|
5
|
+
describe '.all' do
|
6
|
+
it 'returns an array of PermissionTarget objects' do
|
7
|
+
results = described_class.all
|
8
|
+
expect(results).to be_a(Array)
|
9
|
+
expect(results.first).to be_a(described_class)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'includes the information from the server' do
|
13
|
+
results = described_class.all
|
14
|
+
anything = results[0]
|
15
|
+
any_remote = results[1]
|
16
|
+
|
17
|
+
expect(anything.name).to eq('Anything')
|
18
|
+
expect(any_remote.name).to eq('Any Remote')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '.find' do
|
23
|
+
it 'finds a permission target by name' do
|
24
|
+
readers = described_class.find('Anything')
|
25
|
+
|
26
|
+
expect(readers).to be_a(described_class)
|
27
|
+
expect(readers.name).to eq('Anything')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#delete' do
|
32
|
+
it 'deletes the permission target from the server' do
|
33
|
+
readers = described_class.find('Anything')
|
34
|
+
expect(readers.delete).to be_truthy
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#save' do
|
39
|
+
it 'saves the permission target to the server' do
|
40
|
+
target = described_class.new(name: 'testing')
|
41
|
+
expect(target.save).to be_truthy
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#users' do
|
46
|
+
it 'displays the users hash with sorted verbose permissions' do
|
47
|
+
target = described_class.find('Any Remote')
|
48
|
+
expect(target.users).to eq( { 'anonymous' => ['deploy', 'read'] } )
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#groups' do
|
53
|
+
it 'displays the groups hash with sorted verbose permissions' do
|
54
|
+
target = described_class.find('Anything')
|
55
|
+
expect(target.groups).to eq( { 'readers' => ['admin', 'read'] } )
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#users=' do
|
60
|
+
it 'sets the users hash' do
|
61
|
+
target = described_class.find('Any Remote')
|
62
|
+
target.users = { 'admins' => ['admin'] }
|
63
|
+
expect(target.users).to eq( { 'admins' => ['admin'] })
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#groups=' do
|
68
|
+
it 'sets the groups hash' do
|
69
|
+
target = described_class.find('Anything')
|
70
|
+
target.groups = { 'deployers' => ['deploy'] }
|
71
|
+
expect(target.groups).to eq( { 'deployers' => ['deploy'] })
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/spec/support/api_server.rb
CHANGED
@@ -10,6 +10,7 @@ module Artifactory
|
|
10
10
|
require_relative 'api_server/build_endpoints'
|
11
11
|
require_relative 'api_server/group_endpoints'
|
12
12
|
require_relative 'api_server/repository_endpoints'
|
13
|
+
require_relative 'api_server/permission_target_endpoints'
|
13
14
|
require_relative 'api_server/status_endpoints'
|
14
15
|
require_relative 'api_server/system_endpoints'
|
15
16
|
require_relative 'api_server/user_endpoints'
|
@@ -17,6 +18,7 @@ module Artifactory
|
|
17
18
|
register APIServer::ArtifactEndpoints
|
18
19
|
register APIServer::BuildEndpoints
|
19
20
|
register APIServer::GroupEndpoints
|
21
|
+
register APIServer::PermissionTargetEndpoints
|
20
22
|
register APIServer::RepositoryEndpoints
|
21
23
|
register APIServer::StatusEndpoints
|
22
24
|
register APIServer::SystemEndpoints
|
@@ -32,6 +32,20 @@ module Artifactory
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
app.get('/api/search/usage') do
|
36
|
+
content_type 'application/vnd.org.jfrog.artifactory.search.ArtifactUsageResult+json'
|
37
|
+
artifacts_for_conditions do
|
38
|
+
params['notUsedSince'] == '1414800000'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
app.get('/api/search/creation') do
|
43
|
+
content_type 'application/vnd.org.jfrog.artifactory.search.ArtifactCreationResult+json'
|
44
|
+
artifacts_for_conditions do
|
45
|
+
params['from'] == '1414800000'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
35
49
|
app.get('/api/search/versions') do
|
36
50
|
content_type 'application/vnd.org.jfrog.artifactory.search.ArtifactVersionsResult+json'
|
37
51
|
JSON.fast_generate(
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Artifactory
|
2
|
+
module APIServer::PermissionTargetEndpoints
|
3
|
+
def self.registered(app)
|
4
|
+
app.get('/api/security/permissions') do
|
5
|
+
content_type 'application/vnd.org.jfrog.artifactory.security.PermissionTargets+json'
|
6
|
+
JSON.fast_generate([
|
7
|
+
{
|
8
|
+
'name' => 'Anything',
|
9
|
+
'uri' => server_url.join('/api/security/permissions/Anything'),
|
10
|
+
},
|
11
|
+
{
|
12
|
+
'name' => 'Any Remote',
|
13
|
+
'uri' => server_url.join('/api/security/permissions/Any%20Remote')
|
14
|
+
}
|
15
|
+
])
|
16
|
+
end
|
17
|
+
|
18
|
+
app.get('/api/security/permissions/Any%20Remote') do
|
19
|
+
content_type 'application/vnd.org.jfrog.artifactory.security.PermissionTargets+json'
|
20
|
+
JSON.fast_generate(
|
21
|
+
'name' => 'Any Remote',
|
22
|
+
'includes_pattern' => nil,
|
23
|
+
'excludes_pattern' => '',
|
24
|
+
'repositories' => ["ANY REMOTE"],
|
25
|
+
'principals' => { 'users' => { 'anonymous' => ['w', 'r'] }, 'groups' => nil }
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
app.get('/api/security/permissions/Anything') do
|
30
|
+
content_type 'application/vnd.org.jfrog.artifactory.security.PermissionTargets+json'
|
31
|
+
JSON.fast_generate(
|
32
|
+
'name' => 'Anything',
|
33
|
+
'includes_pattern' => nil,
|
34
|
+
'excludes_pattern' => '',
|
35
|
+
'repositories' => ["ANY"],
|
36
|
+
'principals' => { 'users' => { 'anonymous' => ['r'] }, 'groups' => { 'readers' => ['r', 'm'] } }
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
app.put('/api/security/permissions/:name') do
|
41
|
+
return 415 unless request.content_type == 'application/vnd.org.jfrog.artifactory.security.PermissionTarget+json'
|
42
|
+
|
43
|
+
# Attempt to parse the response; if this succeeds, all is well...
|
44
|
+
JSON.parse(request.body.read)
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
|
48
|
+
app.delete('/api/security/permissions/:name') do
|
49
|
+
nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -207,6 +207,56 @@ module Artifactory
|
|
207
207
|
end
|
208
208
|
end
|
209
209
|
|
210
|
+
describe '.usage_search' do
|
211
|
+
let(:response) { { 'results' => [] } }
|
212
|
+
|
213
|
+
it 'calls /api/search/usage' do
|
214
|
+
expect(client).to receive(:get).with('/api/search/usage', {}).once
|
215
|
+
described_class.usage_search
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'slices the correct parameters' do
|
219
|
+
expect(client).to receive(:get).with('/api/search/usage',
|
220
|
+
notUsedSince: 1414800000000,
|
221
|
+
createdBefore: 1414871200000,
|
222
|
+
).once
|
223
|
+
described_class.usage_search(
|
224
|
+
notUsedSince: 1414800000000,
|
225
|
+
createdBefore: 1414871200000,
|
226
|
+
fizz: 'foo',
|
227
|
+
)
|
228
|
+
end
|
229
|
+
|
230
|
+
it 'returns an array of objects' do
|
231
|
+
expect(described_class.usage_search).to be_a(Array)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
describe '.creation_search' do
|
236
|
+
let(:response) { { 'results' => [] } }
|
237
|
+
|
238
|
+
it 'calls /api/search/creation' do
|
239
|
+
expect(client).to receive(:get).with('/api/search/creation', {}).once
|
240
|
+
described_class.creation_search
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'slices the correct parameters' do
|
244
|
+
expect(client).to receive(:get).with('/api/search/creation',
|
245
|
+
from: 1414800000000,
|
246
|
+
to: 1414871200000,
|
247
|
+
).once
|
248
|
+
described_class.creation_search(
|
249
|
+
from: 1414800000000,
|
250
|
+
to: 1414871200000,
|
251
|
+
fizz: 'foo',
|
252
|
+
)
|
253
|
+
end
|
254
|
+
|
255
|
+
it 'returns an array of objects' do
|
256
|
+
expect(described_class.creation_search).to be_a(Array)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
210
260
|
describe '.versions' do
|
211
261
|
let(:response) { { 'results' => [] } }
|
212
262
|
|
@@ -0,0 +1,186 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Artifactory
|
4
|
+
describe Resource::PermissionTarget do
|
5
|
+
let(:client) { double(:client) }
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
allow(Artifactory).to receive(:client).and_return(client)
|
9
|
+
allow(client).to receive(:get).and_return(response) if defined?(response)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '.all' do
|
13
|
+
let(:response) do
|
14
|
+
[
|
15
|
+
{ 'uri' => 'a' },
|
16
|
+
{ 'uri' => 'b' },
|
17
|
+
{ 'uri' => 'c' },
|
18
|
+
]
|
19
|
+
end
|
20
|
+
before do
|
21
|
+
allow(described_class).to receive(:from_url).with('a', client: client).and_return('a')
|
22
|
+
allow(described_class).to receive(:from_url).with('b', client: client).and_return('b')
|
23
|
+
allow(described_class).to receive(:from_url).with('c', client: client).and_return('c')
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'gets /api/security/permissions' do
|
27
|
+
expect(client).to receive(:get).with('/api/security/permissions').once
|
28
|
+
described_class.all
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'returns the permissions' do
|
32
|
+
expect(described_class.all).to eq(['a', 'b', 'c'])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '.find' do
|
37
|
+
let(:response) { {} }
|
38
|
+
|
39
|
+
it 'gets /api/security/permissions/#{name}' do
|
40
|
+
expect(client).to receive(:get).with('/api/security/permissions/Any%20Remote').once
|
41
|
+
described_class.find('Any Remote')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '.from_url' do
|
46
|
+
let(:response) { {} }
|
47
|
+
|
48
|
+
it 'constructs a new instance from the result' do
|
49
|
+
expect(described_class).to receive(:from_hash).once
|
50
|
+
described_class.from_url('/api/security/permissions/Any Remote')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '.from_hash' do
|
55
|
+
let(:hash) do
|
56
|
+
{
|
57
|
+
'name' => 'Test Remote',
|
58
|
+
'includes_pattern' => '**',
|
59
|
+
'excludes_pattern' => '',
|
60
|
+
'repositories' => ['ANY REMOTE'],
|
61
|
+
'principals' => { 'users' => { 'anonymous' => ['w', 'r'] }, 'groups' => {} }
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'creates a new instance' do
|
66
|
+
instance = described_class.from_hash(hash)
|
67
|
+
expect(instance.name).to eq('Test Remote')
|
68
|
+
expect(instance.includes_pattern).to eq('**')
|
69
|
+
expect(instance.excludes_pattern).to eq('')
|
70
|
+
expect(instance.repositories).to eq(['ANY REMOTE'])
|
71
|
+
expect(instance.principals).to eq({ 'users' => { 'anonymous' => ['deploy', 'read'] }, 'groups' => {} })
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe Artifactory::Resource::PermissionTarget::Principal do
|
76
|
+
context 'principal object' do
|
77
|
+
users = { 'anonymous_users' => ['admin', 'deploy', 'read'] }
|
78
|
+
groups = { 'anonymous_groups' => ['delete', 'read'] }
|
79
|
+
instance = described_class.new(users, groups)
|
80
|
+
|
81
|
+
it 'has unabbreviated users' do
|
82
|
+
expect(instance.users).to eq( { 'anonymous_users' => ['admin', 'deploy', 'read'] } )
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'has unabbreviated groups' do
|
86
|
+
expect(instance.groups).to eq( { 'anonymous_groups' => ['delete', 'read'] } )
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'abbreviates' do
|
90
|
+
expect(instance.to_abbreviated).to eq( { 'users' => { 'anonymous_users' => ['m', 'r', 'w'] }, 'groups' => { 'anonymous_groups' => ['d', 'r'] } } )
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe '#save' do
|
96
|
+
let(:client) { double }
|
97
|
+
before do
|
98
|
+
subject.client = client
|
99
|
+
subject.name = 'TestRemote'
|
100
|
+
subject.includes_pattern = nil
|
101
|
+
subject.excludes_pattern = ''
|
102
|
+
subject.repositories = ['ANY']
|
103
|
+
subject.principals = {
|
104
|
+
'users' => {
|
105
|
+
'anonymous_users' => ['read']
|
106
|
+
},
|
107
|
+
'groups' => {
|
108
|
+
'anonymous_readers' => ['read']
|
109
|
+
}
|
110
|
+
}
|
111
|
+
allow(described_class).to receive(:find).with(subject.name, client: client).and_return(nil)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'PUTS the permission target to the server' do
|
115
|
+
expect(client).to receive(:put).with("/api/security/permissions/TestRemote",
|
116
|
+
"{\"name\":\"TestRemote\",\"includesPattern\":null,\"excludesPattern\":\"\",\"repositories\":[\"ANY\"],\"principals\":{\"users\":{\"anonymous_users\":[\"r\"]},\"groups\":{\"anonymous_readers\":[\"r\"]}}}",
|
117
|
+
{ "Content-Type" => "application/vnd.org.jfrog.artifactory.security.PermissionTarget+json"})
|
118
|
+
subject.save
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe '#delete' do
|
123
|
+
let(:client) { double }
|
124
|
+
|
125
|
+
it 'sends DELETE to the client' do
|
126
|
+
subject.client = client
|
127
|
+
subject.name = 'My Permissions'
|
128
|
+
|
129
|
+
expect(client).to receive(:delete).with('/api/security/permissions/My%20Permissions')
|
130
|
+
subject.delete
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe 'getters' do
|
135
|
+
let(:client) { double }
|
136
|
+
before do
|
137
|
+
subject.client = client
|
138
|
+
subject.name = 'TestGetters'
|
139
|
+
subject.principals = {
|
140
|
+
'users' => {
|
141
|
+
'anonymous' => ['read']
|
142
|
+
},
|
143
|
+
'groups' => {
|
144
|
+
'readers' => ['read']
|
145
|
+
}
|
146
|
+
}
|
147
|
+
allow(described_class).to receive(:find).with(subject.name, client: client).and_return(nil)
|
148
|
+
end
|
149
|
+
|
150
|
+
it '#users returns the users hash' do
|
151
|
+
expect(subject.users).to eq({ 'anonymous' => ['read'] })
|
152
|
+
end
|
153
|
+
|
154
|
+
it '#groups returns the groups hash' do
|
155
|
+
expect(subject.groups).to eq({ 'readers' => ['read'] })
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe 'setters' do
|
160
|
+
let(:client) { double }
|
161
|
+
before do
|
162
|
+
subject.client = client
|
163
|
+
subject.name = 'TestSetters'
|
164
|
+
subject.principals = {
|
165
|
+
'users' => {
|
166
|
+
'anonymous' => ['read']
|
167
|
+
},
|
168
|
+
'groups' => {
|
169
|
+
'readers' => ['read']
|
170
|
+
}
|
171
|
+
}
|
172
|
+
allow(described_class).to receive(:find).with(subject.name, client: client).and_return(nil)
|
173
|
+
end
|
174
|
+
|
175
|
+
it '#users= sets the users hash' do
|
176
|
+
subject.users = { 'spiders' => [ 'read', 'admin'] }
|
177
|
+
expect(subject.users).to eq({ 'spiders' => ['admin', 'read'] })
|
178
|
+
end
|
179
|
+
|
180
|
+
it '#groups= sets the groups hash' do
|
181
|
+
subject.groups = { 'beatles' => [ 'deploy', 'delete'] }
|
182
|
+
expect(subject.groups).to eq({ 'beatles' => ['delete', 'deploy'] })
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: artifactory
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Seth Vargo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-11-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -67,6 +67,7 @@ files:
|
|
67
67
|
- lib/artifactory/resources/layout.rb
|
68
68
|
- lib/artifactory/resources/ldap_setting.rb
|
69
69
|
- lib/artifactory/resources/mail_server.rb
|
70
|
+
- lib/artifactory/resources/permission_target.rb
|
70
71
|
- lib/artifactory/resources/plugin.rb
|
71
72
|
- lib/artifactory/resources/repository.rb
|
72
73
|
- lib/artifactory/resources/system.rb
|
@@ -81,6 +82,7 @@ files:
|
|
81
82
|
- spec/integration/resources/layout_spec.rb
|
82
83
|
- spec/integration/resources/ldap_setting_spec.rb
|
83
84
|
- spec/integration/resources/mail_server_spec.rb
|
85
|
+
- spec/integration/resources/permission_target_spec.rb
|
84
86
|
- spec/integration/resources/repository_spec.rb
|
85
87
|
- spec/integration/resources/system_spec.rb
|
86
88
|
- spec/integration/resources/url_base_spec.rb
|
@@ -90,6 +92,7 @@ files:
|
|
90
92
|
- spec/support/api_server/artifact_endpoints.rb
|
91
93
|
- spec/support/api_server/build_endpoints.rb
|
92
94
|
- spec/support/api_server/group_endpoints.rb
|
95
|
+
- spec/support/api_server/permission_target_endpoints.rb
|
93
96
|
- spec/support/api_server/repository_endpoints.rb
|
94
97
|
- spec/support/api_server/status_endpoints.rb
|
95
98
|
- spec/support/api_server/system_endpoints.rb
|
@@ -104,6 +107,7 @@ files:
|
|
104
107
|
- spec/unit/resources/layout_spec.rb
|
105
108
|
- spec/unit/resources/ldap_setting_spec.rb
|
106
109
|
- spec/unit/resources/mail_server_spec.rb
|
110
|
+
- spec/unit/resources/permission_target_spec.rb
|
107
111
|
- spec/unit/resources/plugin_spec.rb
|
108
112
|
- spec/unit/resources/repository_spec.rb
|
109
113
|
- spec/unit/resources/system_spec.rb
|
@@ -142,6 +146,7 @@ test_files:
|
|
142
146
|
- spec/integration/resources/layout_spec.rb
|
143
147
|
- spec/integration/resources/ldap_setting_spec.rb
|
144
148
|
- spec/integration/resources/mail_server_spec.rb
|
149
|
+
- spec/integration/resources/permission_target_spec.rb
|
145
150
|
- spec/integration/resources/repository_spec.rb
|
146
151
|
- spec/integration/resources/system_spec.rb
|
147
152
|
- spec/integration/resources/url_base_spec.rb
|
@@ -151,6 +156,7 @@ test_files:
|
|
151
156
|
- spec/support/api_server/artifact_endpoints.rb
|
152
157
|
- spec/support/api_server/build_endpoints.rb
|
153
158
|
- spec/support/api_server/group_endpoints.rb
|
159
|
+
- spec/support/api_server/permission_target_endpoints.rb
|
154
160
|
- spec/support/api_server/repository_endpoints.rb
|
155
161
|
- spec/support/api_server/status_endpoints.rb
|
156
162
|
- spec/support/api_server/system_endpoints.rb
|
@@ -165,6 +171,7 @@ test_files:
|
|
165
171
|
- spec/unit/resources/layout_spec.rb
|
166
172
|
- spec/unit/resources/ldap_setting_spec.rb
|
167
173
|
- spec/unit/resources/mail_server_spec.rb
|
174
|
+
- spec/unit/resources/permission_target_spec.rb
|
168
175
|
- spec/unit/resources/plugin_spec.rb
|
169
176
|
- spec/unit/resources/repository_spec.rb
|
170
177
|
- spec/unit/resources/system_spec.rb
|