artifactory 1.0.0 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ab81695852a0f488f0a8c0aa5ec0c727a08c9e07
4
- data.tar.gz: 77629846e4f5069fe9ed05645deff8fc6e94b0fd
3
+ metadata.gz: 6b8e07b7674ce29c0b313ce8d5be4a551fd007ac
4
+ data.tar.gz: 37eec0ba96fdb294d4e285977cc0b8d8aec7579a
5
5
  SHA512:
6
- metadata.gz: 0f7ec99417175058028512e76512cb8ca8bdaf7812c3daef9445d62138f049d961840ab0a5e0aa4b1057e8646effd3d0996c43dd490add26a5e5b3dc979c0b04
7
- data.tar.gz: 7ae2fedc3094519ccb94858527366980b34c04efa9cc1a99c5bb22285fef259f1b29d0ab23a523de912b7f39ce78bf75aa46002378d161c6df270c24e534e077
6
+ metadata.gz: e2b460025528de4d36e1addf26d2b32656c05bc68656143c06524afe0ac6bcde325ed85c3f1c63035cf76294d99fe41fe2e474e6a1460984e6885a099ee0218e
7
+ data.tar.gz: 6e00717ca7b4a2e90185adc6677eb10fa762c912f9406e5003a15c02be13b44146b901399d8fce08f8ec43a268cc8761fe53abe4bec6ca6f872957794adac792
data/.gitignore CHANGED
@@ -22,5 +22,6 @@ Gemfile.lock
22
22
  bin/
23
23
  coverage/
24
24
  doc/
25
+ pkg/
25
26
  tmp/
26
27
  vendor/
@@ -1,4 +1,4 @@
1
- # Test on modern rubites
1
+ # Test on modern rubies
2
2
  rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
@@ -6,3 +6,15 @@ rvm:
6
6
 
7
7
  # Setup parallel downloaders
8
8
  bundler_args: --jobs 7
9
+
10
+ # Only test master (PRs are still tested)
11
+ branches:
12
+ only:
13
+ - master
14
+
15
+ # Notifications
16
+ notifications:
17
+ hipchat:
18
+ rooms:
19
+ - secure: eUtMt0CeB2bbIcTeQA3rUJsTtBkq/Ng5AnM59NOCzutcPTnNDeM4kNQEfgJ5QEZZkx08IXyiPJ14gEQUaV0bF0s0FLyzFxjlX9p2jem99FmEA404KJ7axoUiGGxgATbq9V7tUOrp1zG+a8xVQTahZASKadPlC9TSRgKqjUL+Dvg= # Release Engineering
20
+ - secure: fQEeBZSIV9mKpM5XeKxmvcgUb19skv3+qW6TiyvuPReB4B/mc5vf3AABWhbdnnHzjsKnq2iQtcppXVG0eJwuRM5D1werMO91zwSRNBU/ClOLHaYBp5l4tVkuHzAd3eo/Z67vxE0BAV9lGWeWv7r3y/BLgJ265nQMyfgZSyz1i44= # Build Statuses
@@ -4,6 +4,11 @@ This file is used to document the changes between releases of the Artifactory
4
4
  Ruby client.
5
5
 
6
6
 
7
- v1.0.0
8
- ------
7
+ v1.1.0 (2014-02-11)
8
+ -------------------
9
+ - Add support for group resources
10
+ - Add support for user resources
11
+
12
+ v1.0.0 (2014-02-10)
13
+ -------------------
9
14
  - Initial release
@@ -16,6 +16,7 @@ module Artifactory
16
16
  autoload :Artifact, 'artifactory/resources/artifact'
17
17
  autoload :Base, 'artifactory/resources/base'
18
18
  autoload :Build, 'artifactory/resources/build'
19
+ autoload :Group, 'artifactory/resources/group'
19
20
  autoload :Plugin, 'artifactory/resources/plugin'
20
21
  autoload :Repository, 'artifactory/resources/repository'
21
22
  autoload :System, 'artifactory/resources/system'
@@ -190,7 +190,7 @@ module Artifactory
190
190
  raise Error::NotFound.new(url: url)
191
191
  when 405
192
192
  raise Error::MethodNotAllowed.new(url: url)
193
- when 500..600
193
+ else
194
194
  raise Error::ConnectionError.new(url: url, body: response.body)
195
195
  end
196
196
  rescue SocketError, Errno::ECONNREFUSED, EOFError
@@ -212,7 +212,9 @@ module Artifactory
212
212
  # the parsed response, as an object
