Class: Conjur::API

Inherits:
Object
  • Object
show all
Includes:
Cast, Escape, LogSource, StandardMethods
Defined in:
lib/conjur/base.rb,
lib/conjur/core-api.rb,
lib/conjur/api/audit.rb,
lib/conjur/api/authn.rb,
lib/conjur/api/hosts.rb,
lib/conjur/api/roles.rb,
lib/conjur/api/users.rb,
lib/conjur/layer-api.rb,
lib/conjur/api/groups.rb,
lib/conjur/api/layers.rb,
lib/conjur-api/version.rb,
lib/conjur/api/pubkeys.rb,
lib/conjur/api/secrets.rb,
lib/conjur/pubkeys-api.rb,
lib/conjur/api/deputies.rb,
lib/conjur/api/resources.rb,
lib/conjur/api/variables.rb

Constant Summary collapse

VERSION =
"4.9.0"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from LogSource

#log

Methods included from Escape

#fully_escape, included, #path_escape, #query_escape

Constructor Details

#initialize(username, api_key, token) ⇒ API

Returns a new instance of API.



93
94
95
96
97
98
99
# File 'lib/conjur/base.rb', line 93

def initialize username, api_key, token
  @username = username
  @api_key = api_key
  @token = token

  raise "Expecting ( username and api_key ) or token" unless ( username && api_key ) || token
end

Instance Attribute Details

#api_keyObject (readonly)

Returns the value of attribute api_key.



101
102
103
# File 'lib/conjur/base.rb', line 101

def api_key
  @api_key
end

#usernameObject (readonly)

Returns the value of attribute username.



101
102
103
# File 'lib/conjur/base.rb', line 101

def username
  @username
end

Class Method Details

.authenticate(username, password) ⇒ Object



44
45
46
47
48
49
# File 'lib/conjur/api/authn.rb', line 44

def authenticate username, password
  if Conjur.log
    Conjur.log << "Authenticating #{username}\n"
  end
  JSON::parse(RestClient::Resource.new(Conjur::Authn::API.host)["users/#{fully_escape username}/authenticate"].post password, content_type: 'text/plain')
end

.core_asset_hostObject



24
25
26
# File 'lib/conjur/core-api.rb', line 24

def core_asset_host
  ::Conjur::Core::API.host
end

.enroll_host(url) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/conjur/api/hosts.rb', line 26

def enroll_host(url)
  if Conjur.log
    Conjur.log << "Enrolling host with URL #{url}\n"
  end
  require 'uri'
  url = URI.parse(url) if url.is_a?(String)
  response = Net::HTTP.get_response url
  raise "Host enrollment failed with status #{response.code} : #{response.body}" unless response.code.to_i == 200
  mime_type = response['Content-Type']
  body = response.body
  [ mime_type, body ]
end

.layer_asset_hostObject



3
4
5
# File 'lib/conjur/layer-api.rb', line 3

def layer_asset_host
  ENV["CONJUR_LAYER_ASSET_URL"] || Conjur::Core::API.host
end

.login(username, password) ⇒ Object

Perform login by Basic authentication.



27
28
29
30
31
32
# File 'lib/conjur/api/authn.rb', line 27

def  username, password
  if Conjur.log
    Conjur.log << "Logging in #{username} via Basic authentication\n"
  end
  RestClient::Resource.new(Conjur::Authn::API.host, user: username, password: password)['users/login'].get
end

.login_cas(username, password, cas_api_url) ⇒ Object

Perform login by CAS authentication.



35
36
37
38
39
40
41
42
# File 'lib/conjur/api/authn.rb', line 35

def  username, password, cas_api_url
  if Conjur.log
    Conjur.log << "Logging in #{username} via CAS authentication\n"
  end
  require 'cas_rest_client'
  client = CasRestClient.new(:username => username, :password => password, :uri => [ cas_api_url, 'v1', 'tickets' ].join('/'), :use_cookies => false)
  client.get("#{Conjur::Authn::API.host}/users/login").body
end

