conjur-api 2.0.1 → 2.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.
data/Gemfile CHANGED
@@ -3,8 +3,6 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in conjur-api.gemspec
4
4
  gemspec
5
5
 
6
- gem 'slosilo', :git => 'https://github.com/inscitiv/slosilo.git'
7
-
8
6
  group :test do
9
7
  gem 'fuubar'
10
8
  end
@@ -16,7 +16,6 @@ Gem::Specification.new do |gem|
16
16
  gem.version = Conjur::API::VERSION
17
17
 
18
18
  gem.add_dependency 'rest-client'
19
- gem.add_dependency 'slosilo'
20
19
  gem.add_dependency 'activesupport'
21
20
 
22
21
  gem.add_development_dependency 'rake'
@@ -1,5 +1,5 @@
1
1
  module Conjur
2
2
  class API
3
- VERSION = "2.0.1"
3
+ VERSION = "2.1.0"
4
4
  end
5
5
  end
@@ -2,7 +2,7 @@ module Conjur
2
2
  module ActsAsResource
3
3
  def resource
4
4
  require 'conjur/resource'
5
- Conjur::Resource.new("#{Conjur::Authz::API.host}/#{path_escape resource_kind}/#{path_escape resource_id}", self.options)
5
+ Conjur::Resource.new(Conjur::Authz::API.host, self.options)[[ Conjur.account, 'resources', path_escape(resource_kind), path_escape(resource_id) ].join('/')]
6
6
  end
7
7
 
8
8
  def resource_kind
@@ -5,9 +5,5 @@ module Conjur
5
5
  include ActsAsRole
6
6
  end
7
7
  end
8
-
9
- def roleid
10
- id
11
- end
12
8
  end
13
9
  end
@@ -1,14 +1,5 @@
1
1
  require 'conjur/user'
2
2
 
3
- # Fails for the CLI client because it has no slosilo key
4
- #require 'rest-client'
5
-
6
- #RestClient.add_before_execution_proc do |req, params|
7
- # require 'slosilo'
8
- # req.extend Slosilo::HTTPRequest
9
- # req.keyname = :authn
10
- #end
11
-
12
3
  module Conjur
13
4
  class API
14
5
  class << self
@@ -34,19 +25,7 @@ module Conjur
34
25
  if Conjur.log
35
26
  Conjur.log << "Authenticating #{username}\n"
36
27
  end
37
- JSON::parse(RestClient::Resource.new(Conjur::Authn::API.host)["users/#{path_escape username}/authenticate"].post password, content_type: 'text/plain').tap do |token|
38
- raise InvalidToken.new unless token_valid?(token)
39
- end
40
- end
41
-
42
- def token_valid? token
43
- require 'slosilo'
44
- key = Slosilo[:authn]
45
- if key
46
- key.token_valid? token
47
- else
48
- raise KeyError, "authn key not found in Slosilo keystore"
49
- end
28
+ JSON::parse(RestClient::Resource.new(Conjur::Authn::API.host)["users/#{path_escape username}/authenticate"].post password, content_type: 'text/plain')
50
29
  end
51
30
  end
52
31
 
@@ -5,7 +5,7 @@ module Conjur
5
5
  class << self
6
6
  def enroll_host(url)
7
7
  if Conjur.log
8
- logger << "Enrolling host with URL #{url}"
8
+ Conjur.log << "Enrolling host with URL #{url}\n"
9
9
  end
10
10
  require 'uri'
11
11
  url = URI.parse(url) if url.is_a?(String)
@@ -2,8 +2,16 @@ require 'conjur/resource'
2
2
 
3
3
  module Conjur
4
4
  class API
5
- def resource kind, identifier
6
- Resource.new("#{Conjur::Authz::API.host}/#{kind}/#{path_escape identifier}", credentials)
5
+ def create_resource(identifier, options = {})
6
+ resource(identifier).tap do |r|
7
+ r.create(options)
8
+ end
9
+ end
10
+
11
+ def resource identifier
12
+ paths = path_escape(identifier).split(':')
13
+ path = [ paths[0], 'resources', paths[1], paths[2..-1].join(':') ].flatten.join('/')
14
+ Resource.new(Conjur::Authz::API.host, credentials)[path]
7
15
  end
8
16
  end
9
17
  end
@@ -3,15 +3,13 @@ require 'conjur/role'
3
3
  module Conjur
4
4
  class API
5
5
  def create_role(role, options = {})
