conjur-api 2.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
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'