213
213
  #
214
214
  def parse_response(response)
215
- if response.headers['Content-Type'].include?('json')
215
+ content_type = response.headers['Content-Type']
216
+
217
+ if content_type && content_type.include?('json')
216
218
  JSON.parse(response.body)
217
219
  else
218
220
  response.body
@@ -1,3 +1,5 @@
1
+ require 'json'
2
+
1
3
  module Artifactory
2
4
  class Resource::Base
3
5
  class << self
@@ -23,8 +25,13 @@ module Artifactory
23
25
  # @return [Boolean]
24
26
  #
25
27
  def attribute(key, default = nil)
28
+ key = key.to_sym unless key.is_a?(Symbol)
29
+
30
+ # Set the key on the top attributes, mostly for asthetic purposes
31
+ attributes[key] = nil
32
+
26
33
  define_method(key) do
27
- value = instance_variable_get("@#{key}")
34
+ value = attributes[key]
28
35
  return value unless value.nil?
29
36
 
30
37
  if default.nil?
@@ -37,11 +44,11 @@ module Artifactory
37
44
  end
38
45
 
39
46
  define_method("#{key}?") do
40
- !!send(key)
47
+ !!attributes[key]
41
48
  end
42
49
 
43
50
  define_method("#{key}=") do |value|
44
- instance_variable_set("@#{key}", value)
51
+ set(key, value)
45
52
  end
46
53
  end
47
54
 
@@ -96,6 +103,10 @@ module Artifactory
96
103
  def url_safe(value)
97
104
  URI.escape(value.to_s)
98
105
  end
106
+
107
+ def attributes
108
+ @attributes ||= {}
109
+ end
99
110
  end
100
111
 
101
112
  attribute :client, ->{ Artifactory.client }
@@ -104,42 +115,68 @@ module Artifactory
104
115
  # Create a new instance
105
116
  #
106
117
  def initialize(attributes = {})
107
- attributes.each { |key, value| send(:"#{key}=", value) }
118
+ attributes.each do |key, value|
119
+ set(key, value)
120
+ end
121
+ end
122
+
123
+ #
124
+ # The list of attributes for this resource.
125
+ #
126
+ # @return [hash]
127
+ #
128
+ def attributes
129
+ @attributes ||= self.class.attributes.dup
130
+ end
131
+
132
+ #
133
+ # Set a given attribute on this resource.
134
+ #
135
+ # @param [#to_sym] key
136
+ # the attribute to set
137
+ # @param [Object] value
138
+ # the value to set
139
+ #
140
+ # @return [Object]
141
+ # the set value
142
+ #
143
+ def set(key, value)
144
+ attributes[key.to_sym] = value
108
145
  end
109
146
 
110
- # @see {Resource::Base.extract_client!}
147
+ # @see Resource::Base.extract_client!
111
148
  def extract_client!(options)
112
149
  self.class.extract_client!(options)
113
150
  end
114
151
 
115
- # @see {Resource::Base.format_repos!}
152
+ # @see Resource::Base.format_repos!
116
153
  def format_repos!(options)
117
154
  self.class.format_repos!(options)
118
155
  end
119
156
 
120
- # @see {Resource::Base.url_safe}
157
+ # @see Resource::Base.url_safe
121
158
  def url_safe(value)
122
159
  self.class.url_safe(value)
123
160
  end
124
161
 
162
+ # @private
125
163
  def to_s
126
- "#<#{self.class.name}>"
164
+ "#<#{short_classname}>"
127
165
  end
128
166
 
167
+ # @private
129
168
  def inspect
130
- map = instance_variables.map do |k|
131
- unless k == :@client
132
- value = instance_variable_get(k)
133
-
134
- if !value.nil?
135
- "#{k.to_s.gsub(/^@/, '')}: #{value.inspect}"
136
- else
137
- nil
138
- end
139
- end
169
+ list = attributes.collect do |key, value|
170
+ "#{key}: #{value.inspect}" unless key == :client
140
171
  end.compact
141
172
 
142
- "#<#{self.class.name} #{map.join(', ')}>"
173
+ "#<#{short_classname} #{list.join(', ')}>"
174
+ end
175
+
176
+ private
177
+
178
+ def short_classname
179
+ @short_classname ||= self.class.name.split('::').last
143
180
  end
144
181
  end
145
182
  end