6
- log do |logger|
7
- logger << "Creating role #{account}/#{role}"
6
+ role(role).tap do |r|
7
+ r.create(options)
8
8
  end
9
- RestClient::Resource.new(Conjur::Authz::API.host, credentials)["roles/#{path_escape role}"].put(options)
10
- role(role)
11
9
  end
12
10
 
13
11
  def role role
14
- Role.new(Conjur::Authz::API.host, credentials)["roles/#{path_escape role}"]
12
+ Role.new(Conjur::Authz::API.host, credentials)[self.class.parse_role_id(role).join('/')]
15
13
  end
16
14
  end
17
15
  end
@@ -3,6 +3,7 @@ require 'json'
3
3
 
4
4
  require 'conjur/exists'
5
5
  require 'conjur/has_attributes'
6
+ require 'conjur/path_based'
6
7
  require 'conjur/escape'
7
8
  require 'conjur/log'
8
9
  require 'conjur/log_source'
@@ -16,6 +17,12 @@ module Conjur
16
17
  include StandardMethods
17
18
 
18
19
  class << self
20
+ # Parse a role id into [ account, 'roles', kind, id ]
21
+ def parse_role_id(id)
22
+ paths = path_escape(id).split(':')
23
+ [ paths[0], 'roles', paths[1], paths[2..-1].join(':') ]
24
+ end
25
+
19
26
  def new_from_key(username, api_key)
20
27
  self.new username, api_key, nil
21
28
  end
@@ -16,7 +16,7 @@ module Conjur
16
16
  def stack
17
17
  ENV['CONJUR_STACK'] || case env
18
18
  when "production"
19
- "v2"
19
+ "v21"
20
20
  else
21
21
  env
22
22
  end
@@ -2,17 +2,20 @@ module Conjur
2
2
  module Escape
3
3
  module ClassMethods
4
4
  def path_escape(str)
