diff options
| author | Chris McDonough <chrism@agendaless.com> | 2008-08-17 00:15:17 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2008-08-17 00:15:17 +0000 |
| commit | 157721dda97f5aea95f40e307d9d5dceb1014f83 (patch) | |
| tree | 07272c8ff86adcb7e9700aed9daa46af6accd291 /repoze/bfg/security.py | |
| parent | 1a1ca311479764b3c96a3fd61571bf0cdc8cb043 (diff) | |
| download | pyramid-157721dda97f5aea95f40e307d9d5dceb1014f83.tar.gz pyramid-157721dda97f5aea95f40e307d9d5dceb1014f83.tar.bz2 pyramid-157721dda97f5aea95f40e307d9d5dceb1014f83.zip | |
Add RepozeWhoIdentityACLSecurityPolicy; add debug logging.
Diffstat (limited to 'repoze/bfg/security.py')
| -rw-r--r-- | repoze/bfg/security.py | 110 |
1 files changed, 87 insertions, 23 deletions
diff --git a/repoze/bfg/security.py b/repoze/bfg/security.py index 5ab6ae31d..d15d89e96 100644 --- a/repoze/bfg/security.py +++ b/repoze/bfg/security.py @@ -1,3 +1,7 @@ +import logging +import os +import sys + from zope.interface import implements from zope.component import queryUtility @@ -80,29 +84,13 @@ class ACLAuthorizer(object): self.logger and self.logger.debug(str(result)) return result -class RemoteUserACLSecurityPolicy(object): - """ A security policy which: - - - examines the request.environ for the REMOTE_USER variable and - uses any non-false value as a principal id for this request. - - - uses an ACL-based authorization model which attempts to find an - ACL on the context, and which returns ``Allowed`` from its - 'permits' method if the ACL found grants access to the current - principal. It returns ``Denied`` if permission was not granted - (either explicitly via a deny or implicitly by not finding a - matching ACE action). An ACL is an ordered sequence of ACE - tuples, e.g. ``[(Allow, Everyone, 'read'), (Deny, 'george', - 'write')]``. ACLs stored on model instance objects as their - __acl__ attribute will be used by the security machinery to - grant or deny access. - - """ +class ACLSecurityPolicy(object): implements(ISecurityPolicy) authorizer_factory = ACLAuthorizer - def __init__(self, logger=None): + def __init__(self, logger, get_principals): self.logger = logger + self.get_principals = get_principals def permits(self, context, request, permission): """ Return ``Allowed`` if the policy permits access, @@ -118,17 +106,93 @@ class RemoteUserACLSecurityPolicy(object): return False def authenticated_userid(self, request): - return request.environ.get('REMOTE_USER', None) + principals = self.get_principals(request) + if principals: + return principals[0] def effective_principals(self, request): - userid = self.authenticated_userid(request) effective_principals = [Everyone] + principal_ids = self.get_principals(request) - if userid is not None: + if principal_ids: effective_principals.append(Authenticated) - effective_principals.append(userid) + effective_principals.extend(principal_ids) + return effective_principals +DEBUG_LOG_KEY = 'BFG_SECURITY_DEBUG' + +def debug_logger(logger): + if logger is None: + do_debug_log = os.environ.get(DEBUG_LOG_KEY, '') + if str(do_debug_log).lower() in ('1', 'y', 'true', 't', 'on'): + handler = logging.StreamHandler(sys.stdout) + fmt = '%(asctime)s %(message)s' + formatter = logging.Formatter(fmt) + handler.setFormatter(formatter) + logger = logging.Logger('repoze.bfg.security') + logger.addHandler(handler) + logger.setLevel(logging.DEBUG) + return logger + return logger + +def RemoteUserACLSecurityPolicy(logger=None): + """ A security policy which: + + - examines the request.environ for the REMOTE_USER variable and + uses any non-false value as a principal id for this request. + + - uses an ACL-based authorization model which attempts to find an + ACL on the context, and which returns ``Allowed`` from its + 'permits' method if the ACL found grants access to the current + principal. It returns ``Denied`` if permission was not granted + (either explicitly via a deny or implicitly by not finding a + matching ACE action). An ACL is an ordered sequence of ACE + tuples, e.g. ``[(Allow, Everyone, 'read'), (Deny, 'george', + 'write')]``. ACLs stored on model instance objects as their + __acl__ attribute will be used by the security machinery to + grant or deny access. + + """ + logger = debug_logger(logger) + def get_principals(request): + user_id = request.environ.get('REMOTE_USER') + if user_id: + return [user_id] + return [] + return ACLSecurityPolicy(logger, get_principals) + +def RepozeWhoIdentityACLSecurityPolicy(logger=None): + """ A security policy which: + + - examines the request.environ for the ``repoze.who.identity`` + dictionary. If one is found, the principal ids for the request + are composed of ``repoze.who.identity['repoze.who.userid']`` + plus ``repoze.who.identity.get('groups', []). + + - uses an ACL-based authorization model which attempts to find an + ACL on the context, and which returns ``Allowed`` from its + 'permits' method if the ACL found grants access to the current + principal. It returns ``Denied`` if permission was not granted + (either explicitly via a deny or implicitly by not finding a + matching ACE action). An ACL is an ordered sequence of ACE + tuples, e.g. ``[(Allow, Everyone, 'read'), (Deny, 'george', + 'write')]``. ACLs stored on model instance objects as their + __acl__ attribute will be used by the security machinery to + grant or deny access. + + """ + logger = debug_logger(logger) + def get_principals(request): + identity = request.environ.get('repoze.who.identity') + if not identity: + return [] + principals = [identity['repoze.who.userid']] + principals.extend(identity.get('groups', [])) + return principals + + return ACLSecurityPolicy(logger, get_principals) + class PermitsResult: def __init__(self, ace, acl, permission, principals, context): self.acl = acl |