.new_from_key(username, api_key) ⇒ Object



84
85
86
# File 'lib/conjur/base.rb', line 84

def new_from_key(username, api_key)
  self.new username, api_key, nil
end

.new_from_token(token) ⇒ Object



88
89
90
# File 'lib/conjur/base.rb', line 88

def new_from_token(token)
  self.new nil, nil, token
end

.parse_id(id, kind) ⇒ Object

Converts flat id into path components, with mixed-in “super-kind”

(not that kind which is part of id)

NOTE: name is a bit confusing, as result of ‘parse’ is just recombined

representation of parts, not an object of higher abstraction level


71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/conjur/base.rb', line 71

def parse_id(id, kind)
  # Structured IDs (hashes) are no more supported
  raise "Unexpected class #{id.class} for #{id}" unless id.is_a?(String)
  paths = path_escape(id).split(':')
  if paths.size < 2
    raise "Expecting at least two tokens in #{id}"
  elsif paths.size == 2
    paths.unshift Conjur::Core::API.
  end
  # I would strongly recommend to encapsulate this into object 
  [ paths[0], kind, paths[1], paths[2..-1].join(':') ]
end

.parse_resource_id(id) ⇒ Object

Parse a resource id into [ account, ‘resources’, kind, id ]



56
57
58
59
60
61
62
63
64
65
# File 'lib/conjur/base.rb', line 56

def parse_resource_id(id)
  id = id.resource if id.respond_to?(:resource)
  if id.is_a?(Resource)
    [ id., 'resources', id.kind, id.identifier ]
  elsif id.respond_to?(:resource_kind)
    [ Conjur::Core::API., 'resources', id.resource_kind, id.resource_id ]
  else
    parse_id id, 'resources'
  end
end

.parse_role_id(id) ⇒ Object

Parse a role id into [ account, ‘roles’, kind, id ]



44
45
46
47
48
49
50
51
52
53
# File 'lib/conjur/base.rb', line 44

def parse_role_id(id)
  id = id.role if id.respond_to?(:role)
  if id.is_a?(Role)
    [ id., 'roles', id.kind, id.identifier ]
  elsif id.respond_to?(:role_kind)
    [ Conjur::Core::API., 'roles', id.role_kind, id.identifier ]
  else
    parse_id id, 'roles'
  end
end

.pubkeys_asset_hostObject



32
33
34
# File 'lib/conjur/pubkeys-api.rb', line 32

def pubkeys_asset_host 
  Conjur.configuration.pubkeys_url
end

.update_password(username, password, new_password) ⇒ Object



51
52
53
54
55
56
# File 'lib/conjur/api/authn.rb', line 51

def update_password username, password, new_password
  if Conjur.log
    Conjur.log << "Updating password for #{username}\n"
  end
  RestClient::Resource.new(Conjur::Authn::API.host, user: username, password: password)['users/password'].put new_password
end

Instance Method Details

#add_public_key(username, key) ⇒ Object

Add a public key for the given user



36
37
38
# File 'lib/conjur/api/pubkeys.rb', line 36

def add_public_key username, key
  public_keys_resource(username).post key
end

#audit(options = {}, &block) ⇒ Object

Return all events visible to the current authorized role



25
26
27
# File 'lib/conjur/api/audit.rb', line 25

def audit options={}, &block
  audit_event_feed "", options, &block
end

#audit_resource(resource, options = {}, &block) ⇒ Object

Return audit events related to the given resource



37
38
39
# File 'lib/conjur/api/audit.rb', line 37

def audit_resource resource, options={}, &block
  audit_event_feed "resources/#{CGI.escape cast(resource, :resourceid)}", options, &block
end

#audit_role(role, options = {}, &block) ⇒ Object

Return audit events related to the given role_id. Identitical to audit_events except that a String may be given instead of a Role object.

Parameters:

  • role (String)

    the role for which events should be returned.



32
33
34
# File 'lib/conjur/api/audit.rb', line 32

