Skip to content

Commit 2d1af55

Browse files
author
Shakeel Mohamed
committed
start storage passwords tests
1 parent acbe411 commit 2d1af55

File tree

3 files changed

+180
-10
lines changed

3 files changed

+180
-10
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ examples/*/local
1717
examples/*/metadata
1818
tests/searchcommands_data/log/
1919
tests/searchcommands_data/output/
20+
examples/searchcommands_app/searchcommand_app.log

splunklib/client.py

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,7 @@ def _load_list(self, response):
12961296
self._entity_path(state),
12971297
state=state)
12981298
entities.append(entity)
1299+
12991300
return entities
13001301

13011302
def itemmeta(self):
@@ -1707,22 +1708,24 @@ def __init__(self, service):
17071708
raise ValueError("StoragePasswords cannot have wildcards in namespace.")
17081709
super(StoragePasswords, self).__init__(service, PATH_STORAGE_PASSWORDS, item=StoragePassword)
17091710

1710-
def create(self, name, password):
1711-
""" Creates or edits a storage password by *name*.
1711+
def create(self, realm, username, password):
1712+
""" Creates a storage password.
1713+
1714+
# TODO: add some notes about processing that happens before hitting the REST API
17121715
1713-
:param name: A name of the form "username" or "realm:username".
1716+
:param realm: The credential realm.
1717+
:type name: ``string``
1718+
:param name: The username for the credentials.
1719+
:type name: ``string``
1720+
:param username: The password for the credentials - this is the only part of the credentials that will be stored securely.
17141721
:type name: ``string``
17151722
17161723
:return: The :class:`StoragePassword` object created.
1717-
17181724
"""
1719-
if not isinstance(name, basestring):
1720-
raise ValueError('Invalid name: %s' % repr(name))
1721-
1722-
identity = name.split(':', 1)
1723-
realm, name = identity if len(identity) == 2 else ('', identity)
1725+
if not isinstance(username, basestring):
1726+
raise ValueError("Invalid name: %s" % repr(username))
17241727

1725-
response = self.post(password=password, realm=realm, name=name)
1728+
response = self.post(password=password, realm=realm, name=username)
17261729

17271730
if response.status != 201:
17281731
raise ValueError("Unexpected status code %s returned from creating a stanza" % response.status)
@@ -1733,6 +1736,26 @@ def create(self, name, password):
17331736

17341737
return storage_password
17351738

1739+
"""# TODO: docs
1740+
* realm defaults to empty string
1741+
* username is optional... if realm is the full name
1742+
1743+
"""
1744+
def delete(self, realm, username=None):
1745+
# TODO: encode each component separately
1746+
1747+
if username is None:
1748+
# This case makes the username optional, so
1749+
# the full name can be passed in as realm
1750+
name = realm
1751+
else:
1752+
name = urllib.quote(realm) + ":" + urllib.quote(username)
1753+
1754+
# Append the : expected at the end of the name
1755+
if name[-1] is not ":":
1756+
name = name + ":"
1757+
return Collection.delete(self, name)
1758+
17361759

17371760
class AlertGroup(Entity):
17381761
"""This class represents a group of fired alerts for a saved search. Access

