secreto 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +15 -0
  2. data/lib/secreto.rb +319 -0
  3. metadata +101 -0
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YTJmZjNkNzQyYjVkOTBiMzAxMGQzMmRmY2JkM2E1ZDhjNmRhOGE3Mg==
5
+ data.tar.gz: !binary |-
6
+ ZTk2MTAzZWYyYTkyMGUxZGJhZWI5NGQyYWU5ODRhYzE2NTU1OWRiZA==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ OTJmM2IxMjBkYjgxYjlkMzE4NTA1ZTIzNzQ4ZDk5OGU5NWZkMjM4NmE2Yjkx
10
+ OWZkYzE0Nzk5Njk4YTQ5OWNiMzVlYmM5ZWFjOTI5YjRkNTYwN2I4ZWEwZWY5
11
+ YjA4OTkyOTBmOTQxNzYyZDNiMGMyMTczY2MzYmUwNzJhY2NlNDI=
12
+ data.tar.gz: !binary |-
13
+ NzA2ZmZkMGFjMjZiNzhiZWZhYjg0MTI0NWQ2MDIyYTk5MTMzNGY0ZWZhOGEy
14
+ NjVkM2QyOTZkZDQzMzkyNjJlMjI2MjQwOGVmMWQ4MWZhZDM1NjM3MmE2YjA0
15
+ MDkzODg2ZmQ5NDZjYjJhNjAwMzFjMDZkYTI5ZWQwNDVlYTBiZTM=
@@ -0,0 +1,319 @@
1
+ require 'savon'
2
+ require 'nokogiri'
3
+ require 'crack'
4
+ require 'json'
5
+
6
+ # Secreto is a ruby class to interact with Thycotic Secret Server
7
+ # == Supported Operations
8
+ # * Login
9
+ # * Retrieve a secret
10
+ # * Add a Secret
11
+ # * Add a Folder
12
+ class Secreto
13
+
14
+ # Constructor
15
+ def initialize(wsdl, ssl_verify_mode, ssl_version)
16
+ @@wsdl=wsdl
17
+ @@ssl_verify_mode=ssl_verify_mode
18
+ @@ssl_version=ssl_version
19
+ client = Savon.client(wsdl: @@wsdl, ssl_verify_mode: :none, ssl_version: :TLSv1)
20
+ @@secretTemplates = []
21
+ end
22
+
23
+ # Authenticates with Secret Server
24
+ #
25
+ # ==== Attributes
26
+ #
27
+ # * +username+ - Username for secret Server
28
+ # * +password+ - Password
29
+ # * +domain+ - Domain Name
30
+ def Authenticate(username, password, domain)
31
+ client = Savon.client(wsdl: @@wsdl, ssl_verify_mode: :none, ssl_version: :TLSv1)
32
+
33
+ response = client.call(:authenticate, message: {
34
+ username: username,
35
+ password: password,
36
+ organization: "",
37
+ domain: domain
38
+ })
39
+
40
+ @@token = response.to_hash[:authenticate_response][:authenticate_result][:token]
41
+ getSecretTemplates()
42
+ return @@token
43
+ end
44
+
45
+ def GetTokenIsValid #:nodoc:
46
+ client = Savon.client(wsdl: @@wsdl, ssl_verify_mode: :none, ssl_version: :TLSv1)
47
+ response = client.call(:get_token_is_valid, message: {
48
+ token: @@token
49
+ })
50
+
51
+ return response
52
+ end
53
+
54
+ def GetSecret(secretId) #:nodoc:
55
+ thesame = lambda { |key| key }
56
+
57
+ client = Savon.client(wsdl: @@wsdl, ssl_verify_mode: :none, ssl_version: :TLSv1, convert_request_keys_to: :none) #, convert_response_tags_to: thesame)
58
+ response = client.call(:get_secret, message: {
59
+ token: @@token,
60
+ secretId: secretId,
61
+ })
62
+ doc = Nokogiri::XML.parse(response.to_xml)
63
+ items = doc.xpath('//foo:SecretItem', 'foo' => 'urn:thesecretserver.com')
64
+ node = Hash.new
65
+ node["password"] = getField(items,"Password")
66
+ node["username"] = getField(items,"Username")
67
+ node["host"] = getField(items,"Machine")
68
+ return node
69
+ end
70
+
71
+ def getField(items,field) #:nodoc:
72
+ for item in items
73
+ for child in item.children
74
+ if child.content == field
75
+ for child1 in item.children
76
+ if child1.name == "Value"
77
+ return child1.content
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ def UpdateSecret(secret) #:nodoc:
86
+ client = Savon.client(wsdl: @@wsdl, ssl_verify_mode: :none, ssl_version: :TLSv1)
87
+ # Nokogiri is stripping the 'xsi' prefix which is required, and it also puts a 'default' prefix in, which is disallowed.
88
+ fixedXml = secret.to_s.gsub! 'nil=', 'xsi:nil='
89
+ fixedXml = fixedXml.gsub! 'default:',''
90
+
91
+ response = client.call(:update_secret, xml: fixedXml)
92
+ return response
93
+ end
94
+
95
+ def WhoAmI #:nodoc:
96
+ client = Savon.client(wsdl: @@wsdl, ssl_verify_mode: :none, ssl_version: :TLSv1)
97
+ response = client.call(:who_am_i, message: {
98
+ token: @@token
99
+ })
100
+ return response
101
+ end
102
+
103
+ def VersionGet #:nodoc:
104
+ client = Savon.client(wsdl: @@wsdl, ssl_verify_mode: :none, ssl_version: :TLSv1)
105
+ response = client.call(:version_get, message: {
106
+ token: @@token
107
+ })
108
+ return response
109
+ end
110
+
111
+ # Retrieve the secret Details
112
+ #
113
+ # ==== Attributes
114
+ #
115
+ # * +hostName+ - Name of the Secret to search
116
+ # * +objectType+ - Object Type. For example Machine
117
+ def GetSecretByHostName(hostName,objectType)
118
+ thesame = lambda { |key| hostName }
119
+ client = Savon.client(wsdl: @@wsdl, ssl_verify_mode: :none, ssl_version: :TLSv1, convert_request_keys_to: :none)
120
+ response = client.call(:get_secrets_by_field_value, message: {
121
+ token: @@token,
122
+ fieldName: objectType,
123
+ searchTerm: hostName,
124
+ })
125
+ doc = Nokogiri::XML.parse(response.to_xml)
126
+ items = doc.xpath('//foo:Id', 'foo' => 'urn:thesecretserver.com')
127
+ if not items[0].nil?
128
+ if not items[0].content.nil?
129
+ return GetSecret(items[0].content)
130
+ end
131
+ end
132
+ end
133
+
134
+ # Create a Folder
135
+ #
136
+ # ==== Attributes
137
+ #
138
+ # * +folderName+ - Name of the folder you want to create
139
+ # * +parentFolder+ - Parent Folder Name (Give full path /TOPLEVEL/Folder 1/Folder 2
140
+ def createFolder(folderName,parentFolder)
141
+ thesame = lambda { |key| hostName }
142
+ client = Savon.client(wsdl: @@wsdl, ssl_verify_mode: :none, ssl_version: :TLSv1, convert_request_keys_to: :none)
143
+ parentId = getFolder(parentFolder)
144
+ if parentId.nil?
145
+ print "Parent Folder " + parentFolder + " doesn't exist"
146
+ return nil
147
+ else
148
+ response = client.call(:folder_create, message: {
149
+ token: @@token,
150
+ folderName: folderName,
151
+ parentFolderId: parentId,
152
+ folderTypeId: 1
153
+ })
154
+ doc = Nokogiri::XML.parse(response.to_xml)
155
+ puts doc
156
+ end
157
+ end
158
+
159
+ def getFolder(folderName) #:nodoc:
160
+ client = Savon.client(wsdl: @@wsdl, ssl_verify_mode: :none, ssl_version: :TLSv1, convert_request_keys_to: :none)
161
+ response = client.call(:search_folders, message: {
162
+ token: @@token,
163
+ folderName: folderName,
164
+ })
165
+ doc = Nokogiri::XML.parse(response.to_xml)
166
+ items = doc.xpath('//foo:Folder', 'foo' => 'urn:thesecretserver.com')
167
+ if items.length > 1
168
+ print "The folder " + folderName + " could not be identified uniquely " +
169
+ "Consider specifying full path like /TOPLEVEL/Level 1/Level 2/Folder Name" + "\n"
170
+ return nil
171
+ else
172
+ if not items[0].nil?
173
+ node = Hash.new
174
+ for child in items[0].children
175
+ if child.name == "Name"
176
+ node["name"] = child.content
177
+ elsif child.name == "TypeId"
178
+ node["typeId"] = child.content
179
+ elsif child.name == "Id"
180
+ node["id"] = child.content
181
+ elsif child.name == "ParentFolderId"
182
+ node["parentFolderId"] = child.content
183
+ end
184
+ end
185
+ return node["Id"]
186
+ end
187
+ end
188
+ if folderName.include?"/"
189
+ normalizedFolderName = folderName
190
+ if folderName.start_with?("/")
191
+ normalizedFolderName = folderName.sub("/","")
192
+ end
193
+ splitted = normalizedFolderName.split("/")
194
+ $i = 0
195
+ parentId = -1
196
+ while $i < splitted.length do
197
+ parentId = getFolderId(splitted[$i],parentId)
198
+ $i+=1
199
+ end
200
+ return parentId
201
+ end
202
+ return nil
203
+ end
204
+
205
+ def getFolderId(folderName,parentFolderId) #:nodoc:
206
+ client = Savon.client(wsdl: @@wsdl, ssl_verify_mode: :none, ssl_version: :TLSv1, convert_request_keys_to: :none)
207
+
208
+ response = client.call(:folder_get_all_children, message: {
209
+ token: @@token,
210
+ parentFolderId:parentFolderId,
211
+ })
212
+ doc = Nokogiri::XML.parse(response.to_xml)
213
+ items = doc.xpath('//foo:Folder', 'foo' => 'urn:thesecretserver.com')
214
+ for item in items
215
+ node = Hash.new
216
+ for child in item.children
217
+ node[child.name] = child.content
218
+ end
219
+ if node["Name"] == folderName
220
+ return node["Id"]
221
+ end
222
+ end
223
+ return nil
224
+ end
225
+
226
+ def getSecretTemplates() #:nodoc:
227
+ client = Savon.client(wsdl: @@wsdl, ssl_verify_mode: :none, ssl_version: :TLSv1, convert_request_keys_to: :none)
228
+ response = client.call(:get_secret_templates, message: {
229
+ token: @@token,
230
+ })
231
+ doc = Nokogiri::XML.parse(response.to_xml)
232
+
233
+ secretTemplates = doc.xpath('//foo:SecretTemplates', 'foo' => 'urn:thesecretserver.com')
234
+ myjson = Crack::XML.parse(secretTemplates.to_xml)
235
+ @@secretTemplates = myjson["SecretTemplates"]["SecretTemplate"]
236
+ return nil
237
+ end
238
+
239
+ # Create a Secret
240
+ #
241
+ # ==== Attributes
242
+ #
243
+ # * +folderName+ - Folder Name where secret will be added (Give full path /TOPLEVEL/Folder 1/Folder 2
244
+ # * +secretType+ - Secret Type For ex Password/Active Directory Account
245
+ # * +secretName+ - Name of Secret
246
+ # * +fieldKeys+ - List of Items in secret
247
+ # * +fieldValues+ - Value of secret Items
248
+ def createSecret(folderName,secretType,secretName,fieldKeys,fieldValues)
249
+ if fieldKeys.length != fieldValues.length
250
+ print "For each key there should be a value [" + fieldKeys.join(",") + " != " + fieldValues.join(",") + "]\n"
251
+ return nil
252
+ end
253
+ templateFields = nil
254
+ templateId = nil
255
+ @@secretTemplates.each { |x|
256
+ if x['Name'] == secretType
257
+ templateFields = x['Fields']['SecretField']
258
+ templateId = x['Id']
259
+ break
260
+ end
261
+ }
262
+ if templateFields.nil?
263
+ print "secretType " + secretType + " is not available" + "\n"
264
+ return nil
265
+ else
266
+ #puts templateFields
267
+ fieldIds = []
268
+ fieldKeys.each { |fkey|
269
+ templateFields.each { |field|
270
+ if field['DisplayName'] == fkey
271
+ fieldIds.push(field['Id'])
272
+ end
273
+ }
274
+ }
275
+ if fieldIds.length != fieldKeys.length
276
+ print "Not all secretField were found [" + fieldKeys.join(",") + "]\n"
277
+ return nil
278
+ end
279
+ # All Found
280
+ end
281
+ secretFieldIds = "<ns1:secretFieldIds>"
282
+ fieldIds.each { |fid|
283
+ secretFieldIds = secretFieldIds + "<ns1:int>" + fid.to_s + "</ns1:int>"
284
+ }
285
+ secretFieldIds = secretFieldIds + "</ns1:secretFieldIds>"
286
+
287
+ secretItemValues = "<ns1:secretItemValues>"
288
+ fieldValues.each { |fval|
289
+ secretItemValues = secretItemValues + "<ns1:string>" + fval.to_s + "</ns1:string>"
290
+ }
291
+ secretItemValues = secretItemValues + "</ns1:secretItemValues>"
292
+
293
+
294
+ folderId=getFolder(folderName)
295
+ if folderId.nil?
296
+ print "Folder " + folderName + " is not found"
297
+ return nil
298
+ end
299
+ xmlString = '<?xml version="1.0" encoding="utf-8"?>' +
300
+ '<SOAP-ENV:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:thesecretserver.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">' +
301
+ '<SOAP-ENV:Header/>' +
302
+ ' <ns0:Body>' +
303
+ ' <ns1:AddSecret>' +
304
+ ' <ns1:token><ns1:token>' + @@token.to_s + '</ns1:token>' +
305
+ ' <ns1:secretTypeId>' + templateId + '</ns1:secretTypeId>' +
306
+ ' <ns1:secretName>' + secretName + '</ns1:secretName>' +
307
+ secretFieldIds +
308
+ secretItemValues +
309
+ ' <ns1:folderId>' + folderId + '</ns1:folderId>' +
310
+ ' </ns1:token>' +
311
+ ' </ns1:AddSecret>' +
312
+ ' </ns0:Body>' +
313
+ '</SOAP-ENV:Envelope>'
314
+
315
+ client = Savon.client(wsdl: @@wsdl, ssl_verify_mode: :none, ssl_version: :TLSv1)
316
+ response = client.call(:add_secret, xml: xmlString)
317
+ puts response.to_xml
318
+ end
319
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: secreto
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.6
5
+ platform: ruby
6
+ authors:
7
+ - C S P Nanda
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-04-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: savon
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '2.8'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '2.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: nokogiri
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: crack
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '0.4'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '0.4'
55
+ - !ruby/object:Gem::Dependency
56
+ name: json
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.8'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '1.8'
69
+ description: Supported operations are create Folder, add Secret, Retrieve a secret
70
+ from Thycotic Secret Server
71
+ email: cspnanda@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - lib/secreto.rb
77
+ homepage: https://github.com/cspnanda/secreto
78
+ licenses:
79
+ - MIT
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: 1.9.3
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.4.8
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: Secreto is a gem to interact with Thycotic Secret Server
101
+ test_files: []