def audit_role role, options={}, &block
  audit_event_feed "roles/#{CGI.escape cast(role, :roleid)}", options, &block
end

#create_authn_user(login, options = {}) ⇒ Object

Options: password

Response: login api_key



65
66
67
68
69
70
# File 'lib/conjur/api/authn.rb', line 65

def create_authn_user , options = {}
  log do |logger|
    logger << "Creating authn user #{}"
  end
  JSON.parse RestClient::Resource.new(Conjur::Authn::API.host, credentials)['users'].post(options.merge(login: ))
end

#create_deputy(options = {}) ⇒ Object



25
26
27
# File 'lib/conjur/api/deputies.rb', line 25

def create_deputy options = {}
  standard_create Conjur::Core::API.host, :deputy, nil, options
end

#create_group(id, options = {}) ⇒ Object



29
30
31
# File 'lib/conjur/api/groups.rb', line 29

def create_group(id, options = {})
  standard_create Conjur::Core::API.host, :group, id, options
end

#create_host(options = {}) ⇒ Object



40
41
42
# File 'lib/conjur/api/hosts.rb', line 40

def create_host options = {}
  standard_create Conjur::Core::API.host, :host, nil, options
end

#create_layer(id, options = {}) ⇒ Object



5
6
7
# File 'lib/conjur/api/layers.rb', line 5

def create_layer(id, options = {})
  standard_create Conjur::API.layer_asset_host, :layer, id, options
end

#create_resource(identifier, options = {}) ⇒ Object



25
26
27
28
29
# File 'lib/conjur/api/resources.rb', line 25

def create_resource(identifier, options = {})
  resource(identifier).tap do |r|
    r.create(options)
  end
end

#create_role(role, options = {}) ⇒ Object



25
26
27
28
29
# File 'lib/conjur/api/roles.rb', line 25

def create_role(role, options = {})
  role(role).tap do |r|
    r.create(options)
  end
end

#create_secret(value, options = {}) ⇒ Object



25
26
27
# File 'lib/conjur/api/secrets.rb', line 25

def create_secret(value, options = {})
  standard_create Conjur::Core::API.host, :secret, nil, options.merge(value: value)
end

#create_user(login, options = {}) ⇒ Object



25
26
27
# File 'lib/conjur/api/users.rb', line 25

def create_user(, options = {})
  standard_create Conjur::Core::API.host, :user, nil, options.merge(login: )
end

#create_variable(mime_type, kind, options = {}) ⇒ Object



25
26
27
# File 'lib/conjur/api/variables.rb', line 25

def create_variable(mime_type, kind, options = {})
  standard_create Conjur::Core::API.host, :variable, nil, options.merge(mime_type: mime_type, kind: kind)
end

#credentialsObject

Authenticate the username and api_key to obtain a request token. Tokens are cached by username for a short period of time.



117
118
119
# File 'lib/conjur/base.rb', line 117

def credentials
  { headers: { authorization: "Token token=\"#{Base64.strict_encode64 token.to_json}\"" }, username: username }
end

#current_roleObject



35
36
37
# File 'lib/conjur/api/roles.rb', line 35

def current_role
  role_from_username username
end

#delete_public_key(username, keyname) ⇒ Object

Delete a public key for the given user and key name



41
42
43
# File 'lib/conjur/api/pubkeys.rb', line 41

def delete_public_key username, keyname
  public_keys_resource(username, keyname).delete
end

#deputy(id) ⇒ Object



29
30
31
# File 'lib/conjur/api/deputies.rb', line 29

def deputy id
  standard_show Conjur::Core::API.host, :deputy, id
end

#group(id) ⇒ Object



33
34
35
# File 'lib/conjur/api/groups.rb', line 33

def group id
  standard_show Conjur::Core::API.host, :group, id
end

#groups(options = {}) ⇒ Object



25
26
27
# File 'lib/conjur/api/groups.rb', line 25

def groups(options={})
  standard_list Conjur::Core::API.host, :group, options
end

#host(id) ⇒ Object



107
108
109
# File 'lib/conjur/base.rb', line 107