@@ -0,0 +1,171 @@
1
+ module Artifactory
2
+ class Resource::Group < Resource::Base
3
+ class << self
4
+ #
5
+ # Get a list of all groups in the system.
6
+ #
7
+ # @param [Hash] options
8
+ # the list of options
9
+ #
10
+ # @option options [Artifactory::Client] :client
11
+ # the client object to make the request with
12
+ #
13
+ # @return [Array<Resource::Group>]
14
+ # the list of groups
15
+ #
16
+ def all(options = {})
17
+ client = extract_client!(options)
18
+ client.get('/api/security/groups').map do |hash|
19
+ from_url(hash['uri'], client: client)
20
+ end
21
+ end
22
+
23
+ #
24
+ # Find (fetch) a group by its name.
25
+ #
26
+ # @example Find a group by its name
27
+ # Group.find('readers') #=> #<Group name: 'readers' ...>
28
+ #
29
+ # @param [String] name
30
+ # the name of the group to find
31
+ # @param [Hash] options
32
+ # the list of options
33
+ #
34
+ # @option options [Artifactory::Client] :client
35
+ # the client object to make the request with
36
+ #
37
+ # @return [Resource::Group, nil]
38
+ # an instance of the group that matches the given name, or +nil+
39
+ # if one does not exist
40
+ #
41
+ def find(name, options = {})
42
+ client = extract_client!(options)
43
+
44
+ response = client.get("/api/security/groups/#{url_safe(name)}")
45
+ from_hash(response, client: client)
46
+ rescue Error::NotFound
47
+ nil
48
+ end
49
+
50
+ #
51
+ # Construct a group from the given URL.
52
+ #
53
+ # @example Create an group object from the given URL
54
+ # Group.from_url('/security/groups/readers') #=> #<Resource::Group>
55
+ #
56
+ # @param [Artifactory::Client] client
57
+ # the client object to make the request with
58
+ # @param [String] url
59
+ # the URL to find the group from
60
+ #
61
+ # @return [Resource::Group]
62
+ #
63
+ def from_url(url, options = {})
64
+ client = extract_client!(options)
65
+ from_hash(client.get(url), client: client)
66
+ end
67
+
68
+ #
69
+ # Create a instance from the given Hash. This method extracts the "safe"
70
+ # information from the hash and adds them to the instance.
71
+ #
72
+ # @example Create a new group from a hash
73
+ # Group.from_hash('realmAttributes' => '...', 'name' => '...')
74
+ #
75
+ # @param [Artifactory::Client] client
76
+ # the client object to make the request with
77
+ # @param [Hash] hash
78
+ # the hash to create the instance from
79
+ #
80
+ # @return [Resource::Group]
81
+ #
82
+ def from_hash(hash, options = {})
83
+ client = extract_client!(options)
84
+
85
+ new.tap do |instance|
86
+ instance.auto_join = hash['autoJoin']
87
+ instance.client = client
88
+ instance.description = hash['description']
89
+ instance.name = hash['name']
90
+ instance.realm = hash['realm']
91
+ instance.realm_attributes = hash['realmAttributes']
92
+ end
93
+ end
94
+ end
95
+
96
+ attribute :auto_join
97
+ attribute :description
98
+ attribute :name, ->{ raise 'Name missing!' }
99
+ attribute :realm
100
+ attribute :realm_attributes
101
+
102
+ #
103
+ # Delete this group from artifactory, suppressing any +ResourceNotFound+
104
+ # exceptions might occur.
105
+ #
106
+ # @return [Boolean]
107
+ # true if the object was deleted successfully, false otherwise
108
+ #
109
+ def delete
110
+ !!client.delete(api_path)
111
+ rescue Error::NotFound
112
+ false
113
+ end
114
+
115
+ #
116
+ # Save the group to the artifactory server.
117
+ #
118
+ # @return [Boolean]
119
+ #
120
+ def save
121
+ client.put(api_path, to_json, headers)
122
+ true
123
+ end
124
+
125
+ #
126
+ # The hash format for this group.
127
+ #
128
+ # @return [Hash]
129
+ #
130
+ def to_hash
131
+ {
132
+ 'autoJoin' => auto_join,
133
+ 'description' => description,
134
+ 'name' => name,
135
+ 'realm' => realm,
136
+ 'realmAttributes' => realm_attributes,
137
+ }
138
+ end
139
+
140
+ #
141
+ # The JSON representation of this resource.
142
+ #
143
+ # @return [String]
144
+ #
145
+ def to_json
146
+ JSON.fast_generate(to_hash)
147
+ end
148
+
149
+ private
150
+
151
+ #
152
+ # The path to this group on the server.
153
+ #
154
+ # @return [String]
155
+ #
156
+ def api_path
157
+ @api_path ||= "/api/security/groups/#{url_safe(name)}"
158
+ end
159
+
160
+ #
161
+ # The default headers for this object. This includes the +Content-Type+.
162
+ #
163
+ # @return [Hash]
164
+ #
165
+ def headers
166
+ @headers ||= {
167
+ 'Content-Type' => 'application/vnd.org.jfrog.artifactory.security.Group+json'
168
+ }
169
+ end
170
+ end
171
+ end
@@ -2,7 +2,16 @@ module Artifactory
2
2
  class Resource::User < Resource::Base