tests/test_storage_passwords.py

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
#!/usr/bin/env python
2+
#
3+
# Copyright 2011-2014 Splunk, Inc.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"): you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
import testlib
18+
import logging
19+
20+
import splunklib.client as client
21+
22+
class TestCreate(testlib.SDKTestCase):
23+
def setUp(self):
24+
self.service = client.connect(**self.opts.kwargs)
25+
self.storage_passwords = self.service.storage_passwords
26+
27+
def tearDown(self):
28+
# Delete all passwords created by SDK tests
29+
for sp in self.storage_passwords:
30+
if "delete-me" in sp.username or "delete-me" in sp.realm:
31+
sp.delete()
32+
33+
def test_create(self):
34+
start_count = len(self.storage_passwords)
35+
realm = testlib.tmpname()
36+
username = testlib.tmpname()
37+
38+
p = self.storage_passwords.create(realm, username, "changeme")
39+
self.assertEqual(start_count + 1, len(self.storage_passwords))
40+
self.assertEqual(p.realm, realm)
41+
self.assertEqual(p.username, username)
42+
self.assertEqual(p.clear_password, "changeme")
43+
self.assertEqual(p.name, realm + ":" + username + ":")
44+
45+
p.delete()
46+
self.assertEqual(start_count, len(self.storage_passwords))
47+
48+
def test_create_norealm(self):
49+
start_count = len(self.storage_passwords)
50+
username = testlib.tmpname()
51+
52+
p = self.storage_passwords.create("", username, "changeme")
53+
self.assertEqual(start_count + 1, len(self.storage_passwords))
54+
self.assertEqual(p.realm, None)
55+
self.assertEqual(p.username, username)
56+
self.assertEqual(p.clear_password, "changeme")
57+
self.assertEqual(p.name, ":" + username + ":")
58+
59+
p.delete()
60+
self.assertEqual(start_count, len(self.storage_passwords))
61+
62+
def test_create_with_colons(self):
63+
start_count = len(self.storage_passwords)
64+
username = testlib.tmpname()
65+
realm = testlib.tmpname()
66+
67+
p = self.storage_passwords.create(":start" + realm, username + ":end", "changeme")
68+
self.assertEqual(start_count + 1, len(self.storage_passwords))
69+
self.assertEqual(p.realm, ":start" + realm)
70+
self.assertEqual(p.username, username + ":end")
71+
self.assertEqual(p.clear_password, "changeme")
72+
self.assertEqual(p.name, "\\:start" + realm + ":" + username + "\\:end:")
73+
74+
p.delete()
75+
self.assertEqual(start_count, len(self.storage_passwords))
76+
77+
realm = ":r:e:a:l:m:"
78+
user = ":u:s:e:r:"
79+
p = self.storage_passwords.create(realm, user, "changeme")
80+
self.assertEqual(start_count + 1, len(self.storage_passwords))
81+
self.assertEqual(p.realm, realm)
82+
self.assertEqual(p.username, user)
83+
self.assertEqual(p.clear_password, "changeme")
84+
self.assertEqual(p.name, "\\:r\\:e\\:a\\:l\\:m\\::\\:u\\:s\\:e\\:r\\::")
85+
86+
p.delete()
87+
self.assertEqual(start_count, len(self.storage_passwords))
88+
89+
90+
def test_update(self):
91+
start_count = len(self.storage_passwords)
92+
realm = testlib.tmpname()
93+
username = testlib.tmpname()
94+
95+
p = self.storage_passwords.create(realm, username, "changeme")
96+
self.assertEqual(start_count + 1, len(self.storage_passwords))
97+
self.assertEqual(p.realm, realm)
98+
self.assertEqual(p.username, username)
99+
self.assertEqual(p.clear_password, "changeme")
100+
self.assertEqual(p.name, realm + ":" + username + ":")
101+
102+
p.update(password="Splunkeroo!")
103+
self.assertEqual(p.clear_password, "changeme")
104+
105+
p.refresh()
106+
self.assertEqual(start_count + 1, len(self.storage_passwords))
107+
self.assertEqual(p.realm, realm)
108+
self.assertEqual(p.username, username)
109+
self.assertEqual(p.clear_password, "Splunkeroo!")
110+
self.assertEqual(p.name, realm + ":" + username + ":")
111+
112+
p.delete()
113+
self.assertEqual(start_count, len(self.storage_passwords))
114+
115+
def test_delete(self):
116+
# TODO: make a bunch of tests for different ways of deleting
117+
start_count = len(self.storage_passwords)
118+
119+
p = self.storage_passwords.create("myfoo", "yourbar2", "changeme")
120+
self.assertEqual(start_count + 1, len(self.storage_passwords))
121+
self.assertEqual(p.realm, "myfoo")
122+
self.assertEqual(p.username, "yourbar2")
123+
self.assertEqual(p.clear_password, "changeme")
124+
self.assertEqual(p.name, "myfoo:yourbar2:")
125+
126+
# TODO: move these tests out
127+
for sp in self.storage_passwords:
128+
self.assertTrue("myfoo:yourbar2" in self.storage_passwords)
129+
# Name works with or without a trailing colon
130+
self.assertTrue("myfoo:yourbar2:" in self.storage_passwords)
131+
132+
self.storage_passwords.delete("myfoo:yourbar2")
133+
self.assertEqual(start_count, len(self.storage_passwords))
134+
135+
self.storage_passwords.create("myfoo", "yourbar2", "changeme")
136+
self.assertEqual(start_count + 1, len(self.storage_passwords))
137+
138+
self.storage_passwords.delete("myfoo:yourbar2:")
139+
self.assertEqual(start_count, len(self.storage_passwords))
140+
141+
if __name__ == "__main__":
142+
try:
143+
import unittest2 as unittest
144+
except ImportError:
145+
import unittest
146+
unittest.main()

0 commit comments

Comments
 (0)