def host
  self.class.host
end

#layer(id) ⇒ Object



13
14
15
# File 'lib/conjur/api/layers.rb', line 13

def layer id
  standard_show Conjur::API.layer_asset_host, :layer, id
end

#layers(options = {}) ⇒ Object



9
10
11
# File 'lib/conjur/api/layers.rb', line 9

def layers(options = {})
  standard_list Conjur::API.layer_asset_host, :layer, options
end

#public_key(username, keyname) ⇒ Object

Return a specific public key for a given user and key name



31
32
33
# File 'lib/conjur/api/pubkeys.rb', line 31

def public_key username, keyname
  public_keys_resource(username, keyname).get
end

#public_keys(username) ⇒ Object

Return all of a user’s public keys, as a newline delimited string (the format expected by authorized-keys)



26
27
28
# File 'lib/conjur/api/pubkeys.rb', line 26

def public_keys username
  public_keys_resource(username).get
end

#resource(resource) ⇒ Object



31
32
33
# File 'lib/conjur/api/resources.rb', line 31

def resource resource
  Resource.new(Conjur::Authz::API.host, credentials)[self.class.parse_resource_id(resource).join('/')]
end

#resources(opts = {}) ⇒ Object

Return all visible resources. In opts you should pass an account to filter by, and optionally a kind.



37
38
39
40
41
42
43
44
45
46
# File 'lib/conjur/api/resources.rb', line 37

def resources opts = {}
  opts = { host: Conjur::Authz::API.host, credentials: credentials }.merge opts
  opts[:account] ||= Conjur.
  
  Resource.all(opts).map do |result|
    resource(result['id']).tap do |r|
      r.attributes = result
    end
  end
end

#role(role) ⇒ Object



31
32
33
# File 'lib/conjur/api/roles.rb', line 31

def role role
  Role.new(Conjur::Authz::API.host, credentials)[self.class.parse_role_id(role).join('/')]
end

#role_from_username(username) ⇒ Object



39
40
41
# File 'lib/conjur/api/roles.rb', line 39

def role_from_username username
  role(role_name_from_username username)
end

#role_name_from_username(username = self.username) ⇒ Object



43
44
45
46
47
48
49
50
# File 'lib/conjur/api/roles.rb', line 43

def role_name_from_username username = self.username
  tokens = username.split('/')
  if tokens.size == 1
    [ 'user', username ].join(':')
  else
    [ tokens[0], tokens[1..-1].join('/') ].join(':')
  end
end

#secret(id) ⇒ Object



29
30
31
# File 'lib/conjur/api/secrets.rb', line 29

def secret id
  standard_show Conjur::Core::API.host, :secret, id
end

#tokenObject



111
112
113
# File 'lib/conjur/base.rb', line 111

def token
  @token ||= Conjur::API.authenticate(@username, @api_key)
end

#user(login) ⇒ Object



29
30
31
# File 'lib/conjur/api/users.rb', line 29

def user 
  standard_show Conjur::Core::API.host, :user, 
end

#variable(id) ⇒ Object



29
30
31
# File 'lib/conjur/api/variables.rb', line 29

def variable id
  standard_show Conjur::Core::API.host, :variable, id
end

#variable_values(varlist) ⇒ Object

Raises:

  • (ArgumentError)


33
34
35
36
37
38
39
40
41
42
43
# File 'lib/conjur/api/variables.rb', line 33

def variable_values(varlist)
  raise ArgumentError, "Variables list must be an array" unless varlist.kind_of? Array 
  raise ArgumentError, "Variables list is empty" if varlist.empty?
  opts = "?vars=#{varlist.map { |v| fully_escape(v) }.join(',')}"
  begin 
    resp = RestClient::Resource.new(Conjur::Core::API.host, self.credentials)['variables/values'+opts].get
    return JSON.parse( resp.body ) 
  rescue RestClient::ResourceNotFound 
    return Hash[ *varlist.map { |v| [ v, variable(v).value ]  }.flatten ]  
  end
end