Class: Zanzibar::Zanzibar

Inherits:
Object
  • Object
show all
Defined in:
lib/vagrant-zanzibar.rb

Overview

Class for interacting with Secret Server

Instance Method Summary collapse

Constructor Details

#initialize(args = {}) ⇒ Zanzibar

Returns a new instance of Zanzibar.

Parameters:

  • args (:domain, :wsdl, :pwd, :username, :globals{}) (defaults to: {})


13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/vagrant-zanzibar.rb', line 13

def initialize(args = {})

  ## Array to store checked out secrets
  @@secrets = []

  if args[:username]
    @@username = args[:username]
  else
    @@username = ENV['USER']
  end

  if args[:wsdl]
    @@wsdl = args[:wsdl]
  else
    @@wsdl = get_wsdl_location
  end
  if args[:pwd]
    @@password = args[:pwd]
  else
    @@password = prompt_for_password
  end
  if args[:domain]
    @@domain = args[:domain]
  else
    @@domain = prompt_for_domain
  end
  args[:globals] = {} unless args[:globals]
  init_client(args[:globals])
end

Instance Method Details

#check_in_secretsObject

Check in the secrets that are currently checked out



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/vagrant-zanzibar.rb', line 86

def check_in_secrets
  failures = []
  token = get_token
  @@secrets.each do |secret_id|
    begin
      response = @@client.request(:wsdl, :check_in) { soap.body = { token: token, secretId: secret_id} }
        .hash[:envelope][:body][:check_in_response][:check_in_result][:errors]
        if !response.nil? and response[:string] != "Secret is not CheckedOut to current user."
          failures << "Error checking in secret #{secret_id} : #{response[:string]}"
        end
    rescue Savon::Error => err
    raise "There was an error checking in secret #{secret_id}: #{err}"
    end
  end
  if !failures.empty?
    failures.each do |message|
      puts message
    end
    abort()
  end
end

#download_attachment(args = {}) ⇒ Object



208
209
210
211
# File 'lib/vagrant-zanzibar.rb', line 208

def download_attachment(args = {})
  args[:type] = 'Attachment'
  download_secret_file(args)
end

#download_private_key(args = {}) ⇒ Object

Methods to maintain backwards compatibility



198
199
200
201
# File 'lib/vagrant-zanzibar.rb', line 198

def download_private_key(args = {})
  args[:type] = 'Private Key'
  download_secret_file(args)
end

#download_public_key(args = {}) ⇒ Object



203
204
205
206
# File 'lib/vagrant-zanzibar.rb', line 203

def download_public_key(args = {})
  args[:type] = 'Public Key'
  download_secret_file(args)
end

#download_secret_file(args = {}) ⇒ Object

Downloads a file for a secret and places it where Zanzibar is running, or :path if specified Raise on error

Parameters:

  • args, (Hash)

    :scrt_id, :type (one of “Private Key”, “Public Key”, “Attachment”), :scrt_item_id - optional, :path - optional



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/vagrant-zanzibar.rb', line 181

def download_secret_file(args = {})
  token = get_token
  scrt_item_id = get_scrt_item_id(args[:scrt_id], args[:type], token)
  FileUtils.mkdir_p(args[:path]) if args[:path]
  path = args[:path] ? args[:path] : '.' ## The File.join below doesn't handle nils well, so let's take that possibility away.
  begin
    response = @@client.request(:wsdl, :download_file_attachment_by_item_id){ soap.body =
      { token: token, secretId: args[:scrt_id], secretItemId: scrt_item_id  }}
               .hash[:envelope][:body][:download_file_attachment_by_item_id_response][:download_file_attachment_by_item_id_result]
    abort("There was an error getting the #{args[:type]} for secret #{args[:scrt_id]}: #{response[:errors][:string]}")  if response[:errors]
    write_secret_to_file(path, response)
  rescue Savon::Error => err
    raise "There was an error getting the #{args[:type]} for secret #{args[:scrt_id]}: #{err}"
  end
end

#get_password(scrt_id) ⇒ String

Retrieve a simple password from a secret Will raise an error if there are any issues

Parameters:

  • the (Integer)

    secret id

Returns:

  • (String)

    the password for the given secret



141
142
143
144
145
146
147
# File 'lib/vagrant-zanzibar.rb', line 141

def get_password(scrt_id)
  secret = get_secret(scrt_id)
  secret_items = secret[:secret][:items][:secret_item]
  return get_secret_item_by_field_name(secret_items, 'Password')[:value]
rescue Savon::Error => err
  raise "There was an error getting the password for secret #{scrt_id}: #{err}"
end

#get_scrt_item_id(scrt_id, type, token) ⇒ Integer

Get the secret item id that relates to a key file or attachment. Will raise on error