5
- return "false" unless str
6
- str = str.id if str.respond_to?(:id)
7
- require 'uri'
8
- URI.escape(str.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
5
+ path_or_query_escape str
9
6
  end
10
7
 
11
8
  def query_escape(str)
9
+ path_or_query_escape str
10
+ end
11
+
12
+ def path_or_query_escape(str)
12
13
  return "false" unless str
13
14
  str = str.id if str.respond_to?(:id)
15
+ # Leave colons and forward slashes alone
14
16
  require 'uri'
15
- URI.escape(str.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
17
+ pattern = URI::PATTERN::UNRESERVED + ":\\/@"
18
+ URI.escape(str.to_s, Regexp.new("[^#{pattern}]"))
16
19
  end
17
20
  end
18
21
 
@@ -7,7 +7,7 @@ module Conjur
7
7
  include ActsAsUser
8
8
 
9
9
  def roleid
10
- "host-#{id}"
10
+ "host:#{id}"
11
11
  end
12
12
 
13
13
  def enrollment_url
@@ -0,0 +1,19 @@
1
+ module Conjur
2
+ module PathBased
3
+ def account
4
+ match_path(0..0)
5
+ end
6
+
7
+ def kind
8
+ match_path(2..2)
9
+ end
10
+
11
+ protected
12
+
13
+ def match_path(range)
14
+ require 'uri'
15
+ tokens = URI.parse(self.url).path[1..-1].split('/')[range]
16
+ tokens.map{|t| URI.unescape(t)}.join('/')
17
+ end
18
+ end
19
+ end
@@ -2,18 +2,15 @@ module Conjur
2
2
  class Resource < RestClient::Resource
3
3
  include Exists
4
4
  include HasAttributes
5
+ include PathBased
5
6
 
6
- def kind
7
- match_path(0..0)
8
- end
9
-
10
7
  def identifier
11
- match_path(1..-1)
8
+ match_path(3..-1)
12
9
  end
13
10
 
14
11
  def create(options = {})
15
12
  log do |logger|
16
- logger << "Creating resource #{kind} : #{identifier}"
13
+ logger << "Creating resource #{kind}:#{identifier}"
17
14
  unless options.empty?
18
15
  logger << " with options #{options.to_json}"
19
16
  end
@@ -23,7 +20,7 @@ module Conjur
23
20
 
24
21
  # Lists roles that have a specified permission on the resource.
25
22
  def permitted_roles(permission, options = {})
26
- JSON.parse RestClient::Resource.new(Conjur::Authz::API.host, self.options)["roles/allowed_to/#{permission}/#{path_escape kind}/#{path_escape identifier}"].get(options)
23
+ JSON.parse RestClient::Resource.new(Conjur::Authz::API.host, self.options)["#{account}/roles/allowed_to/#{permission}/#{path_escape kind}/#{path_escape identifier}"].get(options)
27
24
  end
28
25
 
29
26
  # Changes the owner of a resource
@@ -71,11 +68,5 @@ module Conjur
71
68
  def eachable(item)
72
69
  item.respond_to?(:each) ? item : [ item ]
73
70
  end
74
-
75
- def match_path(range)
76
- require 'uri'
77
- tokens = URI.parse(self.url).path[1..-1].split('/')[range]
78
- tokens.map{|t| URI.unescape(t)}.join('/')
79
- end
80
71
  end
81
72
  end
@@ -1,11 +1,17 @@
1
1
  module Conjur
2
2
  class Role < RestClient::Resource
3
3
  include Exists
4
- include HasId
4
+ include PathBased
5
+
6
+ def identifier
7
+ match_path(3..-1)
8
+ end
9
+
10
+ alias id identifier
5
11
 
6
12
  def create(options = {})
7
13
  log do |logger|
8
- logger << "Creating role #{id}"
14
+ logger << "Creating role #{kind}:#{identifier}"
9
15
  unless options.empty?
10
16
  logger << " with options #{options.to_json}"
11
17
  end
@@ -14,14 +20,14 @@ module Conjur
14
20
  end
15
21
 
16
22
  def all(options = {})
17
- JSON.parse(self["all"].get(options)).collect do |id|
18
- Role.new("#{Conjur::Authz::API.host}/roles/#{path_escape id}", self.options)
23
+ JSON.parse(self["?all"].get(options)).collect do |id|
24
+ Role.new(Conjur::Authz::API.host, self.options)[Conjur::API.parse_role_id(id).join('/')]
19
25
  end
20
26
  end
21
27
 
22
28
  def grant_to(member, admin_option = false, options = {})
23
29
  log do |logger|
24
- logger << "Granting role #{id} to #{member}"
30
+ logger << "Granting role #{identifier} to #{member}"
25
31
  if admin_option
26
32
  logger << " with admin option"
27
33
  end
@@ -29,24 +35,30 @@ module Conjur
29
35
  logger << " and extended options #{options.to_json}"
30
36
  end
31
37
  end
32
- self["members/#{path_escape member}?admin_option=#{query_escape admin_option}"].put(options)
38
+ self["?members&member=#{query_escape member}&admin_option=#{query_escape admin_option}"].put(options)
33
39
  end
34
40
 
35
41
  def revoke_from(member, options = {})
36
42
  log do |logger|
37
- logger << "Revoking role #{id} from #{member}"
43
+ logger << "Revoking role #{identifier} from #{member}"
38
44
  unless options.empty?
39
45
  logger << " with options #{options.to_json}"
40
46
  end
41
47
  end
42
- self["members/#{path_escape member}"].delete(options)
48
+ self["?members&member=#{query_escape member}"].delete(options)
43
49
  end
44
50
 
45
51
  def permitted?(resource_kind, resource_id, privilege, options = {})
46
- self["permitted?resource_kind=#{query_escape resource_kind}&resource_id=#{query_escape resource_id}&privilege=#{query_escape privilege}"].get(options)
52
+ self["?check&resource_kind=#{query_escape resource_kind}&resource_id=#{query_escape resource_id}&privilege=#{query_escape privilege}"].get(options)
47
53
  true
48
54
  rescue RestClient::ResourceNotFound
49
55
  false
50
56
  end
57
+
58
+ def members
59
+ JSON.parse(self["?members"].get(options)).collect do |id|
60
+ Role.new(Conjur::Authz::API.host, self.options)[Conjur::API.parse_role_id(id).join('/')]
61
+ end
62
+ end
51
63
  end
52
64
  end
@@ -9,5 +9,9 @@ module Conjur
9
9
  include ActsAsUser
10
10
 
11
11
  alias login id
12
+
13
+ def roleid
14
+ [ 'user', id ].join(':')
15
+ end
12
16
  end
13
17
  end
@@ -66,16 +66,6 @@ describe Conjur::API do
66
66
  it_should_behave_like "API endpoint"
67
67
  end
68
68
  end
69
- context ".class" do
70
- describe '#token_valid?' do
71
- subject { Conjur::API }
72
- it "raises KeyError when there's no authn key in the db" do
73
- require 'slosilo'
74
- Slosilo.stub(:[]).with(:authn).and_return nil
75
- expect { subject.token_valid? :whatever }.to raise_error(KeyError)
76
- end
77
- end
78
- end
79
69
  context "credential handling" do
80
70
  let(:login) { "bob" }
81
71
  let(:token) { { 'data' => login, 'timestamp' => (Time.now + elapsed ).to_s } }
@@ -3,11 +3,12 @@ require 'spec_helper'
3
3
  require 'conjur/api'
4
4
 
5
5
  describe Conjur::Resource do
6
+ let(:account) { "the-account" }
6
7
  let(:uuid) { "ddd1f59a-494d-48fb-b045-0374c4a6eef9" }
7
8
 
8
9
  context "identifier" do
9
10
  include Conjur::Escape
10
- let(:resource) { Conjur::Resource.new("#{Conjur::Authz::API.host}/#{kind}/#{path_escape identifier}") }
11
+ let(:resource) { Conjur::Resource.new("#{Conjur::Authz::API.host}/#{account}/resources/#{kind}/#{path_escape identifier}") }
11
12
 
12
13
  context "Object with an #id" do
13
14
  let(:kind) { "host" }
@@ -19,7 +20,7 @@ describe Conjur::Resource do
19
20
  end
20
21
  end
21
22
 
22
- [ [ "foo", "bar/baz" ], [ "f:o", "bar" ], [ "@f", "bar.baz" ], [ "@f", "bar baz" ], [ "@f", "bar?baz" ] ].each do |p|
23
+ [ [ "foo", "bar/baz" ], [ "f:o", "bar" ], [ "@f", "bar.baz" ], [ "@f", "bar baz" ], [ "@f", "@:bar/baz" ] ].each do |p|
23
24
  context "of /#{p[0]}/#{p[1]}" do
24
25
  let(:kind) { p[0] }
25
26
  let(:identifier) { p[1] }
@@ -4,20 +4,25 @@ require 'conjur/api'
4
4
 
5
5
  shared_examples_for "properties" do
6
6
  subject { role }
7
+ its(:kind) { should == kind }
7
8
  its(:id) { should == id }
8
9
  end
9
10
 
10
11
  describe Conjur::Role do
12
+ let(:account) { "the-account" }
11
13
  context "#new" do
12
- let(:url) { "#{Conjur::Authz::API.host}/roles/#{id}" }
13
- let(:credentials) { mock(:credentials) }
14
- let(:role) { Conjur::Role.new(url, credentials) }
14
+ let(:kind) { "test" }
15
+ let(:role) { Conjur::API.new_from_key('the-user', 'the-key').role([ account, kind, id ].join(":")) }
16
+ let(:token) { 'the-token' }
17
+ before {
18
+ Conjur::TokenCache.stub(:fetch).and_return token
19
+ }
15
20
  context "with plain id" do
16
21
  let(:id) { "foo" }
17
22
  it_should_behave_like "properties"
18
23
  end
19
24
  context "with more complex id" do
20
- let(:id) { "@foo;bar" }
25
+ let(:id) { "foo/bar" }
21
26
  it_should_behave_like "properties"
22
27
  end
23
28
  end
@@ -12,14 +12,18 @@ describe Conjur::User do
12
12
  subject { user }
13
13
  its(:id) { should == login }
14
14
  its(:login) { should == login }
15
- its(:roleid) { should == login }
15
+ its(:roleid) { should == ["user", login].join(':') }
16
16
  its(:resource_id) { should == login }
17
17
  its(:resource_kind) { should == "user" }
18
18
  its(:options) { should == credentials }
19
19
  end
20
+ before {
21
+ Conjur.stub(:account).and_return 'ci'
22
+ }
20
23
  it "connects to a Resource" do
21
24
  require 'conjur/resource'
22
- Conjur::Resource.should_receive(:new).with("#{Conjur::Authz::API.host}/#{user.resource_kind}/#{user.resource_id}", credentials)
25
+ Conjur::Resource.should_receive(:new).with(Conjur::Authz::API.host, credentials).and_return resource = double(:resource)
26
+ resource.should_receive(:[]).with("ci/resources/user/the-login")
23
27
 
24
28
  user.resource
25
29
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: conjur-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-03-14 00:00:00.000000000 Z
13
+ date: 2013-03-25 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rest-client
@@ -28,22 +28,6 @@ dependencies:
28
28
  - - ! '>='
29
29
  - !ruby/object:Gem::Version
30
30
  version: '0'
31
- - !ruby/object:Gem::Dependency
32
- name: slosilo
33
- requirement: !ruby/object:Gem::Requirement
34
- none: false
35
- requirements:
36
- - - ! '>='
37
- - !ruby/object:Gem::Version
38
- version: '0'
39
- type: :runtime
40
- prerelease: false
41
- version_requirements: !ruby/object:Gem::Requirement
42
- none: false
43
- requirements:
44
- - - ! '>='
45
- - !ruby/object:Gem::Version
46
- version: '0'
47
31
  - !ruby/object:Gem::Dependency
48
32
  name: activesupport
49
33
  requirement: !ruby/object:Gem::Requirement
@@ -167,7 +151,6 @@ files:
167
151
  - lib/conjur/acts_as_user.rb
168
152
  - lib/conjur/api.rb
169
153
  - lib/conjur/api/authn.rb
170
- - lib/conjur/api/das.rb
171
154
  - lib/conjur/api/groups.rb
172
155
  - lib/conjur/api/hosts.rb
173
156
  - lib/conjur/api/resources.rb
@@ -179,7 +162,6 @@ files:
179
162
  - lib/conjur/authz-api.rb
180
163
  - lib/conjur/base.rb
181
164
  - lib/conjur/core-api.rb
182
- - lib/conjur/das-api.rb
183
165
  - lib/conjur/env.rb
184
166
  - lib/conjur/escape.rb
185
167
  - lib/conjur/exists.rb
@@ -190,6 +172,7 @@ files:
190
172
  - lib/conjur/host.rb
191
173
  - lib/conjur/log.rb
192
174
  - lib/conjur/log_source.rb
175
+ - lib/conjur/path_based.rb
193
176
  - lib/conjur/resource.rb
194
177
  - lib/conjur/role.rb
195
178
  - lib/conjur/secret.rb
@@ -219,7 +202,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
219
202
  version: '0'
220
203
  segments:
221
204
  - 0
222
- hash: 3809342943954328390
205
+ hash: -1471203965853689802
223
206
  required_rubygems_version: !ruby/object:Gem::Requirement
224
207
  none: false
225
208
  requirements:
@@ -228,7 +211,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
228
211
  version: '0'
229
212
  segments:
230
213
  - 0
231
- hash: 3809342943954328390
214
+ hash: -1471203965853689802
232
215
  requirements: []
233
216
  rubyforge_project:
234
217
  rubygems_version: 1.8.24
@@ -1,33 +0,0 @@
1
-
2
- module Conjur
3
- class API
4
- class << self
5
- def data_access_service_url(account, path = nil, params = {})
6
- provider = 'inscitiv'
7
- base_url = if path.nil? || path.empty?
8
- "#{Conjur::DAS::API.host}/data/#{account}/#{provider}"
9
- else
10
- path = path.split('/').collect do |p|
11
- # Best possible answer I could find
12
- # http://stackoverflow.com/questions/2834034/how-do-i-raw-url-encode-decode-in-javascript-and-ruby-to-get-the-same-values-in
13
- URI.escape(p, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
14
- end.join('/')
15
- "#{Conjur::DAS::API.host}/data/#{account}/#{provider}/#{path}"
16
- end
17
- if params.nil? || params.empty?
18
- base_url
19
- else
20
- query_string = params.map do |name,values|
21
- values = [ values ] unless values.is_a?(Array)
22
- values.map do |value|
23
- name = URI.escape(name, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
24
- value = URI.escape(value || "", Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
25
- "#{name}=#{value}"
26
- end
27
- end.flatten.join("&")
28
- "#{base_url}?#{query_string}"
29
- end
30
- end
31
- end
32
- end
33
- end
@@ -1,22 +0,0 @@
1
- module Conjur
2
- module DAS
3
- class API < Conjur::API
4
- class << self
5
- def host
6
- ENV['CONJUR_DAS_URL'] || default_host
7
- end
8
-
9
- def default_host
10
- case Conjur.env
11
- when 'test', 'development'
12
- "http://localhost:#{Conjur.service_base_port + 200}"
13
- else
14
- "https://das-#{Conjur.stack}-conjur.herokuapp.com"
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
21
-
22
- require 'conjur/api/das'