summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2015-10-05 20:09:02 -0400
committerSimo Sorce <simo@redhat.com>2015-10-19 12:17:37 -0400
commitbd2e62767e6287dcaf5275362338682fc555d4ce (patch)
treef7d02b6c8c69c408327598b51331ef01eb3f91ee
parentc0c31ce07974e7aa5bde3a4ceac5f103a26d524e (diff)
downloadcustodia-bd2e62767e6287dcaf5275362338682fc555d4ce.tar.gz
custodia-bd2e62767e6287dcaf5275362338682fc555d4ce.tar.xz
custodia-bd2e62767e6287dcaf5275362338682fc555d4ce.zip
Add UserNameSpace auths plugin
Moves the secrets.Namespaces plugin to the proper authorizers file and fixes it to properly enforce the user-named namespace is being used. Signed-off-by: Simo Sorce <simo@redhat.com> Reviewed-by: Christian Heimes <cheimes@redhat.com>
-rw-r--r--custodia.conf6
-rw-r--r--custodia/httpd/authorizers.py26
-rw-r--r--custodia/secrets.py33
3 files changed, 32 insertions, 33 deletions
diff --git a/custodia.conf b/custodia.conf
index c3c56a5..c3c20af 100644
--- a/custodia.conf
+++ b/custodia.conf
@@ -16,7 +16,7 @@ handler = custodia.httpd.authorizers.SimplePathAuthz
paths = /.
[authz:namespaces]
-handler = custodia.secrets.Namespaces
+handler = custodia.httpd.authorizers.UserNameSpace
path = /secrets/
store = simple
@@ -37,7 +37,7 @@ dburi = secrets.db
table = tenant1
[authz:tenant1]
-handler = custodia.secrets.Namespaces
+handler = custodia.httpd.authorizers.UserNameSpace
path = /tenant1/secrets/
store = tenant1
@@ -55,7 +55,7 @@ master_key = examples/enclite.sample.key
master_enctype = A128CBC-HS256
[authz:encrypted]
-handler = custodia.secrets.Namespaces
+handler = custodia.httpd.authorizers.UserNameSpace
path = /enc/secrets/
store = encrypted
diff --git a/custodia/httpd/authorizers.py b/custodia/httpd/authorizers.py
index bc4f009..dbf3d37 100644
--- a/custodia/httpd/authorizers.py
+++ b/custodia/httpd/authorizers.py
@@ -46,3 +46,29 @@ class SimplePathAuthz(HTTPAuthorizer):
else:
path, _ = os.path.split(path)
return None
+
+
+class UserNameSpace(HTTPAuthorizer):
+
+ def __init__(self, *args, **kwargs):
+ super(UserNameSpace, self).__init__(*args, **kwargs)
+ self.path = self.config.get('path', '/')
+
+ def handle(self, request):
+ # Only check if we are in the right (sub)path
+ path = request.get('path', '/')
+ if not path.startswith(self.path):
+ return None
+
+ name = request.get('remote_user', None)
+ if name is None:
+ # UserNameSpace requires a user ...
+ return False
+
+ namespace = self.path.rstrip('/') + '/' + name + '/'
+ if not path.startswith(namespace):
+ # Not in the namespace
+ return False
+
+ request['default_namespace'] = name
+ return True
diff --git a/custodia/secrets.py b/custodia/secrets.py
index 3f01afb..b2979d0 100644
--- a/custodia/secrets.py
+++ b/custodia/secrets.py
@@ -5,7 +5,7 @@ import os
import unittest
from custodia import log
-from custodia.httpd.authorizers import HTTPAuthorizer
+from custodia.httpd.authorizers import UserNameSpace
from custodia.httpd.consumer import HTTPConsumer
from custodia.httpd.server import HTTPError
from custodia.message.common import UnallowedMessage
@@ -16,34 +16,6 @@ from custodia.store.interface import CSStoreExists
from custodia.store.sqlite import SqliteStore
-class Namespaces(HTTPAuthorizer):
-
- def __init__(self, *args, **kwargs):
- super(Namespaces, self).__init__(*args, **kwargs)
- self.path = self.config.get('path', '/')
- # warn if self.path does not end with '/' ?
-
- def handle(self, request):
-
- # First of all check we are in the right path
- path = request.get('path', '/')
- if not path.startswith(self.path):
- return None
-
- if 'remote_user' not in request:
- return False
- # At the moment we just have one namespace, the user's name
- namespaces = [request['remote_user']]
-
- # Check the request is in a valid namespace
- trail = request.get('trail', [])
- if len(trail) > 0 and trail[0] != namespaces[0]:
- return False
-
- request['default_namespace'] = namespaces[0]
- return True
-
-
class Secrets(HTTPConsumer):
def __init__(self, *args, **kwargs):
@@ -278,7 +250,7 @@ class SecretsTests(unittest.TestCase):
def setUpClass(cls):
cls.secrets = Secrets({'auditlog': 'test.audit.log'})
cls.secrets.root.store = SqliteStore({'dburi': 'testdb.sqlite'})
- cls.authz = Namespaces({})
+ cls.authz = UserNameSpace({})
@classmethod
def tearDownClass(cls):
@@ -289,6 +261,7 @@ class SecretsTests(unittest.TestCase):
pass
def check_authz(self, req):
+ req['path'] = '/'.join([''] + req.get('trail', []))
if self.authz.handle(req) is False:
raise HTTPError(403)