Parameters:

  • the (Integer)

    secret id

  • the (String)

    type of secret item to get, one of privatekey, publickey, attachment

Returns:

  • (Integer)

    the secret item id



167
168
169
170
171
172
173
174
175
# File 'lib/vagrant-zanzibar.rb', line 167

def get_scrt_item_id(scrt_id, type, token)
  secret = get_secret(scrt_id, token)
  secret_items = secret[:secret][:items][:secret_item]
  begin
    return get_secret_item_by_field_name(secret_items, type)[:id]
  rescue
    raise "Unknown type, #{type}."
  end
end

#get_secret(scrt_id, token = nil) ⇒ Hash

Get a secret returned as a hash Will raise an error if there was an issue getting the secret

Parameters:

  • the (Integer)

    secret id

Returns:

  • (Hash)

    the secret hash retrieved from the wsdl



126
127
128
129
130
131
132
133
134
# File 'lib/vagrant-zanzibar.rb', line 126

def get_secret(scrt_id, token = nil)
  token = get_token if token.nil?
  secret = @@client.request(:wsdl, :get_secret) { soap.body = { token: token, secretId: scrt_id } }.hash[:envelope][:body][:get_secret_response][:get_secret_result]
  abort("There was an error getting secret #{scrt_id}: #{secret[:errors][:string]}") if secret[:errors]
  @@secrets << scrt_id
  return secret
rescue Savon::Error => err
  raise "There was an error getting the secret with id #{scrt_id}: #{err}"
end

#get_secret_item_by_field_name(secret_items, field_name) ⇒ Object



155
156
157
158
159
# File 'lib/vagrant-zanzibar.rb', line 155

def get_secret_item_by_field_name(secret_items, field_name)
  secret_items.each do |item|
    return item if item[:field_name] == field_name
  end
end

#get_tokenObject

Get an authentication token for interacting with Secret Server. These are only good for about 10 minutes so just get a new one each time. Will raise an error if there is an issue with the authentication.

Returns:

  • the authentication token for the current user.



112
113
114
115
116
117
118
119
# File 'lib/vagrant-zanzibar.rb', line 112

def get_token
  response = @@client.request( :wsdl, :authenticate) { soap.body =  { username: @@username, password: @@password, organization: '', domain: @@domain }}
    .hash[:envelope][:body][:authenticate_response][:authenticate_result]
  abort("Error generating the authentication token for user #{@@username}: #{response[:errors][:string]}")  if response[:errors]
  response[:token]
rescue Savon::Error => err
  raise "There was an error generating the authentiaton token for user #{@@username}: #{err}"
end

#init_client(globals = {}) ⇒ Object

Initializes the Savon client class variable with the wdsl document location and optional global variables

Parameters:

  • globals{},

    optional



46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/vagrant-zanzibar.rb', line 46

def init_client(globals = {})
  globals = {} if globals.nil?
  Savon.configure do |config|
    config.log = false
  end
  @@client = Savon::Client.new(@@wsdl) do
    #wsdl.endpoint  = "https://scrt.vistaprint.net/webservices/sswebservice.asmx"
    #wsdl.namespace = "thesecretserver.com"
    http.auth.ssl.verify_mode = :none
    HTTPI.log = false
  end
  #@@client.log = false
  #@@client.http.auth.ssl.verify_mode = :none
end

#prompt_for_domainString

Gets the domain of the Secret Server installation if none is provided in the constructor

Returns:

  • (String)

    the domain of the secret server installation



80
81
82
83
# File 'lib/vagrant-zanzibar.rb', line 80

def prompt_for_domain
  puts 'Enter the domain of your Secret Server:'
  STDIN.gets.chomp
end

#prompt_for_passwordString

Gets the user’s password if none is provided in the constructor.

Returns:

  • (String)

    the password for the current user



64
65
66
67
# File 'lib/vagrant-zanzibar.rb', line 64

def prompt_for_password
  puts "Please enter password for #{@@username}:"
  STDIN.noecho(&:gets).chomp
end

#prompt_for_wsdl_locationString

Gets the wsdl document location if none is provided in the constructor

Returns:

  • (String)

    the location of the WDSL document



72
73
74
75
# File 'lib/vagrant-zanzibar.rb', line 72

def prompt_for_wsdl_location
  puts 'Enter the URL of the Secret Server WSDL:'
  STDIN.gets.chomp
end

#write_secret_to_file(path, secret_response) ⇒ Object



149
150
151
152
153
# File 'lib/vagrant-zanzibar.rb', line 149

def write_secret_to_file(path, secret_response)
  File.open(File.join(path, secret_response[:file_name]), 'wb') do |file|
    file.puts Base64.decode64(secret_response[:file_attachment])
  end
end