3
3
  class << self
4
4
  #
5
+ # Get a list of all users in the system.
5
6
  #
7
+ # @param [Hash] options
8
+ # the list of options
9
+ #
10
+ # @option options [Artifactory::Client] :client
11
+ # the client object to make the request with
12
+ #
13
+ # @return [Array<Resource::User>]
14
+ # the list of users
6
15
  #
7
16
  def all(options = {})
8
17
  client = extract_client!(options)
@@ -12,19 +21,44 @@ module Artifactory
12
21
  end
13
22
 
14
23
  #
24
+ # Find (fetch) a user by its name.
25
+ #
26
+ # @example Find a user by its name
27
+ # User.find('readers') #=> #<User name: 'readers' ...>
15
28
  #
29
+ # @param [String] name
30
+ # the name of the user to find
31
+ # @param [Hash] options
32
+ # the list of options
16
33
  #
17
- def find(options = {})
18
- client = extract_client!(options)
19
- username = URI.escape(options[:username])
20
- response = client.get("/api/security/users/#{username}")
34
+ # @option options [Artifactory::Client] :client
35
+ # the client object to make the request with
36
+ #
37
+ # @return [Resource::User, nil]
38
+ # an instance of the user that matches the given name, or +nil+
39
+ # if one does not exist
40
+ #
41
+ def find(name, options = {})
42
+ client = extract_client!(options)
43
+
44
+ response = client.get("/api/security/users/#{url_safe(name)}")
21
45
  from_hash(response, client: client)
22
46
  rescue Error::NotFound
23
47
  nil
24
48
  end
25
49
 
26
50
  #
51
+ # Construct a user from the given URL.
52
+ #
53
+ # @example Create an user object from the given URL
54
+ # User.from_url('/security/users/readers') #=> #<Resource::User>
55
+ #
56
+ # @param [Artifactory::Client] client
57
+ # the client object to make the request with
58
+ # @param [String] url
59
+ # the URL to find the user from
27
60
  #
61
+ # @return [Resource::User]
28
62
  #
29
63
  def from_url(url, options = {})
30
64
  client = extract_client!(options)
@@ -32,26 +66,117 @@ module Artifactory
32
66
  end
33
67
 
34
68
  #
69
+ # Create a instance from the given Hash. This method extracts the "safe"
70
+ # information from the hash and adds them to the instance.
35
71
  #
72
+ # @example Create a new user from a hash
73
+ # User.from_hash('realmAttributes' => '...', 'name' => '...')
74
+ #
75
+ # @param [Artifactory::Client] client
76
+ # the client object to make the request with
77
+ # @param [Hash] hash
78
+ # the hash to create the instance from
79
+ #
80
+ # @return [Resource::User]
36
81
  #
37
82
  def from_hash(hash, options = {})
38
83
  client = extract_client!(options)
39
84
 
40
- new(client).tap do |instance|
41
- instance.admin = hash['admin']
42
- instance.email = hash['email']
43
- instance.last_login = Time.parse(hash['lastLoggedIn']) rescue nil
44
- instance.name = hash['name']
45
- instance.realm = hash['realm']
85
+ new.tap do |instance|
86
+ instance.admin = !!hash['admin']
87
+ instance.email = hash['email']
88
+ instance.groups = Array(hash['groups'])
89
+ instance.internal_password_disabled = hash['internalPasswordDisabled']
90
+ instance.last_logged_in = hash['lastLoggedIn']
91
+ instance.name = hash['name']
92
+ instance.password = hash['password']
93
+ instance.profile_updatable = !!hash['profileUpdatable']
94
+ instance.realm = hash['realm']
46
95
  end
47
96
  end
48
97
  end
49
98
 
50
99
  attribute :admin, false
51
100
  attribute :email
