lib/zanzibar.rb
require 'zanzibar/version'
require 'savon'
require 'io/console'
require 'fileutils'
require 'yaml'
require 'zanzibar/client'
module Zanzibar
##
# High-level operations for downloading things from Secret Server
class Zanzibar
##
# @param args{:domain, :wsdl, :pwd, :username, :globals{}}
def initialize(args = {})
@username = resolve_username(args)
@wsdl = resolve_wsdl(args)
@password = resolve_password(args)
@domain = resolve_domain(args)
args[:globals] = {} unless args[:globals]
@client = Client.new(@username, @password, @domain, @wsdl, args[:globals])
end
##
# Gets the user's password if none is provided in the constructor.
# @return [String] the password for the current user
def prompt_for_password
puts "Please enter password for #{@username}:"
STDIN.noecho(&:gets).chomp.tap do
puts 'Using password to login...'
end
end
##
# Gets the wsdl document location if none is provided in the constructor
# @return [String] the location of the WDSL document
def prompt_for_wsdl_location
puts 'Enter the URL of the Secret Server WSDL:'
STDIN.gets.chomp
end
##
# Gets the domain of the Secret Server installation if none is provided in the constructor
# @return [String] the domain of the secret server installation
def prompt_for_domain
puts 'Enter the domain of your Secret Server:'
STDIN.gets.chomp
end
##
# Retrieve the value from a field label of a secret
# Will raise an error if there are any issues
# @param [Integer] the secret id
# @param [String] the field label to get, defaults to Password
# @return [String] the value for the given field label
def get_fieldlabel_value(scrt_id, fieldlabel = 'Password')
secret = @client.get_secret(scrt_id)
secret_items = secret[:secret][:items][:secret_item]
return @client.get_secret_item_by_field_name(secret_items, fieldlabel)[:value]
rescue Savon::Error => err
raise "There was an error getting '#{fieldlabel}' for secret #{scrt_id}: #{err}"
end
##
# Retrieve a simple password from a secret
# Calls get get_fieldlabel_value()
# @param [Integer] the secret id
# @return [String] the password for the given secret
def get_password(scrt_id)
get_fieldlabel_value(scrt_id)
end
##
# Get the password, save it to a file, and return the path to the file.
def get_username_and_password_and_save(scrt_id, path, name)
secret_items = @client.get_secret(scrt_id)[:secret][:items][:secret_item]
password = @client.get_secret_item_by_field_name(secret_items, 'Password')[:value]
username = @client.get_secret_item_by_field_name(secret_items, 'Username')[:value]
save_username_and_password_to_file(password, username, path, name)
File.join(path, name)
end
##
# Write the password to a file. Intended for use with a Zanzifile
def save_username_and_password_to_file(password, username, path, name)
user_pass = { 'username' => username.to_s, 'password' => password.to_s }.to_yaml
File.open(File.join(path, name), 'wb') do |file|
file.print user_pass
end
end
##
# Downloads a file for a secret and places it where Zanzibar is running, or :path if specified
# Raise on error
# @param [Hash] args, :scrt_id, :type (one of "Private Key", "Public Key", "Attachment"), :scrt_item_id - optional, :path - optional
def download_secret_file(args = {})
response = @client.download_file_attachment_by_item_id(args[:scrt_id], args[:scrt_item_id], args[:type])
raise "There was an error getting the #{args[:type]} for secret #{args[:scrt_id]}: #{response[:errors][:string]}" if response[:errors]
return write_secret_to_file(args[:path], response)
rescue Savon::Error => err
raise "There was an error getting the #{args[:type]} for secret #{args[:scrt_id]}: #{err}"
end
##
# Download a private key secret
# @deprecated
def download_private_key(args = {})
args[:type] = 'Private Key'
download_secret_file(args)
end
##
# Download a public key secret
# @deprecated
def download_public_key(args = {})
args[:type] = 'Public Key'
download_secret_file(args)
end
##
# Download an arbitrary secret attachment
# @deprecated
def download_attachment(args = {})
args[:type] = 'Attachment'
download_secret_file(args)
end
private
def make_or_find_path(path = nil)
FileUtils.mkdir_p(path) if path
path || '.'
end
def resolve_username(args = {})
if args[:username]
args[:username]
elsif ENV['ZANZIBAR_USER']
ENV['ZANZIBAR_USER']
else
ENV['USER']
end
end
def resolve_wsdl(args = {})
args[:wsdl]
end
def resolve_password(args = {})
if args[:pwd]
args[:pwd]
elsif ENV['ZANZIBAR_PASSWORD']
ENV['ZANZIBAR_PASSWORD']
else
prompt_for_password
end
end
def resolve_domain(args = {})
if args[:domain]
args[:domain]
else
prompt_for_domain
end
end
def write_secret_to_file(path, secret_response)
path = make_or_find_path(path)
filepath = File.join(path, secret_response[:file_name])
File.open(filepath, 'wb') do |file|
file.puts Base64.decode64(secret_response[:file_attachment])
end
filepath
end
end
end