conjur-api 2.0.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.
Files changed (57) hide show
  1. data/.gitignore +18 -0
  2. data/.project +18 -0
  3. data/.rspec +2 -0
  4. data/.rvmrc +1 -0
  5. data/Gemfile +10 -0
  6. data/LICENSE +22 -0
  7. data/README.md +29 -0
  8. data/Rakefile +20 -0
  9. data/conjur-api.gemspec +28 -0
  10. data/features/enroll_server.feature +26 -0
  11. data/features/login.feature +13 -0
  12. data/features/ping_as_server.feature +16 -0
  13. data/features/ping_as_user.feature +9 -0
  14. data/lib/conjur-api/version.rb +5 -0
  15. data/lib/conjur/acts_as_resource.rb +21 -0
  16. data/lib/conjur/acts_as_role.rb +8 -0
  17. data/lib/conjur/acts_as_user.rb +13 -0
  18. data/lib/conjur/api.rb +22 -0
  19. data/lib/conjur/api/authn.rb +66 -0
  20. data/lib/conjur/api/das.rb +33 -0
  21. data/lib/conjur/api/groups.rb +18 -0
  22. data/lib/conjur/api/hosts.rb +37 -0
  23. data/lib/conjur/api/resources.rb +9 -0
  24. data/lib/conjur/api/roles.rb +18 -0
  25. data/lib/conjur/api/secrets.rb +23 -0
  26. data/lib/conjur/api/users.rb +23 -0
  27. data/lib/conjur/api/variables.rb +25 -0
  28. data/lib/conjur/authn-api.rb +22 -0
  29. data/lib/conjur/authz-api.rb +23 -0
  30. data/lib/conjur/base.rb +50 -0
  31. data/lib/conjur/core-api.rb +26 -0
  32. data/lib/conjur/das-api.rb +22 -0
  33. data/lib/conjur/env.rb +24 -0
  34. data/lib/conjur/escape.rb +31 -0
  35. data/lib/conjur/exists.rb +12 -0
  36. data/lib/conjur/group.rb +11 -0
  37. data/lib/conjur/has_attributes.rb +30 -0
  38. data/lib/conjur/has_id.rb +8 -0
  39. data/lib/conjur/has_identifier.rb +13 -0
  40. data/lib/conjur/host.rb +20 -0
  41. data/lib/conjur/log.rb +52 -0
  42. data/lib/conjur/log_source.rb +13 -0
  43. data/lib/conjur/resource.rb +81 -0
  44. data/lib/conjur/role.rb +52 -0
  45. data/lib/conjur/secret.rb +12 -0
  46. data/lib/conjur/user.rb +13 -0
  47. data/lib/conjur/variable.rb +27 -0
  48. data/spec/lib/api_spec.rb +98 -0
  49. data/spec/lib/das_spec.rb +33 -0
  50. data/spec/lib/resource_spec.rb +84 -0
  51. data/spec/lib/role_spec.rb +24 -0
  52. data/spec/lib/user_spec.rb +33 -0
  53. data/spec/spec_helper.rb +86 -0
  54. data/spec/vcr_cassettes/Conjur_Resource/_create/with_path-like_identifier.yml +87 -0
  55. data/spec/vcr_cassettes/Conjur_Resource/_create/with_un-encoded_path-like_identifier.yml +87 -0
  56. data/spec/vcr_cassettes/Conjur_Resource/_create/with_uuid_identifier.yml +87 -0
  57. metadata +266 -0