52
- attribute :last_login
53
- attribute :name, ->{ raise 'Name missing!' }
54
- attribute :password
101
+ attribute :groups, []
102
+ attribute :internal_password_disabled, false
103
+ attribute :last_logged_in
104
+ attribute :name, -> { raise 'Name missing' }
105
+ attribute :password # write only, never returned
106
+ attribute :profile_updatable, true
55
107
  attribute :realm
108
+
109
+ #
110
+ # Delete this user from artifactory, suppressing any +ResourceNotFound+
111
+ # exceptions might occur.
112
+ #
113
+ # @return [Boolean]
114
+ # true if the object was deleted successfully, false otherwise
115
+ #
116
+ def delete
117
+ !!client.delete(api_path)
118
+ rescue Error::NotFound
119
+ false
120
+ end
121
+
122
+ #
123
+ # Save the user to the artifactory server.
124
+ #
125
+ # @return [Boolean]
126
+ #
127
+ def save
128
+ client.put(api_path, to_json, headers)
129
+ true
130
+ end
131
+
132
+ #
133
+ # The hash format for this user.
134
+ #
135
+ # @return [Hash]
136
+ #
137
+ def to_hash
138
+ {
139
+ 'admin' => admin,
140
+ 'email' => email,
141
+ 'groups' => groups,
142
+ 'internalPasswordDisabled' => internal_password_disabled,
143
+ 'lastLoggedIn' => last_logged_in,
144
+ 'name' => name,
145
+ 'password' => password,
146
+ 'profileUpdatable' => profile_updatable,
147
+ 'realm' => realm,
148
+ }
149
+ end
150
+
151
+ #
152
+ # The JSON representation of this resource.
153
+ #
154
+ # @return [String]
155
+ #
156
+ def to_json
157
+ JSON.fast_generate(to_hash)
158
+ end
159
+
160
+ private
161
+
162
+ #
163
+ # The path to this user on the server.
164
+ #
165
+ # @return [String]
166
+ #
167
+ def api_path
168
+ @api_path ||= "/api/security/users/#{url_safe(name)}"
169
+ end
170
+
171
+ #
172
+ # The default headers for this object. This includes the +Content-Type+.
173
+ #
174
+ # @return [Hash]
175
+ #
176
+ def headers
177
+ @headers ||= {
178
+ 'Content-Type' => 'application/vnd.org.jfrog.artifactory.security.User+json'
179
+ }
180
+ end
56
181
  end
57
182
  end
@@ -1,3 +1,3 @@
1
1
  module Artifactory
2
- VERSION = '1.0.0'
2
+ VERSION = '1.1.0'
3
3
  end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ module Artifactory
4
+ describe Resource::Group, :integration do
5
+ describe '.all' do
6
+ it 'returns an array of group 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
+ readers = results[0]
15
+ leads = results[1]
16
+
17
+ expect(readers.name).to eq('readers')
18
+ expect(leads.name).to eq('tech-leads')
19
+ end
20
+ end
21
+
22
+ describe '.find' do
23
+ it 'finds a group by name' do
24
+ readers = described_class.find('readers')
25
+
26
+ expect(readers).to be_a(described_class)
27
+ expect(readers.name).to eq('readers')
28
+ end
29
+ end
30
+
31
+ describe '#delete' do
32
+ it 'deletes the group from the server' do
33
+ readers = described_class.find('readers')
34
+ expect(readers.delete).to be_true
35
+ end
36
+ end
37
+
38
+ describe '#save' do
39
+ it 'saves the group to the server' do
40
+ group = described_class.new(name: 'testing')
41
+ expect(group.save).to be_true
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ module Artifactory
4
+ describe Resource::User, :integration do
5
+ describe '.all' do
6
+ it 'returns an array of user 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
+ seth = results[0]
15
+ yvonne = results[1]
16
+
17
+ expect(seth.name).to eq('sethvargo')
18
+ expect(yvonne.name).to eq('yzl')
19
+ end
20
+ end
21
+
22
+ describe '.find' do
23
+ it 'finds a user by name' do
24
+ seth = described_class.find('sethvargo')
25
+
26
+ expect(seth).to be_a(described_class)
27
+ expect(seth.name).to eq('sethvargo')
28
+ end
29
+ end
30
+
31
+ describe '#delete' do
32
+ it 'deletes the user from the server' do
33
+ sethvargo = described_class.find('sethvargo')
34
+ expect(sethvargo.delete).to be_true
35
+ end
36
+ end
37
+
38
+ describe '#save' do
39
+ it 'saves the user to the server' do
40
+ user = described_class.new(name: 'schisamo')
41
+ expect(user.save).to be_true
42
+ end
43
+ end
44
+ end
45
+ end
@@ -8,15 +8,19 @@ module Artifactory
8
8
  class APIServer < Sinatra::Base
