Initiaize Repo

This commit is contained in:
Jason Davis-Cooke
2015-01-12 10:49:59 -05:00
commit 728f727dc7
19 changed files with 1352 additions and 0 deletions

14
.gitignore vendored Normal file
View File

@@ -0,0 +1,14 @@
/.bundle/
/.yardoc
/Gemfile.lock
/_yardoc/
/coverage/
/doc/
/pkg/
/spec/reports/
/tmp/
*.bundle
*.so
*.o
*.a
mkmf.log

9
Gemfile Normal file
View File

@@ -0,0 +1,9 @@
source 'https://rubygems.org'
gem 'savon'
gem 'savon_spec'
gem 'rspec'
gem 'webmock'
# Specify your gem's dependencies in zanzibar.gemspec
gemspec

13
LICENSE.txt Normal file
View File

@@ -0,0 +1,13 @@
Copyright (c) 2015 Cimpress
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

60
README.md Normal file
View File

@@ -0,0 +1,60 @@
# Zanzibar
Zanzibar is a utility to retrieve secrets from a Secret Server installation. It supports retrieval of a password, public/private key, or secret attachment.
## Installation
Add this line to your application's Gemfile:
```ruby
gem 'zanzibar'
```
And then execute:
$ bundle
Or install it yourself as:
$ gem install zanzibar
## Usage
In your ruby project, rakefile, etc., create a new Zanzibar object. The constructor takes a hash of optional parameters for the WSDL location, the domain of the Secret Server, a hash of global variables to pass to savon (necessary for windows environments with self-signed certs) and a password for the current user (intended to be passed in through some encryption method, unless you really want a plaintext password there.). All of these parameters are optional and the user will be prompted to enter them if they are missing.
```ruby
my_object = Zanzibar::Zanzibar.new(:domain => 'my.domain.net', :wsdl => 'my.scrt.srvr.com/webservices/sswebservice.asmx?wdsl', :pwd => get_encrypted_password_from_somewhere)
```
Example:
```ruby
require 'zanzibar'
## Constructor takes hash as argument, all optional :domain, :wsdl, :pwd, :globals
secrets = Zanzibar::Zanzibar.new(:domain => 'mydomain.net', :wsdl => "https://my.scrt.server/webservices/sswebservice.asmx?wsdl")
# On windows with self-signed certs,
# Zanzibar::Zanzibar.new(:domain => 'mydomain.net', :wsdl => "https://my.scrt.server/webservices/sswebservice.asmx?wsdl", :globals => {:ssl_verify_mode => :none})
## Simple password -> takes secret id as argument
secrets.get_secret(1234)
## Private Key -> takes hash as argument, requires :scrt_id, optional :scrt_item_id, :path
secrets.download_private_key(:scrt_id => 2345, :path => 'secrets/')
## Public Key -> takes hash as argument, requires :scrt_id, optional :scrt_item_id, :path
secrets.download_public_key(:scrt_id => 2345, :path => 'secrets/')
## Attachment; only supports secrets with single attachment -> takes hash as argument, requires :scrt_id, optional :scrt_item_id, :path
secrets.download_attachment(:scrt_id => 3456, :path => 'secrets/')
```
## Contributing
1. Fork it ( https://github.com/Cimpress-MCP/zanzibar/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request

10
Rakefile Normal file
View File

@@ -0,0 +1,10 @@
require "bundler/gem_tasks"
task 'test' do
Dir.chdir('test')
system("rspec zanzibar_spec.rb")
end
task 'install_dependencies' do
system('bundle install')
end

209
lib/zanzibar.rb Normal file
View File

@@ -0,0 +1,209 @@
require "zanzibar/version"
require 'savon'
require 'io/console'
require 'fileutils'
module Zanzibar
##
# Class for interacting with Secret Server
class Zanzibar
##
# @param args{:domain, :wsdl, :pwd, :globals{}}
def initialize(args = {})
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
## Initializes the Savon client class variable with the wdsl document location and optional global variables
# @param globals{}, optional
def init_client(globals = {})
globals = {} if globals == nil
@@client = Savon.client(globals) do
wsdl @@wsdl
end
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 #{ENV['USER']}:"
return STDIN.noecho(&:gets).chomp
end
## Gets the wsdl document location if none is provided in the constructor
# @return [String] the location of the WDSL document
def get_wsdl_location
puts "Enter the URL of the Secret Server WSDL:"
return 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:"
return STDIN.gets.chomp
end
## 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.
# @return the authentication token for the current user.
def get_token
begin
response = @@client.call(:authenticate, message: { username: ENV['USER'], password: @@password, organization: "", domain: @@domain }).hash
if response[:envelope][:body][:authenticate_response][:authenticate_result][:errors]
raise "Error generating the authentication token for user #{ENV['USER']}: #{response[:envelope][:body][:authenticate_response][:authenticate_result][:errors][:string]}"
end
response[:envelope][:body][:authenticate_response][:authenticate_result][:token]
rescue Savon::Error => err
raise "There was an error generating the authentiaton token for user #{ENV['USER']}: #{err}"
end
end
## Get a secret returned as a hash
# Will raise an error if there was an issue getting the secret
# @param [Integer] the secret id
# @return [Hash] the secret hash retrieved from the wsdl
def get_secret(scrt_id, token = nil)
begin
secret = @@client.call(:get_secret, message: { token: token || get_token, secretId: scrt_id}).hash
if secret[:envelope][:body][:get_secret_response][:get_secret_result][:errors]
raise "There was an error getting secret #{scrt_id}: #{secret[:envelope][:body][:get_secret_response][:get_secret_result][:errors][:string]}"
end
return secret
rescue Savon::Error => err
raise "There was an error getting the secret with id #{scrt_id}: #{err}"
end
end
## Retrieve a simple password from a secret
# Will raise an error if there are any issues
# @param [Integer] the secret id
# @return [String] the password for the given secret
def get_password(scrt_id)
begin
secret = get_secret(scrt_id)
return secret[:envelope][:body][:get_secret_response][:get_secret_result][:secret][:items][:secret_item][1][:value]
rescue Savon::Error => err
raise "There was an error getting the password for secret #{scrt_id}: #{err}"
end
end
## Get the secret item id that relates to a key file or attachment.
# Will raise on error
# @param [Integer] the secret id
# @param [String] the type of secret item to get, one of privatekey, publickey, attachment
# @return [Integer] the secret item id
def get_scrt_item_id(scrt_id, type, token)
secret = get_secret(scrt_id, token)
case type
when 'privatekey'
## Get private key item id
secret[:envelope][:body][:get_secret_response][:get_secret_result][:secret][:items][:secret_item].each do |item|
return item[:id] if item[:field_name] == 'Private Key'
end
when 'publickey'
## Get public key item id
secret[:envelope][:body][:get_secret_response][:get_secret_result][:secret][:items][:secret_item].each do |item|
return item[:id] if item[:field_name] == 'Public Key'
end
when 'attachment'
## Get attachment item id. This currently only supports secrets with one attachment.
secret[:envelope][:body][:get_secret_response][:get_secret_result][:secret][:items][:secret_item].each do |item|
return item[:id] if item[:field_name] == 'Attachment'
end
else
raise "Unknown type, #{type}."
end
end
## Downloads the private key for a secret and places it where Zanzibar is running, or :path if specified
# Raise on error
# @param [Hash] args, :scrt_id, :scrt_item_id - optional, :path - optional
def download_private_key(args = {})
token = get_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.call(:download_file_attachment_by_item_id, message: { token: token, secretId: args[:scrt_id], secretItemId: args[:scrt_item_id] || get_scrt_item_id(args[:scrt_id], 'privatekey', token)}).hash
if response[:envelope][:body][:download_file_attachment_by_item_id_response][:download_file_attachment_by_item_id_result][:errors]
raise "There was an error getting the private key for secret #{args[:scrt_id]}: #{response[:envelope][:body][:download_file_attachment_by_item_id_response][:download_file_attachment_by_item_id_result][:string]}"
end
File.open(File.join(path, response[:envelope][:body][:download_file_attachment_by_item_id_response][:download_file_attachment_by_item_id_result][:file_name]), 'wb') do |file|
file.puts Base64.decode64(response[:envelope][:body][:download_file_attachment_by_item_id_response][:download_file_attachment_by_item_id_result][:file_attachment])
end
rescue Savon::Error => err
raise "There was an error getting the private key for secret #{args[:scrt_id]}: #{err}"
end
end
## Downloads the public key for a secret and places it where Zanzibar is running, or :path if specified
# Raise on error
# @param [Hash] args, :scrt_id, :scrt_item_id - optional, :path - optional
def download_public_key(args = {})
token = get_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.call(:download_file_attachment_by_item_id, message: { token: token, secretId: args[:scrt_id], secretItemId: args[:scrt_item_id] || get_scrt_item_id(args[:scrt_id], 'publickey', token)}).hash
if response[:envelope][:body][:download_file_attachment_by_item_id_response][:download_file_attachment_by_item_id_result][:errors]
raise "There was an error getting the public key for secret #{args[:scrt_id]}: #{response[:envelope][:body][:download_file_attachment_by_item_id_response][:download_file_attachment_by_item_id_result][:string]}"
end
File.open(File.join(path, response[:envelope][:body][:download_file_attachment_by_item_id_response][:download_file_attachment_by_item_id_result][:file_name]), 'wb') do |file|
file.puts Base64.decode64(response[:envelope][:body][:download_file_attachment_by_item_id_response][:download_file_attachment_by_item_id_result][:file_attachment])
end
rescue Savon::Error => err
raise "There was an error getting the public key for secret #{args[:scrt_id]}: #{err}"
end
end
## Downloads an attachment for a secret and places it where Zanzibar is running, or :path if specified
# Raise on error
# @param [Hash] args, :scrt_id, :scrt_item_id - optional, :path - optional
def download_attachment(args = {})
token = get_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.call(:download_file_attachment_by_item_id, message: { token: token, secretId: args[:scrt_id], secretItemId: args[:scrt_item_id] || get_scrt_item_id(args[:scrt_id], 'attachment', token)}).hash
if response[:envelope][:body][:download_file_attachment_by_item_id_response][:download_file_attachment_by_item_id_result][:errors]
raise "There was an error getting the attachment for secret #{args[:scrt_id]}: #{response[:envelope][:body][:download_file_attachment_by_item_id_response][:download_file_attachment_by_item_id_result][:string]}"
end
File.open(File.join(path, response[:envelope][:body][:download_file_attachment_by_item_id_response][:download_file_attachment_by_item_id_result][:file_name]), 'wb') do |file|
file.puts Base64.decode64(response[:envelope][:body][:download_file_attachment_by_item_id_response][:download_file_attachment_by_item_id_result][:file_attachment])
end
rescue Savon::Error => err
raise "There was an error getting the attachment from secret #{args[:scrt_id]}: #{err}"
end
end
end
end

3
lib/zanzibar/version.rb Normal file
View File

@@ -0,0 +1,3 @@
module Zanzibar
VERSION = "0.0.8"
end

2
test/.rspec Normal file
View File

@@ -0,0 +1,2 @@
--color
--require spec_helper

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<DownloadFileAttachmentByItemIdResponse xmlns="urn:thesecretserver.com">
<DownloadFileAttachmentByItemIdResult>
<Errors />
<FileAttachment>SSBhbSBhIHNlY3JldCBhdHRhY2htZW50</FileAttachment>
<FileName>attachment.txt</FileName>
</DownloadFileAttachmentByItemIdResult>
</DownloadFileAttachmentByItemIdResponse>
</soap:Body>
</soap:Envelope>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<AuthenticateResponse xmlns="urn:thesecretserver.com">
<AuthenticateResult>
<Errors>
</Errors>
<Token>imatoken</Token>
</AuthenticateResult>
</AuthenticateResponse>
</soap:Body>
</soap:Envelope>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<DownloadFileAttachmentByItemIdResponse xmlns="urn:thesecretserver.com">
<DownloadFileAttachmentByItemIdResult>
<Errors />
<FileAttachment>LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVkgLS0tLS0KemFuemliYXJUZXN0UGFzc3dvcmQKLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0=</FileAttachment>
<FileName>zanzi_key</FileName>
</DownloadFileAttachmentByItemIdResult>
</DownloadFileAttachmentByItemIdResponse>
</soap:Body>
</soap:Envelope>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<DownloadFileAttachmentByItemIdResponse xmlns="urn:thesecretserver.com">
<DownloadFileAttachmentByItemIdResult>
<Errors />
<FileAttachment>MTIzNFB1YmxpY0tleTU2Nzg9PQ==</FileAttachment>
<FileName>zanzi_key.pub</FileName>
</DownloadFileAttachmentByItemIdResult>
</DownloadFileAttachmentByItemIdResponse>
</soap:Body>
</soap:Envelope>

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetSecretResponse xmlns="urn:thesecretserver.com">
<GetSecretResult>
<Errors />
<Secret>
<Name>Zanzi Test Secret</Name>
<Items>
<SecretItem>
<Value>ZanziUser</Value>
<Id>15391</Id>
<FieldId>284</FieldId>
<FieldName>Username</FieldName>
<IsFile>false</IsFile>
<IsNotes>false</IsNotes>
<IsPassword>false</IsPassword>
<FieldDisplayName>Username</FieldDisplayName>
</SecretItem>
<SecretItem>
<Value>zanziUserPassword</Value>
<Id>15392</Id>
<FieldId>285</FieldId>
<FieldName>Password</FieldName>
<IsFile>false</IsFile>
<IsNotes>false</IsNotes>
<IsPassword>true</IsPassword>
<FieldDisplayName>Password</FieldDisplayName>
</SecretItem>
<SecretItem>
<Value />
<Id>15395</Id>
<FieldId>287</FieldId>
<FieldName>Attachment</FieldName>
<IsFile>true</IsFile>
<IsNotes>false</IsNotes>
<IsPassword>false</IsPassword>
<FieldDisplayName>Attachment</FieldDisplayName>
</SecretItem>
</Items>
<Id>1234</Id>
<SecretTypeId>6028</SecretTypeId>
<FolderId>106</FolderId>
<IsWebLauncher>false</IsWebLauncher>
<Active>true</Active>
<CheckOutMinutesRemaining xsi:nil="true" />
<IsCheckedOut xsi:nil="true" />
<CheckOutUserDisplayName />
<CheckOutUserId xsi:nil="true" />
<IsOutOfSync xsi:nil="true" />
<IsRestricted>false</IsRestricted>
<OutOfSyncReason />
</Secret>
</GetSecretResult>
</GetSecretResponse>
</soap:Body>
</soap:Envelope>

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetSecretResponse xmlns="urn:thesecretserver.com">
<GetSecretResult>
<Errors />
<Secret>
<Name>Zanzi Secret Attachment</Name>
<Items>
<SecretItem>
<Value>N/A</Value>
<Id>20144</Id>
<FieldId>284</FieldId>
<FieldName>Username</FieldName>
<IsFile>false</IsFile>
<IsNotes>false</IsNotes>
<IsPassword>false</IsPassword>
<FieldDisplayName>Username</FieldDisplayName>
</SecretItem>
<SecretItem>
<Value>N/A</Value>
<Id>20145</Id>
<FieldId>285</FieldId>
<FieldName>Password</FieldName>
<IsFile>false</IsFile>
<IsNotes>false</IsNotes>
<IsPassword>true</IsPassword>
<FieldDisplayName>Password</FieldDisplayName>
</SecretItem>
<SecretItem>
<Value />
<Id>20148</Id>
<FieldId>287</FieldId>
<FieldName>Attachment</FieldName>
<IsFile>true</IsFile>
<IsNotes>false</IsNotes>
<IsPassword>false</IsPassword>
<FieldDisplayName>Attachment</FieldDisplayName>
</SecretItem>
</Items>
<Id>3456</Id>
<SecretTypeId>6028</SecretTypeId>
<FolderId>85</FolderId>
<IsWebLauncher>false</IsWebLauncher>
<Active>true</Active>
<CheckOutMinutesRemaining xsi:nil="true" />
<IsCheckedOut xsi:nil="true" />
<CheckOutUserDisplayName />
<CheckOutUserId xsi:nil="true" />
<IsOutOfSync xsi:nil="true" />
<IsRestricted>false</IsRestricted>
<OutOfSyncReason />
</Secret>
</GetSecretResult>
</GetSecretResponse>
</soap:Body>
</soap:Envelope>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetSecretResponse xmlns="urn:thesecretserver.com">
<GetSecretResult>
<Errors />
<Secret>
<Name>Zanzibar Test Keys</Name>
<Items>
<SecretItem>
<Value />
<Id>15214</Id>
<FieldId>486</FieldId>
<FieldName>Private Key</FieldName>
<IsFile>true</IsFile>
<IsNotes>false</IsNotes>
<IsPassword>false</IsPassword>
<FieldDisplayName>Private Key</FieldDisplayName>
</SecretItem>
<SecretItem>
<Value />
<Id>15215</Id>
<FieldId>487</FieldId>
<FieldName>Public Key</FieldName>
<IsFile>true</IsFile>
<IsNotes>false</IsNotes>
<IsPassword>false</IsPassword>
<FieldDisplayName>Public Key</FieldDisplayName>
</SecretItem>
</Items>
<Id>2345</Id>
<SecretTypeId>6054</SecretTypeId>
<FolderId>85</FolderId>
<IsWebLauncher>false</IsWebLauncher>
<Active>true</Active>
<CheckOutMinutesRemaining xsi:nil="true" />
<IsCheckedOut xsi:nil="true" />
<CheckOutUserDisplayName />
<CheckOutUserId xsi:nil="true" />
<IsOutOfSync xsi:nil="true" />
<IsRestricted>false</IsRestricted>
<OutOfSyncReason />
</Secret>
</GetSecretResult>
</GetSecretResponse>
</soap:Body>
</soap:Envelope>

629
test/scrt.wsdl Normal file
View File

@@ -0,0 +1,629 @@
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="urn:thesecretserver.com" xmlns:s1="urn:thesecretserver.com/AbstractTypes" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" targetNamespace="urn:thesecretserver.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Webservice for standard integration.</wsdl:documentation>
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="urn:thesecretserver.com">
<s:complexType name="GenericResult">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="ErrorMessage" type="s:string" />
</s:sequence>
</s:complexType>
<s:element name="Authenticate">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="username" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="password" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="organization" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="domain" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="AuthenticateResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="AuthenticateResult" type="tns:AuthenticateResult" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="AuthenticateResult">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Errors" type="tns:ArrayOfString" />
<s:element minOccurs="0" maxOccurs="1" name="Token" type="s:string" />
</s:sequence>
</s:complexType>
<s:complexType name="ArrayOfString">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="s:string" />
</s:sequence>
</s:complexType>
<s:complexType name="GetSecretResult">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Errors" type="tns:ArrayOfString" />
<s:element minOccurs="0" maxOccurs="1" name="SecretError" type="tns:SecretError" />
<s:element minOccurs="0" maxOccurs="1" name="Secret" type="tns:Secret" />
</s:sequence>
</s:complexType>
<s:complexType name="SecretError">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="ErrorCode" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="ErrorMessage" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="AllowsResponse" type="s:boolean" />
<s:element minOccurs="0" maxOccurs="1" name="CommentTitle" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="AdditionalCommentTitle" type="s:string" />
</s:sequence>
</s:complexType>
<s:complexType name="Secret">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Items" type="tns:ArrayOfSecretItem" />
<s:element minOccurs="1" maxOccurs="1" name="Id" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="SecretTypeId" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="FolderId" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="IsWebLauncher" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="Active" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="CheckOutMinutesRemaining" nillable="true" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="IsCheckedOut" nillable="true" type="s:boolean" />
<s:element minOccurs="0" maxOccurs="1" name="CheckOutUserDisplayName" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="CheckOutUserId" nillable="true" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="IsOutOfSync" nillable="true" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="IsRestricted" nillable="true" type="s:boolean" />
<s:element minOccurs="0" maxOccurs="1" name="OutOfSyncReason" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="SecretSettings" type="tns:SecretSettings" />
<s:element minOccurs="0" maxOccurs="1" name="SecretPermissions" type="tns:SecretPermissions" />
</s:sequence>
</s:complexType>
<s:complexType name="ArrayOfSecretItem">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="SecretItem" nillable="true" type="tns:SecretItem" />
</s:sequence>
</s:complexType>
<s:complexType name="SecretItem">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Value" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="Id" nillable="true" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="FieldId" nillable="true" type="s:int" />
<s:element minOccurs="0" maxOccurs="1" name="FieldName" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="IsFile" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="IsNotes" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="IsPassword" type="s:boolean" />
<s:element minOccurs="0" maxOccurs="1" name="FieldDisplayName" type="s:string" />
</s:sequence>
</s:complexType>
<s:complexType name="SecretSettings">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="AutoChangeEnabled" nillable="true" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="RequiresApprovalForAccess" nillable="true" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="RequiresComment" nillable="true" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="CheckOutEnabled" nillable="true" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="CheckOutChangePasswordEnabled" nillable="true" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="PrivilegedSecretId" nillable="true" type="s:int" />
<s:element minOccurs="0" maxOccurs="1" name="AssociatedSecretIds" type="tns:ArrayOfInt" />
<s:element minOccurs="0" maxOccurs="1" name="Approvers" type="tns:ArrayOfGroupOrUserRecord" />
<s:element minOccurs="1" maxOccurs="1" name="IsChangeToSettings" type="s:boolean" />
</s:sequence>
</s:complexType>
<s:complexType name="ArrayOfInt">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="int" type="s:int" />
</s:sequence>
</s:complexType>
<s:complexType name="ArrayOfGroupOrUserRecord">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="GroupOrUserRecord" nillable="true" type="tns:GroupOrUserRecord" />
</s:sequence>
</s:complexType>
<s:complexType name="GroupOrUserRecord">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="DomainName" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="IsUser" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="GroupId" nillable="true" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="UserId" nillable="true" type="s:int" />
</s:sequence>
</s:complexType>
<s:complexType name="SecretPermissions">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="CurrentUserHasView" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="CurrentUserHasEdit" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="CurrentUserHasOwner" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="InheritPermissionsEnabled" nillable="true" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="IsChangeToPermissions" type="s:boolean" />
<s:element minOccurs="0" maxOccurs="1" name="Permissions" type="tns:ArrayOfPermission" />
</s:sequence>
</s:complexType>
<s:complexType name="ArrayOfPermission">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="Permission" nillable="true" type="tns:Permission" />
</s:sequence>
</s:complexType>
<s:complexType name="Permission">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="UserOrGroup" type="tns:GroupOrUserRecord" />
<s:element minOccurs="1" maxOccurs="1" name="View" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="Edit" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="Owner" type="s:boolean" />
</s:sequence>
</s:complexType>
<s:element name="GetSecret">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="token" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="secretId" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="loadSettingsAndPermissions" nillable="true" type="s:boolean" />
<s:element minOccurs="0" maxOccurs="1" name="codeResponses" type="tns:ArrayOfCodeResponse" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="ArrayOfCodeResponse">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="CodeResponse" nillable="true" type="tns:CodeResponse" />
</s:sequence>
</s:complexType>
<s:complexType name="CodeResponse">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="ErrorCode" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Comment" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="AdditionalComment" type="s:string" />
</s:sequence>
</s:complexType>
<s:element name="GetSecretResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="GetSecretResult" type="tns:GetSecretResult" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="WebServiceResult">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Errors" type="tns:ArrayOfString" />
</s:sequence>
</s:complexType>
<s:element name="GetSecretsByFieldValue">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="token" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="fieldName" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="searchTerm" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="showDeleted" type="s:boolean" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="GetSecretsByFieldValueResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="GetSecretsByFieldValueResult" type="tns:GetSecretsByFieldValueResult" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="GetSecretsByFieldValueResult">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Errors" type="tns:ArrayOfString" />
<s:element minOccurs="0" maxOccurs="1" name="Secrets" type="tns:ArrayOfSecret" />
</s:sequence>
</s:complexType>
<s:complexType name="ArrayOfSecret">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="Secret" nillable="true" type="tns:Secret" />
</s:sequence>
</s:complexType>
<s:element name="DownloadFileAttachment">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="token" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="secretId" type="s:int" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="DownloadFileAttachmentResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="DownloadFileAttachmentResult" type="tns:FileDownloadResult" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="FileDownloadResult">
<s:complexContent mixed="false">
<s:extension base="tns:WebServiceResult">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="FileAttachment" type="s:base64Binary" />
<s:element minOccurs="0" maxOccurs="1" name="FileName" type="s:string" />
</s:sequence>
</s:extension>
</s:complexContent>
</s:complexType>
<s:element name="DownloadFileAttachmentByItemId">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="token" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="secretId" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="secretItemId" type="s:int" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="DownloadFileAttachmentByItemIdResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="DownloadFileAttachmentByItemIdResult" type="tns:FileDownloadResult" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="AuthenticateResult" nillable="true" type="tns:AuthenticateResult" />
<s:element name="GetSecretResult" nillable="true" type="tns:GetSecretResult" />
<s:element name="GetSecretsByFieldValueResult" nillable="true" type="tns:GetSecretsByFieldValueResult" />
<s:element name="FileDownloadResult" nillable="true" type="tns:FileDownloadResult" />
</s:schema>
<s:schema targetNamespace="urn:thesecretserver.com/AbstractTypes">
<s:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
<s:complexType name="StringArray">
<s:complexContent mixed="false">
<s:restriction base="soapenc:Array">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="String" type="s:string" />
</s:sequence>
</s:restriction>
</s:complexContent>
</s:complexType>
</s:schema>
</wsdl:types>
<wsdl:message name="AuthenticateSoapIn">
<wsdl:part name="parameters" element="tns:Authenticate" />
</wsdl:message>
<wsdl:message name="AuthenticateSoapOut">
<wsdl:part name="parameters" element="tns:AuthenticateResponse" />
</wsdl:message>
<wsdl:message name="GetSecretSoapIn">
<wsdl:part name="parameters" element="tns:GetSecret" />
</wsdl:message>
<wsdl:message name="GetSecretSoapOut">
<wsdl:part name="parameters" element="tns:GetSecretResponse" />
</wsdl:message>
<wsdl:message name="GetSecretsByFieldValueSoapIn">
<wsdl:part name="parameters" element="tns:GetSecretsByFieldValue" />
</wsdl:message>
<wsdl:message name="GetSecretsByFieldValueSoapOut">
<wsdl:part name="parameters" element="tns:GetSecretsByFieldValueResponse" />
</wsdl:message>
<wsdl:message name="DownloadFileAttachmentSoapIn">
<wsdl:part name="parameters" element="tns:DownloadFileAttachment" />
</wsdl:message>
<wsdl:message name="DownloadFileAttachmentSoapOut">
<wsdl:part name="parameters" element="tns:DownloadFileAttachmentResponse" />
</wsdl:message>
<wsdl:message name="DownloadFileAttachmentByItemIdSoapIn">
<wsdl:part name="parameters" element="tns:DownloadFileAttachmentByItemId" />
</wsdl:message>
<wsdl:message name="DownloadFileAttachmentByItemIdSoapOut">
<wsdl:part name="parameters" element="tns:DownloadFileAttachmentByItemIdResponse" />
</wsdl:message>
<wsdl:message name="UploadFileAttachmentSoapIn">
<wsdl:part name="parameters" element="tns:UploadFileAttachment" />
</wsdl:message>
<wsdl:message name="UploadFileAttachmentSoapOut">
<wsdl:part name="parameters" element="tns:UploadFileAttachmentResponse" />
</wsdl:message>
<wsdl:message name="UploadFileAttachmentByItemIdSoapIn">
<wsdl:part name="parameters" element="tns:UploadFileAttachmentByItemId" />
</wsdl:message>
<wsdl:message name="UploadFileAttachmentByItemIdSoapOut">
<wsdl:part name="parameters" element="tns:UploadFileAttachmentByItemIdResponse" />
</wsdl:message>
<wsdl:message name="AuthenticateHttpGetIn">
<wsdl:part name="username" type="s:string" />
<wsdl:part name="password" type="s:string" />
<wsdl:part name="organization" type="s:string" />
<wsdl:part name="domain" type="s:string" />
</wsdl:message>
<wsdl:message name="AuthenticateHttpGetOut">
<wsdl:part name="Body" element="tns:AuthenticateResult" />
</wsdl:message>
<wsdl:message name="GetSecretsByFieldValueHttpGetIn">
<wsdl:part name="token" type="s:string" />
<wsdl:part name="fieldName" type="s:string" />
<wsdl:part name="searchTerm" type="s:string" />
<wsdl:part name="showDeleted" type="s:string" />
</wsdl:message>
<wsdl:message name="GetSecretsByFieldValueHttpGetOut">
<wsdl:part name="Body" element="tns:GetSecretsByFieldValueResult" />
</wsdl:message>
<wsdl:message name="DownloadFileAttachmentHttpGetIn">
<wsdl:part name="token" type="s:string" />
<wsdl:part name="secretId" type="s:string" />
</wsdl:message>
<wsdl:message name="DownloadFileAttachmentHttpGetOut">
<wsdl:part name="Body" element="tns:FileDownloadResult" />
</wsdl:message>
<wsdl:message name="DownloadFileAttachmentByItemIdHttpGetIn">
<wsdl:part name="token" type="s:string" />
<wsdl:part name="secretId" type="s:string" />
<wsdl:part name="secretItemId" type="s:string" />
</wsdl:message>
<wsdl:message name="DownloadFileAttachmentByItemIdHttpGetOut">
<wsdl:part name="Body" element="tns:FileDownloadResult" />
</wsdl:message>
<wsdl:message name="UploadFileAttachmentHttpGetIn">
<wsdl:part name="token" type="s:string" />
<wsdl:part name="secretId" type="s:string" />
<wsdl:part name="fileData" type="s1:StringArray" />
<wsdl:part name="fileName" type="s:string" />
</wsdl:message>
<wsdl:message name="AuthenticateHttpPostIn">
<wsdl:part name="username" type="s:string" />
<wsdl:part name="password" type="s:string" />
<wsdl:part name="organization" type="s:string" />
<wsdl:part name="domain" type="s:string" />
</wsdl:message>
<wsdl:message name="AuthenticateHttpPostOut">
<wsdl:part name="Body" element="tns:AuthenticateResult" />
</wsdl:message>
<wsdl:message name="GetSecretsByFieldValueHttpPostIn">
<wsdl:part name="token" type="s:string" />
<wsdl:part name="fieldName" type="s:string" />
<wsdl:part name="searchTerm" type="s:string" />
<wsdl:part name="showDeleted" type="s:string" />
</wsdl:message>
<wsdl:message name="GetSecretsByFieldValueHttpPostOut">
<wsdl:part name="Body" element="tns:GetSecretsByFieldValueResult" />
</wsdl:message>
<wsdl:message name="DownloadFileAttachmentHttpPostIn">
<wsdl:part name="token" type="s:string" />
<wsdl:part name="secretId" type="s:string" />
</wsdl:message>
<wsdl:message name="DownloadFileAttachmentHttpPostOut">
<wsdl:part name="Body" element="tns:FileDownloadResult" />
</wsdl:message>
<wsdl:message name="DownloadFileAttachmentByItemIdHttpPostIn">
<wsdl:part name="token" type="s:string" />
<wsdl:part name="secretId" type="s:string" />
<wsdl:part name="secretItemId" type="s:string" />
</wsdl:message>
<wsdl:message name="DownloadFileAttachmentByItemIdHttpPostOut">
<wsdl:part name="Body" element="tns:FileDownloadResult" />
</wsdl:message>
<wsdl:portType name="SSWebServiceSoap">
<wsdl:operation name="Authenticate">
<wsdl:input message="tns:AuthenticateSoapIn" />
<wsdl:output message="tns:AuthenticateSoapOut" />
</wsdl:operation>
<wsdl:operation name="GetSecret">
<wsdl:input message="tns:GetSecretSoapIn" />
<wsdl:output message="tns:GetSecretSoapOut" />
</wsdl:operation>
<wsdl:operation name="GetSecretsByFieldValue">
<wsdl:input message="tns:GetSecretsByFieldValueSoapIn" />
<wsdl:output message="tns:GetSecretsByFieldValueSoapOut" />
</wsdl:operation>
<wsdl:operation name="DownloadFileAttachment">
<wsdl:input message="tns:DownloadFileAttachmentSoapIn" />
<wsdl:output message="tns:DownloadFileAttachmentSoapOut" />
</wsdl:operation>
<wsdl:operation name="DownloadFileAttachmentByItemId">
<wsdl:input message="tns:DownloadFileAttachmentByItemIdSoapIn" />
<wsdl:output message="tns:DownloadFileAttachmentByItemIdSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:portType name="SSWebServiceHttpGet">
<wsdl:operation name="Authenticate">
<wsdl:input message="tns:AuthenticateHttpGetIn" />
<wsdl:output message="tns:AuthenticateHttpGetOut" />
</wsdl:operation>
<wsdl:operation name="GetSecretsByFieldValue">
<wsdl:input message="tns:GetSecretsByFieldValueHttpGetIn" />
<wsdl:output message="tns:GetSecretsByFieldValueHttpGetOut" />
</wsdl:operation>
<wsdl:operation name="DownloadFileAttachment">
<wsdl:input message="tns:DownloadFileAttachmentHttpGetIn" />
<wsdl:output message="tns:DownloadFileAttachmentHttpGetOut" />
</wsdl:operation>
<wsdl:operation name="DownloadFileAttachmentByItemId">
<wsdl:input message="tns:DownloadFileAttachmentByItemIdHttpGetIn" />
<wsdl:output message="tns:DownloadFileAttachmentByItemIdHttpGetOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:portType name="SSWebServiceHttpPost">
<wsdl:operation name="Authenticate">
<wsdl:input message="tns:AuthenticateHttpPostIn" />
<wsdl:output message="tns:AuthenticateHttpPostOut" />
</wsdl:operation>
<wsdl:operation name="GetSecretsByFieldValue">
<wsdl:input message="tns:GetSecretsByFieldValueHttpPostIn" />
<wsdl:output message="tns:GetSecretsByFieldValueHttpPostOut" />
</wsdl:operation>
<wsdl:operation name="DownloadFileAttachment">
<wsdl:input message="tns:DownloadFileAttachmentHttpPostIn" />
<wsdl:output message="tns:DownloadFileAttachmentHttpPostOut" />
</wsdl:operation>
<wsdl:operation name="DownloadFileAttachmentByItemId">
<wsdl:input message="tns:DownloadFileAttachmentByItemIdHttpPostIn" />
<wsdl:output message="tns:DownloadFileAttachmentByItemIdHttpPostOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="SSWebServiceSoap" type="tns:SSWebServiceSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="Authenticate">
<soap:operation soapAction="urn:thesecretserver.com/Authenticate" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetSecret">
<soap:operation soapAction="urn:thesecretserver.com/GetSecret" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetSecretsByFieldValue">
<soap:operation soapAction="urn:thesecretserver.com/GetSecretsByFieldValue" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="DownloadFileAttachment">
<soap:operation soapAction="urn:thesecretserver.com/DownloadFileAttachment" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="DownloadFileAttachmentByItemId">
<soap:operation soapAction="urn:thesecretserver.com/DownloadFileAttachmentByItemId" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="SSWebServiceSoap12" type="tns:SSWebServiceSoap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="Authenticate">
<soap12:operation soapAction="urn:thesecretserver.com/Authenticate" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetSecret">
<soap12:operation soapAction="urn:thesecretserver.com/GetSecret" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetSecretsByFieldValue">
<soap12:operation soapAction="urn:thesecretserver.com/GetSecretsByFieldValue" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="DownloadFileAttachment">
<soap12:operation soapAction="urn:thesecretserver.com/DownloadFileAttachment" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="DownloadFileAttachmentByItemId">
<soap12:operation soapAction="urn:thesecretserver.com/DownloadFileAttachmentByItemId" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="SSWebServiceHttpGet" type="tns:SSWebServiceHttpGet">
<http:binding verb="GET" />
<wsdl:operation name="Authenticate">
<http:operation location="/Authenticate" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetSecretsByFieldValue">
<http:operation location="/GetSecretsByFieldValue" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="DownloadFileAttachment">
<http:operation location="/DownloadFileAttachment" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="DownloadFileAttachmentByItemId">
<http:operation location="/DownloadFileAttachmentByItemId" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="SSWebServiceHttpPost" type="tns:SSWebServiceHttpPost">
<http:binding verb="POST" />
<wsdl:operation name="Authenticate">
<http:operation location="/Authenticate" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetSecretsByFieldValue">
<http:operation location="/GetSecretsByFieldValue" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="DownloadFileAttachment">
<http:operation location="/DownloadFileAttachment" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="DownloadFileAttachmentByItemId">
<http:operation location="/DownloadFileAttachmentByItemId" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="SSWebService">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Webservice for standard integration.</wsdl:documentation>
<wsdl:port name="SSWebServiceSoap" binding="tns:SSWebServiceSoap">
<soap:address location="https://www.zanzitest.net/webservices/sswebservice.asmx" />
</wsdl:port>
<wsdl:port name="SSWebServiceSoap12" binding="tns:SSWebServiceSoap12">
<soap12:address location="https://www.zanzitest.net/webservices/sswebservice.asmx" />
</wsdl:port>
<wsdl:port name="SSWebServiceHttpGet" binding="tns:SSWebServiceHttpGet">
<http:address location="https://www.zanzitest.net/webservices/sswebservice.asmx" />
</wsdl:port>
<wsdl:port name="SSWebServiceHttpPost" binding="tns:SSWebServiceHttpPost">
<http:address location="https://www.zanzitest.net/webservices/sswebservice.asmx" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

90
test/spec/spec_helper.rb Normal file
View File

@@ -0,0 +1,90 @@
# This file was generated by the `rspec --init` command. Conventionally, all
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
# The generated `.rspec` file contains `--require spec_helper` which will cause this
# file to always be loaded, without a need to explicitly require it in any files.
#
# Given that it is always loaded, you are encouraged to keep this file as
# light-weight as possible. Requiring heavyweight dependencies from this file
# will add to the boot time of your test suite on EVERY test run, even for an
# individual file that may not need all of that loaded. Instead, consider making
# a separate helper file that requires the additional dependencies and performs
# the additional setup, and require it from the spec files that actually need it.
#
# The `.rspec` file also contains a few flags that are not defaults but that
# users commonly want.
#
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
require 'webmock/rspec'
RSpec.configure do |config|
# rspec-expectations config goes here. You can use an alternate
# assertion/expectation library such as wrong or the stdlib/minitest
# assertions if you prefer.
config.expect_with :rspec do |expectations|
# This option will default to `true` in RSpec 4. It makes the `description`
# and `failure_message` of custom matchers include text for helper methods
# defined using `chain`, e.g.:
# be_bigger_than(2).and_smaller_than(4).description
# # => "be bigger than 2 and smaller than 4"
# ...rather than:
# # => "be bigger than 2"
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
# rspec-mocks config goes here. You can use an alternate test double
# library (such as bogus or mocha) by changing the `mock_with` option here.
config.mock_with :rspec do |mocks|
# Prevents you from mocking or stubbing a method that does not exist on
# a real object. This is generally recommended, and will default to
# `true` in RSpec 4.
mocks.verify_partial_doubles = true
end
# The settings below are suggested to provide a good initial experience
# with RSpec, but feel free to customize to your heart's content.
=begin
# These two settings work together to allow you to limit a spec run
# to individual examples or groups you care about by tagging them with
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
# get run.
config.filter_run :focus
config.run_all_when_everything_filtered = true
# Limits the available syntax to the non-monkey patched syntax that is recommended.
# For more details, see:
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
config.disable_monkey_patching!
# This setting enables warnings. It's recommended, but in some cases may
# be too noisy due to issues in dependencies.
config.warnings = true
# Many RSpec users commonly either run the entire suite or an individual
# file, and it's useful to allow more verbose output when running an
# individual spec file.
if config.files_to_run.one?
# Use the documentation formatter for detailed output,
# unless a formatter has already been configured
# (e.g. via a command-line flag).
config.default_formatter = 'doc'
end
# Print the 10 slowest examples and example groups at the
# end of the spec run, to help surface which specs are running
# particularly slow.
config.profile_examples = 10
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = :random
# Seed global randomization in this process using the `--seed` CLI option.
# Setting this allows you to use `--seed` to deterministically reproduce
# test failures related to randomization by passing the same `--seed` value
# as the one that triggered the failure.
Kernel.srand config.seed
=end
end

80
test/zanzibar_spec.rb Normal file
View File

@@ -0,0 +1,80 @@
require '../lib/zanzibar.rb'
require 'savon'
require 'webmock'
require 'rspec'
require 'webmock/rspec'
include WebMock::API
describe "Zanzibar Test" do
client = Zanzibar::Zanzibar.new(:domain => "zanzitest.net", :pwd=>'password', :wsdl => "scrt.wsdl")
auth_xml = File.read('responses/authenticate_response.xml')
secret_xml = File.read('responses/get_secret_response.xml')
secret_with_key_xml = File.read('responses/get_secret_with_keys_response.xml')
secret_with_attachment_xml = File.read('responses/get_secret_with_attachment_response.xml')
private_key_xml = File.read('responses/download_private_key_response.xml')
public_key_xml = File.read('responses/download_public_key_response.xml')
attachment_xml = File.read('responses/attachment_response.xml')
it 'should return an auth token' do
stub_request(:any, "https://www.zanzitest.net/webservices/sswebservice.asmx").
to_return(:body => auth_xml, :status => 200)
expect(client.get_token).to eq("imatoken")
end
it 'should get a secret' do
stub_request(:any, "https://www.zanzitest.net/webservices/sswebservice.asmx").
to_return(:body => auth_xml, :status => 200).then.
to_return(:body => secret_xml, :status => 200)
expect(client.get_secret(1234)[:envelope][:body][:get_secret_response][:get_secret_result][:secret][:name]).to eq("Zanzi Test Secret")
end
it 'should get a password' do
stub_request(:any, "https://www.zanzitest.net/webservices/sswebservice.asmx").
to_return(:body => auth_xml, :status => 200).then.
to_return(:body => secret_xml, :status => 200)
expect(client.get_password(1234)).to eq("zanziUserPassword")
end
it 'should download a private key' do
stub_request(:any, "https://www.zanzitest.net/webservices/sswebservice.asmx").
to_return(:body => auth_xml, :status => 200).then.
to_return(:body => secret_with_key_xml, :status => 200).then.
to_return(:body => private_key_xml, :status => 200)
client.download_private_key(:scrt_id => 2345)
expect(File.exist? 'zanzi_key')
expect(File.read('zanzi_key')).to eq("-----BEGIN RSA PRIVATE KEY -----\nzanzibarTestPassword\n-----END RSA PRIVATE KEY-----\n")
File.delete('zanzi_key')
end
it 'should download a public key' do
stub_request(:any, "https://www.zanzitest.net/webservices/sswebservice.asmx").
to_return(:body => auth_xml, :status => 200).then.
to_return(:body => secret_with_key_xml, :status => 200).then.
to_return(:body => public_key_xml, :status => 200)
client.download_public_key(:scrt_id => 2345)
expect(File.exist? 'zanzi_key.pub')
expect(File.read('zanzi_key.pub')).to eq("1234PublicKey5678==\n")
File.delete('zanzi_key.pub')
end
it 'should download an attachment' do
stub_request(:any, "https://www.zanzitest.net/webservices/sswebservice.asmx").
to_return(:body => auth_xml, :status => 200).then.
to_return(:body => secret_with_attachment_xml, :status => 200).then.
to_return(:body => attachment_xml, :status => 200)
client.download_attachment(:scrt_id => 3456)
expect(File.exist? 'attachment.txt')
expect(File.read('attachment.txt')).to eq("I am a secret attachment\n")
File.delete('attachment.txt')
end
end

24
zanzibar.gemspec Normal file
View File

@@ -0,0 +1,24 @@
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'zanzibar/version'
Gem::Specification.new do |spec|
spec.name = "zanzibar"
spec.version = Zanzibar::VERSION
spec.authors = ["Jason Davis-Cooke"]
spec.email = ["jdaviscooke@cimpress.com"]
spec.summary = "Retrieve secrets from Secret Server"
spec.description = "Programatically get secrets from Secret Server via the Web Service API"
spec.homepage = "https://github.com/Cimpress-MCP/zanzibar"
spec.license = "Apache 2.0"
spec.files = `git ls-files -z`.split("\x0")
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]
spec.add_development_dependency "bundler", "~> 1.7"
spec.add_development_dependency "rake", "~> 10.0"
spec.add_runtime_dependency "savon", "~> 2.8.0"
end