Skip to content

Commit b6d733d

Browse files
committed
Initial Commit
The main realm setup codes lives in `k5test.realm`, while the unit test helper and decorators live in `k5test.unit`.
0 parents  commit b6d733d

File tree

10 files changed

+733
-0
lines changed

10 files changed

+733
-0
lines changed

.gitignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
*.egg-info
2+
*.egg
3+
*~
4+
*.pyc
5+
/build/
6+
*.swp
7+
*.swo
8+
*.so
9+
.tox
10+
dist
11+
**/__pycache__
12+
.eggs
13+
.venv

K5TEST-LICENSE.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Export of this software from the United States of America may
2+
require a specific license from the United States Government.
3+
It is the responsibility of any person or organization contemplating
4+
export to obtain such a license before exporting.
5+
6+
WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
7+
distribute this software and its documentation for any purpose and
8+
without fee is hereby granted, provided that the above copyright
9+
notice appear in all copies and that both that copyright notice and
10+
this permission notice appear in supporting documentation, and that
11+
the name of M.I.T. not be used in advertising or publicity pertaining
12+
to distribution of the software without specific, written prior
13+
permission. Furthermore if you modify this software you must label
14+
your software as modified software and not distribute it in such a
15+
fashion that it might be confused with the original M.I.T. software.
16+
M.I.T. makes no representations about the suitability of
17+
this software for any purpose. It is provided "as is" without express
18+
or implied warranty.

LICENSE.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
NOTE: The file k5test/realm.py falls under the MIT License. See the file K5TEST-LICENSE.txt for the full text.
2+
3+
Copyright (c) 2015, The Python GSSAPI Team
4+
5+
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
6+
7+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

MANIFEST.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
include *.txt
2+
include *.md

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
K5Test
2+
======
3+
4+
*k5test* is a library for setting up self-contained Kerberos 5 environments,
5+
and running Python unit tests inside those environments. It is based on
6+
the file of the same name found alongside the MIT Kerberos 5 unit tests.
7+
8+
Using k5test to set up a Kerberos 5 deployment
9+
----------------------------------------------
10+
11+
*k5test* can be used to set up a self-contained MIT Kerberos 5 environment.
12+
This is useful for testing applications without having to manipulate existing
13+
Kerberos realms, or having to set up a full Kerberos deployment by hand.
14+
15+
To set up a realm, use the `k5test.K5Realm` class. The constructor accepts
16+
several useful arguments for controlling which parts get set up; refer to the
17+
inline documentation for more information.
18+
19+
Using k5test to run unit tests
20+
------------------------------
21+
22+
Instead of having test cases inherit from `unittest.TestCase`, inherit from
23+
`k5test.KerberosTestCase`, which will automatically set up a Kerberos 5 environment,
24+
before the test case, and tear it down afterwards.
25+
26+
Additionally, several decorators are defined. the
27+
`k5test.gssapi_extension_test(extension_name, human_readable_name)` decorator
28+
(which requires `python-gssapi`) allows you to skip tests with installations that don't
29+
support a particular GSSAPI extension. The the
30+
`k5test.krb_minversion_test(target_version, problem_name)` decorator allows you to skip tests
31+
when running a version of krb5 less that the required version. The
32+
`k5test.krb_plugin_test(plugin_type, plugin_name)` decorator allows you to skip tests for
33+
installations that don't have a particular plugin installed.

k5test/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from k5test.realm import K5Realm # noqa
2+
from k5test.unit import * # noqa

k5test/_utils.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import os
2+
import sys
3+
import subprocess
4+
5+
6+
# general use
7+
def get_output(*args, **kwargs):
8+
res = subprocess.check_output(*args, shell=True, **kwargs)
9+
decoded = res.decode('utf-8')
10+
return decoded.strip()
11+
12+
13+
# python-gssapi related
14+
def import_gssapi_extension(name):
15+
"""Import a GSSAPI extension module
16+
17+
This method imports a GSSAPI extension module based
18+
on the name of the extension (not including the
19+
'ext_' prefix). If the extension is not available,
20+
the method retuns None.
21+
22+
Args:
23+
name (str): the name of the extension
24+
25+
Returns:
26+
module: Either the extension module or None
27+
"""
28+
29+
try:
30+
path = 'gssapi.raw.ext_{0}'.format(name)
31+
__import__(path)
32+
return sys.modules[path]
33+
except ImportError:
34+
return None
35+
36+
37+
# krb5-plugin related
38+
_PLUGIN_DIR = None
39+
40+
41+
def find_plugin_dir():
42+
global _PLUGIN_DIR
43+
if _PLUGIN_DIR is not None:
44+
return _PLUGIN_DIR
45+
46+
# if we've set a LD_LIBRARY_PATH, use that first
47+
ld_path_raw = os.environ.get('LD_LIBRARY_PATH')
48+
if ld_path_raw is not None:
49+
# first, try assuming it's just a normal install
50+
51+
ld_paths = [path for path in ld_path_raw.split(':') if path]
52+
53+
for ld_path in ld_paths:
54+
if not os.path.exists(ld_path):
55+
continue
56+
57+
_PLUGIN_DIR = _decide_plugin_dir(
58+
_find_plugin_dirs_installed(ld_path))
59+
if _PLUGIN_DIR is None:
60+
_PLUGIN_DIR = _decide_plugin_dir(
61+
_find_plugin_dirs_src(ld_path))
62+
63+
if _PLUGIN_DIR is not None:
64+
break
65+
66+
# if there was no LD_LIBRARY_PATH, or the above failed
67+
if _PLUGIN_DIR is None:
68+
# if we don't have a LD_LIBRARY_PATH, just search in
69+
# $prefix/lib
70+
71+
lib_dir = os.path.join(get_output('krb5-config --prefix'), 'lib')
72+
_PLUGIN_DIR = _decide_plugin_dir(_find_plugin_dirs_installed(lib_dir))
73+
74+
if _PLUGIN_DIR is not None:
75+
_PLUGIN_DIR = os.path.normpath(_PLUGIN_DIR)
76+
return _PLUGIN_DIR
77+
else:
78+
return None
79+
80+
81+
def _decide_plugin_dir(dirs):
82+
if dirs is None:
83+
return None
84+
85+
# the shortest path is probably more correct
86+
shortest_first = sorted(dirs, key=len)
87+
88+
for path in shortest_first:
89+
# check to see if it actually contains .so files
90+
if get_output('find %s -name "*.so"' % path):
91+
return path
92+
93+
return None
94+
95+
96+
def _find_plugin_dirs_installed(search_path):
97+
options_raw = get_output('find %s/ -type d '
98+
'-path "*/krb5/plugins"' % search_path)
99+
100+
if options_raw:
101+
return options_raw.split('\n')
102+
else:
103+
return None
104+
105+
106+
def _find_plugin_dirs_src(search_path):
107+
options_raw = get_output('find %s/../ -type d -name plugins' % search_path)
108+
109+
if options_raw:
110+
return options_raw.split('\n')
111+
else:
112+
return None

0 commit comments

Comments
 (0)