9
9
  require_relative 'api_server/artifact_endpoints'
10
10
  require_relative 'api_server/build_endpoints'
11
+ require_relative 'api_server/group_endpoints'
11
12
  require_relative 'api_server/repository_endpoints'
12
13
  require_relative 'api_server/status_endpoints'
13
14
  require_relative 'api_server/system_endpoints'
15
+ require_relative 'api_server/user_endpoints'
14
16
 
15
17
  register APIServer::ArtifactEndpoints
16
18
  register APIServer::BuildEndpoints
19
+ register APIServer::GroupEndpoints
17
20
  register APIServer::RepositoryEndpoints
18
21
  register APIServer::StatusEndpoints
19
22
  register APIServer::SystemEndpoints
23
+ register APIServer::UserEndpoints
20
24
 
21
25
  private
22
26
 
@@ -0,0 +1,53 @@
1
+ module Artifactory
2
+ module APIServer::GroupEndpoints
3
+ def self.registered(app)
4
+ app.get('/api/security/groups') do
5
+ content_type 'application/vnd.org.jfrog.artifactory.security.Groups+json'
6
+ JSON.fast_generate([
7
+ {
8
+ 'name' => 'readers',
9
+ 'uri' => server_url.join('/api/security/groups/readers'),
10
+ },
11
+ {
12
+ 'name' => 'tech-leads',
13
+ 'uri' => server_url.join('/api/security/groups/tech-leads')
14
+ }
15
+ ])
16
+ end
17
+
18
+ app.get('/api/security/groups/readers') do
19
+ content_type 'application/vnd.org.jfrog.artifactory.security.Group+json'
20
+ JSON.fast_generate(
21
+ 'name' => 'readers',
22
+ 'description' => 'This list of read-only users',
23
+ 'autoJoin' => true,
24
+ 'realm' => 'artifactory',
25
+ 'realmAttributes' => nil,
26
+ )
27
+ end
28
+
29
+ app.get('/api/security/groups/tech-leads') do
30
+ content_type 'application/vnd.org.jfrog.artifactory.security.Group+json'
31
+ JSON.fast_generate(
32
+ 'name' => 'tech-leads',
33
+ 'description' => 'This development leads group',
34
+ 'autoJoin' => false,
35
+ 'realm' => 'artifactory',
36
+ 'realmAttributes' => nil,
37
+ )
38
+ end
39
+
40
+ app.put('/api/security/groups/:name') do
41
+ return 415 unless request.content_type == 'application/vnd.org.jfrog.artifactory.security.Group+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/groups/:name') do
49
+ nil
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,59 @@
1
+ module Artifactory
2
+ module APIServer::UserEndpoints
3
+ def self.registered(app)
4
+ app.get('/api/security/users') do
5
+ content_type 'application/vnd.org.jfrog.artifactory.security.Users+json'
6
+ JSON.fast_generate([
7
+ {
8
+ 'name' => 'sethvargo',
9
+ 'uri' => server_url.join('/api/security/users/sethvargo'),
10
+ },
11
+ {
12
+ 'name' => 'yzl',
13
+ 'uri' => server_url.join('/api/security/users/yzl')
14
+ }
15
+ ])
16
+ end
17
+
18
+ app.get('/api/security/users/sethvargo') do
19
+ content_type 'application/vnd.org.jfrog.artifactory.security.User+json'
20
+ JSON.fast_generate(
21
+ 'admin' => false,
22
+ 'email' => 'sethvargo@gmail.com',
23
+ 'groups' => ['admin'],
24
+ 'internalPasswordDisabled' => true,
25
+ 'lastLoggedIn' => nil,
26
+ 'name' => 'sethvargo',
27
+ 'profileUpdatable' => true,
28
+ 'realm' => 'artifactory',
29
+ )
30
+ end
31
+
32
+ app.get('/api/security/users/yzl') do
33
+ content_type 'application/vnd.org.jfrog.artifactory.security.User+json'
34
+ JSON.fast_generate(
35
+ 'admin' => true,
36
+ 'email' => 'yvonne@getchef.com',
37
+ 'groups' => ['admin'],
38
+ 'internalPasswordDisabled' => true,
39
+ 'lastLoggedIn' => nil,
40
+ 'name' => 'yzl',
41
+ 'profileUpdatable' => true,
42
+ 'realm' => 'crowd',
43
+ )
44
+ end
45
+
46
+ app.put('/api/security/users/:name') do
47
+ return 415 unless request.content_type == 'application/vnd.org.jfrog.artifactory.security.User+json'
48
+
49
+ # Attempt to parse the response; if this succeeds, all is well...
50
+ JSON.parse(request.body.read)
51
+ nil
52
+ end
53
+
54
+ app.delete('/api/security/users/:name') do
55
+ nil
56
+ end
57
+ end
58
+ end
59
+ end
@@ -126,14 +126,17 @@ module Artifactory
126
126
 
