conjur-api 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/.project +18 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/Gemfile +10 -0
- data/LICENSE +22 -0
- data/README.md +29 -0
- data/Rakefile +20 -0
- data/conjur-api.gemspec +28 -0
- data/features/enroll_server.feature +26 -0
- data/features/login.feature +13 -0
- data/features/ping_as_server.feature +16 -0
- data/features/ping_as_user.feature +9 -0
- data/lib/conjur-api/version.rb +5 -0
- data/lib/conjur/acts_as_resource.rb +21 -0
- data/lib/conjur/acts_as_role.rb +8 -0
- data/lib/conjur/acts_as_user.rb +13 -0
- data/lib/conjur/api.rb +22 -0
- data/lib/conjur/api/authn.rb +66 -0
- data/lib/conjur/api/das.rb +33 -0
- data/lib/conjur/api/groups.rb +18 -0
- data/lib/conjur/api/hosts.rb +37 -0
- data/lib/conjur/api/resources.rb +9 -0
- data/lib/conjur/api/roles.rb +18 -0
- data/lib/conjur/api/secrets.rb +23 -0
- data/lib/conjur/api/users.rb +23 -0
- data/lib/conjur/api/variables.rb +25 -0
- data/lib/conjur/authn-api.rb +22 -0
- data/lib/conjur/authz-api.rb +23 -0
- data/lib/conjur/base.rb +50 -0
- data/lib/conjur/core-api.rb +26 -0
- data/lib/conjur/das-api.rb +22 -0
- data/lib/conjur/env.rb +24 -0
- data/lib/conjur/escape.rb +31 -0
- data/lib/conjur/exists.rb +12 -0
- data/lib/conjur/group.rb +11 -0
- data/lib/conjur/has_attributes.rb +30 -0
- data/lib/conjur/has_id.rb +8 -0
- data/lib/conjur/has_identifier.rb +13 -0
- data/lib/conjur/host.rb +20 -0
- data/lib/conjur/log.rb +52 -0
- data/lib/conjur/log_source.rb +13 -0
- data/lib/conjur/resource.rb +81 -0
- data/lib/conjur/role.rb +52 -0
- data/lib/conjur/secret.rb +12 -0
- data/lib/conjur/user.rb +13 -0
- data/lib/conjur/variable.rb +27 -0
- data/spec/lib/api_spec.rb +98 -0
- data/spec/lib/das_spec.rb +33 -0
- data/spec/lib/resource_spec.rb +84 -0
- data/spec/lib/role_spec.rb +24 -0
- data/spec/lib/user_spec.rb +33 -0
- data/spec/spec_helper.rb +86 -0
- data/spec/vcr_cassettes/Conjur_Resource/_create/with_path-like_identifier.yml +87 -0
- data/spec/vcr_cassettes/Conjur_Resource/_create/with_un-encoded_path-like_identifier.yml +87 -0
- data/spec/vcr_cassettes/Conjur_Resource/_create/with_uuid_identifier.yml +87 -0
- metadata +266 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'conjur/role'
|
2
|
+
|
3
|
+
module Conjur
|
4
|
+
class API
|
5
|
+
def create_role(role, options = {})
|
6
|
+
log do |logger|
|
7
|
+
logger << "Creating role "
|
8
|
+
logger << role
|
9
|
+
end
|
10
|
+
RestClient::Resource.new(Conjur::Authz::API.host, credentials)["/roles/#{path_escape role}"].put(options)
|
11
|
+
Role.new(role, credentials)
|
12
|
+
end
|
13
|
+
|
14
|
+
def role identifier
|
15
|
+
Role.new("#{Conjur::Authz::API.host}/roles/#{path_escape identifier}", credentials)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'conjur/secret'
|
2
|
+
|
3
|
+
module Conjur
|
4
|
+
class API
|
5
|
+
def create_secret(value, options = {})
|
6
|
+
log do |logger|
|
7
|
+
logger << "Creating secret "
|
8
|
+
logger << value
|
9
|
+
end
|
10
|
+
resp = RestClient::Resource.new(Conjur::Core::API.host, credentials)['/secrets'].post(options.merge(value: value))
|
11
|
+
Secret.new(resp.headers[:location], credentials).tap do |secret|
|
12
|
+
log do |logger|
|
13
|
+
logger << "Created secret "
|
14
|
+
logger << secret.id
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def secret id
|
20
|
+
Secret.new("#{Conjur::Core::API.host}/secrets/#{path_escape id}", credentials)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'conjur/user'
|
2
|
+
|
3
|
+
module Conjur
|
4
|
+
class API
|
5
|
+
def create_user(login, options = {})
|
6
|
+
log do |logger|
|
7
|
+
logger << "Creating user "
|
8
|
+
logger << login
|
9
|
+
end
|
10
|
+
resp = JSON.parse RestClient::Resource.new(Conjur::Core::API.host, credentials)['/users'].post(options.merge(login: login))
|
11
|
+
user(resp['login']).tap do |u|
|
12
|
+
log do |logger|
|
13
|
+
logger << "Created user #{u.login}"
|
14
|
+
end
|
15
|
+
u.attributes = resp
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def user login
|
20
|
+
User.new(Conjur::Core::API.host, credentials)["/users/#{path_escape login}"]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'conjur/variable'
|
2
|
+
|
3
|
+
module Conjur
|
4
|
+
class API
|
5
|
+
def create_variable(mime_type, kind, options = {})
|
6
|
+
log do |logger|
|
7
|
+
logger << "Creating #{mime_type} variable #{kind}"
|
8
|
+
if options
|
9
|
+
logger << " with options #{options.inspect}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
resp = RestClient::Resource.new(Conjur::Core::API.host, credentials)['variables'].post(options.merge(mime_type: mime_type, kind: kind))
|
13
|
+
Variable.new(resp.headers[:location], credentials).tap do |variable|
|
14
|
+
log do |logger|
|
15
|
+
logger << "Created variable "
|
16
|
+
logger << variable.id
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def variable id
|
22
|
+
Variable.new("#{Conjur::Core::API.host}/variables/#{path_escape id}", credentials)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Conjur
|
2
|
+
module Authn
|
3
|
+
class API < Conjur::API
|
4
|
+
class << self
|
5
|
+
def host
|
6
|
+
ENV['CONJUR_AUTHN_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}"
|
13
|
+
else
|
14
|
+
"https://authn-#{Conjur.stack}-conjur.herokuapp.com"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'conjur/api/authn'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Conjur
|
2
|
+
module Authz
|
3
|
+
class API < Conjur::API
|
4
|
+
class << self
|
5
|
+
def host
|
6
|
+
ENV['CONJUR_AUTHZ_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 + 100}"
|
13
|
+
else
|
14
|
+
"https://authz-#{Conjur.stack}-conjur.herokuapp.com"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'conjur/api/roles'
|
23
|
+
require 'conjur/api/resources'
|
data/lib/conjur/base.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
require 'conjur/exists'
|
5
|
+
require 'conjur/has_attributes'
|
6
|
+
require 'conjur/escape'
|
7
|
+
require 'conjur/log'
|
8
|
+
require 'conjur/log_source'
|
9
|
+
|
10
|
+
module Conjur
|
11
|
+
class API
|
12
|
+
include Escape
|
13
|
+
include LogSource
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def new_from_key(username, api_key)
|
17
|
+
self.new username, api_key, nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def new_from_token(token)
|
21
|
+
self.new nil, nil, token
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize username, api_key, token
|
26
|
+
@username = username
|
27
|
+
@api_key = api_key
|
28
|
+
@token = token
|
29
|
+
raise "Expecting ( username and api_key ) or token" unless ( username && api_key ) || token
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_reader :api_key, :username, :token
|
33
|
+
|
34
|
+
def username
|
35
|
+
@username || token['data']
|
36
|
+
end
|
37
|
+
|
38
|
+
def host
|
39
|
+
self.class.host
|
40
|
+
end
|
41
|
+
|
42
|
+
def credentials
|
43
|
+
if token
|
44
|
+
{ headers: { authorization: "Token token=\"#{Base64.strict_encode64 token.to_json}\"" }, username: username }
|
45
|
+
else
|
46
|
+
{ user: username, password: api_key }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Conjur
|
2
|
+
module Core
|
3
|
+
class API < Conjur::API
|
4
|
+
class << self
|
5
|
+
def host
|
6
|
+
ENV['CONJUR_CORE_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 + 300}"
|
13
|
+
else
|
14
|
+
"https://core-#{Conjur.stack}-conjur.herokuapp.com"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'conjur/api/hosts'
|
23
|
+
require 'conjur/api/secrets'
|
24
|
+
require 'conjur/api/users'
|
25
|
+
require 'conjur/api/groups'
|
26
|
+
require 'conjur/api/variables'
|
@@ -0,0 +1,22 @@
|
|
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'
|
data/lib/conjur/env.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module Conjur
|
2
|
+
extend self
|
3
|
+
|
4
|
+
def service_base_port
|
5
|
+
(ENV['CONJUR_SERVICE_BASE_PORT'] || 5000 ).to_i
|
6
|
+
end
|
7
|
+
|
8
|
+
def account
|
9
|
+
ENV['CONJUR_ACCOUNT'] or raise "No CONJUR_ACCOUNT defined"
|
10
|
+
end
|
11
|
+
|
12
|
+
def env
|
13
|
+
ENV['CONJUR_ENV'] || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || "development"
|
14
|
+
end
|
15
|
+
|
16
|
+
def stack
|
17
|
+
ENV['CONJUR_STACK'] || case env
|
18
|
+
when "production"
|
19
|
+
"v2"
|
20
|
+
else
|
21
|
+
env
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Conjur
|
2
|
+
module Escape
|
3
|
+
module ClassMethods
|
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}]"))
|
9
|
+
end
|
10
|
+
|
11
|
+
def query_escape(str)
|
12
|
+
return "false" unless str
|
13
|
+
str = str.id if str.respond_to?(:id)
|
14
|
+
require 'uri'
|
15
|
+
URI.escape(str.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.included(base)
|
20
|
+
base.extend ClassMethods
|
21
|
+
end
|
22
|
+
|
23
|
+
def path_escape(str)
|
24
|
+
self.class.path_escape str
|
25
|
+
end
|
26
|
+
|
27
|
+
def query_escape(str)
|
28
|
+
self.class.query_escape str
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/conjur/group.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
module Conjur
|
2
|
+
module HasAttributes
|
3
|
+
def attributes=(a); @attributes = a; end
|
4
|
+
def attributes
|
5
|
+
return @attributes if @attributes
|
6
|
+
fetch
|
7
|
+
end
|
8
|
+
|
9
|
+
def save
|
10
|
+
self.put(attributes.to_json)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Reload the attributes. This action can be used to guarantee a current view of the entity in the case
|
14
|
+
# that it has been modified by an update method or by an external party.
|
15
|
+
def refresh
|
16
|
+
fetch
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def invalidate(&block)
|
22
|
+
yield
|
23
|
+
@attributes = nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def fetch
|
27
|
+
@attributes = JSON.parse(get.body)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/conjur/host.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module Conjur
|
2
|
+
class Host < RestClient::Resource
|
3
|
+
include Exists
|
4
|
+
include HasId
|
5
|
+
include HasIdentifier
|
6
|
+
include HasAttributes
|
7
|
+
include ActsAsUser
|
8
|
+
|
9
|
+
def roleid
|
10
|
+
"host-#{id}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def enrollment_url
|
14
|
+
log do |logger|
|
15
|
+
logger << "Fetching enrollment_url for #{id}"
|
16
|
+
end
|
17
|
+
self['enrollment_url'].head{|response, request, result| response }.headers[:location]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/conjur/log.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# Logging mechanism borrowed from rest-client
|
2
|
+
module Conjur
|
3
|
+
# You can also configure logging by the environment variable CONJURAPI_LOG.
|
4
|
+
def self.log= log
|
5
|
+
@@log = create_log log
|
6
|
+
end
|
7
|
+
|
8
|
+
# Create a log that respond to << like a logger
|
9
|
+
# param can be 'stdout', 'stderr', a string (then we will log to that file) or a logger (then we return it)
|
10
|
+
def self.create_log param
|
11
|
+
if param
|
12
|
+
if param.is_a? String
|
13
|
+
if param == 'stdout'
|
14
|
+
stdout_logger = Class.new do
|
15
|
+
def << obj
|
16
|
+
STDOUT.write obj
|
17
|
+
end
|
18
|
+
end
|
19
|
+
stdout_logger.new
|
20
|
+
elsif param == 'stderr'
|
21
|
+
stderr_logger = Class.new do
|
22
|
+
def << obj
|
23
|
+
STDERR.write obj
|
24
|
+
end
|
25
|
+
end
|
26
|
+
stderr_logger.new
|
27
|
+
else
|
28
|
+
file_logger = Class.new do
|
29
|
+
attr_writer :target_file
|
30
|
+
|
31
|
+
def << obj
|
32
|
+
File.open(@target_file, 'a') { |f| f.write obj }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
logger = file_logger.new
|
36
|
+
logger.target_file = param
|
37
|
+
logger
|
38
|
+
end
|
39
|
+
else
|
40
|
+
param
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
@@env_log = create_log ENV['CONJURAPI_LOG']
|
46
|
+
|
47
|
+
@@log = nil
|
48
|
+
|
49
|
+
def self.log # :nodoc:
|
50
|
+
@@env_log || @@log
|
51
|
+
end
|
52
|
+
end
|