@@ -0,0 +1,18 @@
1
+ build_number
2
+ *.gem
3
+ *.rbc
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
@@ -0,0 +1,18 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <projectDescription>
3
+ <name>conjur-api</name>
4
+ <comment></comment>
5
+ <projects>
6
+ </projects>
7
+ <buildSpec>
8
+ <buildCommand>
9
+ <name>com.aptana.ide.core.unifiedBuilder</name>
10
+ <arguments>
11
+ </arguments>
12
+ </buildCommand>
13
+ </buildSpec>
14
+ <natures>
15
+ <nature>com.aptana.ruby.core.rubynature</nature>
16
+ <nature>com.aptana.projects.webnature</nature>
17
+ </natures>
18
+ </projectDescription>
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format Fuubar
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.3@conjur-api-ruby --create
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in conjur-api.gemspec
4
+ gemspec
5
+
6
+ gem 'slosilo', :git => 'https://github.com/inscitiv/slosilo.git'
7
+
8
+ group :test do
9
+ gem 'fuubar'
10
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Rafał Rzepecki
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ # Conjur::API
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'conjur-api'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install conjur-api
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ begin
5
+ require 'rspec/core/rake_task'
6
+ RSpec::Core::RakeTask.new(:spec)
7
+ rescue LoadError
8
+ $stderr.puts "RSpec Rake tasks not available in environment #{ENV['RACK_ENV']}"
9
+ end
10
+
11
+ task :jenkins do
12
+ if ENV['BUILD_NUMBER']
13
+ File.write('build_number', ENV['BUILD_NUMBER'])
14
+ end
15
+ require 'ci/reporter/rake/rspec'
16
+ Rake::Task["ci:setup:rspec"].invoke
17
+ Rake::Task["spec"].invoke
18
+ end
19
+
20
+ task default: :spec
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/conjur-api/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Rafa\305\202 Rzepecki","Kevin Gilpin"]
6
+ gem.email = ["divided.mind@gmail.com","kevin.gilpin@inscitiv.com"]
7
+ gem.description = %q{Conjur API}
8
+ gem.summary = %q{Conjur API}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\) + Dir['build_number']
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "conjur-api"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Conjur::API::VERSION
17
+
18
+ gem.add_runtime_dependency 'rest-client'
19
+ gem.add_runtime_dependency 'slosilo'
20
+ gem.add_runtime_dependency 'activesupport'
21
+
22
+ gem.add_development_dependency 'rake'
23
+ gem.add_development_dependency 'spork'
24
+ gem.add_development_dependency 'rspec'
25
+ gem.add_development_dependency 'vcr'
26
+ gem.add_development_dependency 'webmock'
27
+ gem.add_development_dependency 'ci_reporter'
28
+ end
@@ -0,0 +1,26 @@
1
+ Feature: Server enrollment
2
+
3
+ Background:
4
+ When I login with my username and password
5
+ And I receive an API key
6
+
7
+ Scenario: Enroll this server
8
+ When I enroll a server
9
+ Then the request succeeds
10
+ Then I receive an enrollment key
11
+
12
+ Scenario: The server is granted no other roles by default
13
+ Given I enroll a server
14
+ And I switch to the server role
15
+ When I list my roles
16
+ Then the result contains 1 item
17
+
18
+ Scenario: The server can be granted other roles
19
+ Given I enroll a server
20
+ And I create a role
21
+ And I grant the role to the server
22
+ And I switch to the server role
23
+ And I list my roles
24
+ Then the result contains 2 items
25
+
26
+
@@ -0,0 +1,13 @@
1
+ Feature: Login
2
+
3
+ Scenario: Login with my username and password
4
+ When I login with my username and password
5
+ Then the request succeeds
6
+ And I receive an API key
7
+
8
+ Scenario: Login with my username and password
9
+ When I login with my username and invalid password
10
+ Then the request fails with error 401
11
+
12
+
13
+
@@ -0,0 +1,16 @@
1
+ Feature: Ping
2
+
3
+ Background:
4
+ Given I login with my username and password
5
+ And I receive an API key
6
+ And I enroll a server
7
+ And I switch to the server role
8
+
9
+ Scenario: Ping using the server enrollment key
10
+ When I ping
11
+ Then the request succeeds
12
+
13
+ Scenario: Server credentials do not work from a different host
14
+ Given I force the request IP address to 127.0.0.1
15
+ When I ping
16
+ Then the request fails with error 401
@@ -0,0 +1,9 @@
1
+ Feature: Ping
2
+
3
+ Background:
4
+ When I login with my username and password
5
+ And I receive an API key
6
+
7
+ Scenario: Ping using an API key
8
+ When I ping
9
+ Then the request succeeds
@@ -0,0 +1,5 @@
1
+ module Conjur
2
+ class API
3
+ VERSION = "2.0.0"
4
+ end
5
+ end
@@ -0,0 +1,21 @@
1
+ module Conjur
2
+ module ActsAsResource
3
+ def resource
4
+ require 'conjur/resource'
5
+ Conjur::Resource.new("#{Conjur::Authz::API.host}/#{path_escape resource_kind}/#{path_escape resource_id}", self.options)
6
+ end
7
+
8
+ def resource_kind
9
+ self.class.name.split("::")[1..-1].join('-').downcase
10
+ end
11
+
12
+ def resource_id
13
+ id
14
+ end
15
+
16
+ def delete
17
+ resource.delete
18
+ super
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,8 @@
1
+ module Conjur
2
+ module ActsAsRole
3
+ def role
4
+ require 'conjur/role'
5
+ Conjur::Role.new("#{Conjur::Authz::API.host}/roles/#{path_escape roleid}", self.options)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,13 @@
1
+ module Conjur
2
+ module ActsAsUser
3
+ def self.included(base)
4
+ base.instance_eval do
5
+ include ActsAsRole
6
+ end
7
+ end
8
+
9
+ def roleid
10
+ id
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,22 @@
1
+ require 'conjur/env'
2
+ require 'conjur/base'
3
+ require 'conjur/acts_as_resource'
4
+ require 'conjur/acts_as_role'
5
+ require 'conjur/acts_as_user'
6
+ require 'conjur/log_source'
7
+ require 'conjur/has_attributes'
8
+ require 'conjur/has_identifier'
9
+ require 'conjur/has_id'
10
+ require 'conjur/das-api'
11
+ require 'conjur/authn-api'
12
+ require 'conjur/authz-api'
13
+ require 'conjur/core-api'
14
+
15
+ class RestClient::Resource
16
+ include Conjur::Escape
17
+ include Conjur::LogSource
18
+
19
+ def username
20
+ options[:user] || options[:username]
21
+ end
22
+ end
@@ -0,0 +1,66 @@
1
+ require 'conjur/user'
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
+ module Conjur
13
+ class API
14
+ class << self
15
+ # Perform login by Basic authentication.
16
+ def login username, password
17
+ if Conjur.log
18
+ Conjur.log << "Logging in #{username} via Basic authentication\n"
19
+ end
20
+ RestClient::Resource.new(Conjur::Authn::API.host, user: username, password: password)['/users/login'].get
21
+ end
22
+
23
+ # Perform login by CAS authentication.
24
+ def login_cas username, password, cas_api_url
25
+ if Conjur.log
26
+ Conjur.log << "Logging in #{username} via CAS authentication\n"
27
+ end
28
+ require 'cas_rest_client'
29
+ client = CasRestClient.new(:username => username, :password => password, :uri => [ cas_api_url, 'v1', 'tickets' ].join('/'), :use_cookies => false)
30
+ client.get("#{Conjur::Authn::API.host}/users/login").body
31
+ end
32
+
33
+ def authenticate username, password
34
+ if Conjur.log
35
+ Conjur.log << "Authenticating #{username}\n"
36
+ 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
50
+ end
51
+ end
52
+
53
+ # Options:
54
+ # +password+
55
+ #
56
+ # Response:
57
+ # +login+
58
+ # +api_key+
59
+ def create_authn_user login, options = {}
60
+ log do |logger|
61
+ logger << "Creating authn user #{login}"
62
+ end
63
+ JSON.parse RestClient::Resource.new(Conjur::Authn::API.host, credentials)['/users'].post(options.merge(login: login))
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,33 @@
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
@@ -0,0 +1,18 @@
1
+ require 'conjur/group'
2
+
3
+ module Conjur
4
+ class API
5
+ def create_group(id, options = {})
6
+ log do |logger|
7
+ logger << "Creating group "
8
+ logger << id
9
+ end
10
+ resp = RestClient::Resource.new(Conjur::Core::API.host, credentials)['/groups'].post(options.merge(id: id))
11
+ Group.new(resp.headers[:location], credentials)
12
+ end
13
+
14
+ def group id
15
+ Group.new(Conjur::Core::API.host)["/groups/#{path_escape id}"]
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,37 @@
1
+ require 'conjur/host'
2
+
3
+ module Conjur
4
+ class API
5
+ def create_host options
6
+ log do |logger|
7
+ logger << "Creating host"
8
+ end
9
+ resp = JSON.parse RestClient::Resource.new("#{Conjur::Core::API.host}/hosts", credentials).post(options)
10
+ host(resp['id']).tap do |h|
11
+ log do |logger|
12
+ logger << "Created host #{h.id}"
13
+ end
14
+ h.attributes = resp
15
+ end
16
+ end
17
+
18
+ class << self
19
+ def enroll_host(url)
20
+ if Conjur.log
21
+ logger << "Enrolling host with URL #{url}"
22
+ end
23
+ require 'uri'
24
+ url = URI.parse(url) if url.is_a?(String)
25
+ response = Net::HTTP.get_response url
26
+ raise "Host enrollment failed with status #{response.code} : #{response.body}" unless response.code.to_i == 200
27
+ mime_type = response['Content-Type']
28
+ body = response.body
29
+ [ mime_type, body ]
30
+ end
31
+ end
32
+
33
+ def host id
34
+ Host.new("#{Conjur::Core::API.host}/hosts/#{path_escape id}", credentials)
35
+ end
36
+ end
37
+ end