127
127
  describe '#to_s' do
128
128
  it 'returns the name of the class' do
129
- expect(subject.to_s).to eq('#<Artifactory::Resource::Base>')
129
+ expect(subject.to_s).to eq('#<Base>')
130
130
  end
131
131
  end
132
132
 
133
133
  describe '#inspect' do
134
- it 'includes all the instance variables' do
135
- subject.instance_variable_set(:@foo, 'bar')
136
- expect(subject.inspect).to eq(%q|#<Artifactory::Resource::Base foo: "bar">|)
134
+ it 'includes all the attributes' do
135
+ subject.stub(:attributes) do
136
+ { foo: 'bar' }
137
+ end
138
+
139
+ expect(subject.inspect).to eq(%q|#<Base foo: "bar">|)
137
140
  end
138
141
  end
139
142
  end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ module Artifactory
4
+ describe Resource::Group do
5
+ let(:client) { double(:client) }
6
+
7
+ before(:each) do
8
+ Artifactory.stub(:client).and_return(client)
9
+ client.stub(: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
+ described_class.stub(:from_url).with('a', client: client).and_return('a')
22
+ described_class.stub(:from_url).with('b', client: client).and_return('b')
23
+ described_class.stub(:from_url).with('c', client: client).and_return('c')
24
+ end
25
+
26
+ it 'gets /api/security/groups' do
27
+ expect(client).to receive(:get).with('/api/security/groups').once
28
+ described_class.all
29
+ end
30
+
31
+ it 'returns the groups' 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/repositories/#{name}' do
40
+ expect(client).to receive(:get).with('/api/security/groups/readers').once
41
+ described_class.find('readers')
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/groups/readers')
51
+ end
52
+ end
53
+
54
+ describe '.from_hash' do
55
+ let(:hash) do
56
+ {
57
+ 'name' => 'readers',
58
+ 'description' => 'This list of read-only users',
59
+ 'autoJoin' => true,
60
+ 'realm' => 'artifactory',
61
+ 'realmAttributes' => nil,
62
+ }
63
+ end
64
+
65
+ it 'creates a new instnace' do
66
+ instance = described_class.from_hash(hash)
67
+ expect(instance.name).to eq('readers')
68
+ expect(instance.description).to eq('This list of read-only users')
69
+ expect(instance.auto_join).to be_true
70
+ expect(instance.realm).to eq('artifactory')
71
+ expect(instance.realm_attributes).to be_nil
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,82 @@
1
+ require 'spec_helper'
2
+
3
+ module Artifactory
4
+ describe Resource::User do
5
+ let(:client) { double(:client) }
6
+
7
+ before(:each) do
8
+ Artifactory.stub(:client).and_return(client)
9
+ client.stub(: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
+ described_class.stub(:from_url).with('a', client: client).and_return('a')
22
+ described_class.stub(:from_url).with('b', client: client).and_return('b')
23
+ described_class.stub(:from_url).with('c', client: client).and_return('c')
24
+ end
25
+
26
+ it 'gets /api/security/users' do
27
+ expect(client).to receive(:get).with('/api/security/users').once
28
+ described_class.all
29
+ end
30
+
31
+ it 'returns the users' 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/repositories/#{name}' do
40
+ expect(client).to receive(:get).with('/api/security/users/readers').once
41
+ described_class.find('readers')
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/users/readers')
51
+ end
52
+ end
53
+
54
+ describe '.from_hash' do
55
+ let(:hash) do
56
+ {
57
+ 'admin' => false,
58
+ 'email' => 'admin@example.com',
59
+ 'groups' => ['admin'],
60
+ 'internalPasswordDisabled' => true,
61
+ 'lastLoggedIn' => nil,
62
+ 'name' => 'admin',
63
+ 'profileUpdatable' => true,
64
+ 'realm' => 'artifactory',
65
+ }
66
+ end
67
+
68
+ it 'creates a new instnace' do
69
+ instance = described_class.from_hash(hash)
70
+ expect(instance.admin).to be_false
71
+ expect(instance.email).to eq('admin@example.com')
72
+ expect(instance.groups).to eq(['admin'])
73
+ expect(instance.internal_password_disabled).to be_true
74
+ expect(instance.last_logged_in).to be_nil
75
+ expect(instance.name).to eq('admin')
76
+ expect(instance.password).to be_nil
77
+ expect(instance.profile_updatable).to be_true
78
+ expect(instance.realm).to eq('artifactory')
79
+ end
80
+ end
81
+ end
82
+ 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: 1.0.0
4
+ version: 1.1.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-02-10 00:00:00.000000000 Z
11
+ date: 2014-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httpclient
@@ -90,6 +90,7 @@ files:
90
90
  - lib/artifactory/resources/artifact.rb
91
91
  - lib/artifactory/resources/base.rb
92
92
  - lib/artifactory/resources/build.rb
93
+ - lib/artifactory/resources/group.rb
93
94
  - lib/artifactory/resources/plugin.rb
94
95
  - lib/artifactory/resources/repository.rb
95
96
  - lib/artifactory/resources/system.rb
@@ -99,23 +100,29 @@ files:
99
100
  - locales/en.yml
100
101
  - spec/integration/resources/artifact_spec.rb
101
102
  - spec/integration/resources/build_spec.rb
103
+ - spec/integration/resources/group_spec.rb
102
104
  - spec/integration/resources/repository_spec.rb
103
105
  - spec/integration/resources/system_spec.rb
106
+ - spec/integration/resources/user_spec.rb
104
107
  - spec/spec_helper.rb
105
108
  - spec/support/api_server.rb
106
109
  - spec/support/api_server/artifact_endpoints.rb
107
110
  - spec/support/api_server/build_endpoints.rb
111
+ - spec/support/api_server/group_endpoints.rb
108
112
  - spec/support/api_server/repository_endpoints.rb
109
113
  - spec/support/api_server/status_endpoints.rb
110
114
  - spec/support/api_server/system_endpoints.rb
115
+ - spec/support/api_server/user_endpoints.rb
111
116
  - spec/unit/artifactory_spec.rb
112
117
  - spec/unit/client_spec.rb
113
118
  - spec/unit/resources/artifact_spec.rb
114
119
  - spec/unit/resources/base_spec.rb
115
120
  - spec/unit/resources/build_spec.rb
121
+ - spec/unit/resources/group_spec.rb
116
122
  - spec/unit/resources/plugin_spec.rb
117
123
  - spec/unit/resources/repository_spec.rb
118
124
  - spec/unit/resources/system_spec.rb
125
+ - spec/unit/resources/user_spec.rb
119
126
  homepage: https://github.com/opscode/artifactory-client
120
127
  licenses:
121
128
  - Apache 2.0
@@ -144,21 +151,27 @@ summary: Artifactory is a simple, lightweight Ruby client for interacting with t
144
151
  test_files:
145
152
  - spec/integration/resources/artifact_spec.rb
146
153
  - spec/integration/resources/build_spec.rb
154
+ - spec/integration/resources/group_spec.rb
147
155
  - spec/integration/resources/repository_spec.rb
148
156
  - spec/integration/resources/system_spec.rb
157
+ - spec/integration/resources/user_spec.rb
149
158
  - spec/spec_helper.rb
150
159
  - spec/support/api_server.rb
151
160
  - spec/support/api_server/artifact_endpoints.rb
152
161
  - spec/support/api_server/build_endpoints.rb
162
+ - spec/support/api_server/group_endpoints.rb
153
163
  - spec/support/api_server/repository_endpoints.rb
154
164
  - spec/support/api_server/status_endpoints.rb
155
165
  - spec/support/api_server/system_endpoints.rb
166
+ - spec/support/api_server/user_endpoints.rb
156
167
  - spec/unit/artifactory_spec.rb
157
168
  - spec/unit/client_spec.rb
158
169
  - spec/unit/resources/artifact_spec.rb
159
170
  - spec/unit/resources/base_spec.rb
160
171
  - spec/unit/resources/build_spec.rb
172
+ - spec/unit/resources/group_spec.rb
161
173
  - spec/unit/resources/plugin_spec.rb
162
174
  - spec/unit/resources/repository_spec.rb
163
175
  - spec/unit/resources/system_spec.rb
176
+ - spec/unit/resources/user_spec.rb
164
177
  has_rdoc: