[Zope-CVS] CVS: Products/AdaptableStorage/gateway_fs - FSSecurityAttributes.py:1.1 params.py:1.1 public.py:1.5

Shane Hathaway shane@zope.com
Sat, 1 Mar 2003 15:43:31 -0500


Update of /cvs-repository/Products/AdaptableStorage/gateway_fs
In directory cvs.zope.org:/tmp/cvs-serv29278/gateway_fs

Modified Files:
	public.py 
Added Files:
	FSSecurityAttributes.py params.py 
Log Message:
- Added SecurityAttributes, FSSecurityAttributes, and
SQLSecurityAttributes.  These classes store Zope 2 role names, local
roles, executable ownership, permission mappings, and proxy roles.
(Until now, all of this ended up in the remainder pickle.)

- Added a second abstract object mapper to Zope2Mapper.  The "base"
mapper has no properties aspect, while the "base_p" mapper does.  This
made Zope2FS and Zope2SQL a little cleaner, since they don't have to
remove the properties aspect.

- Added corresponding unit tests.


=== Added File Products/AdaptableStorage/gateway_fs/FSSecurityAttributes.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Gateway for storing properties.

$Id: FSSecurityAttributes.py,v 1.1 2003/03/01 20:42:59 shane Exp $
"""

from mapper_public import IGateway, RowSequenceSchema

from params import stringToParams, paramsToString


class FSSecurityAttributes:

    __implements__ = IGateway

    schema = RowSequenceSchema()
    schema.addField('declaration_type', 'string')
    schema.addField('role', 'string')
    schema.addField('permission', 'string')
    schema.addField('username', 'string')

    def __init__(self, fs_conn, section='security'):
        self.fs_conn = fs_conn
        self.section = section

    def getSchema(self):
        return self.schema

    def load(self, event):
        key = event.getKey()
        text = self.fs_conn.readSection(key, self.section, '')
        res = []
        if text:
            lines = text.split('\n')
            for line in lines:
                line = line.strip()
                if not line or line.startswith('#'):
                    continue
                params = stringToParams(line)
                if params:
                    decl_type = params[0][0]
                    row = [decl_type, '', '', '']
                    for k, v in params[1:]:
                        k = k.lower().split('_', 1)[0]
                        if k == 'role':
                            row[1] = v
                        elif k == 'permission':
                            row[2] = v
                        elif k == 'username':
                            row[3] = v
                        else:
                            raise ValueError(
                                "Could not read security declaration "
                                "%s for %s" % (repr(line), repr(key)))
                    res.append(tuple(row))
        res.sort()
        return res, tuple(res)


    def store(self, event, state):
        lines = []
        for d, r, p, u in state:
            params = [(d, '')]
            if r:
                params.append(('role', r))
            if p:
                params.append(('permission', p))
            if u:
                params.append(('username', u))
            s = paramsToString(params)
            lines.append(s)
        lines.sort()
        text = '\n'.join(lines)
        self.fs_conn.writeSection(event.getKey(), self.section, text)
        state = list(state)
        state.sort()
        return tuple(state)



=== Added File Products/AdaptableStorage/gateway_fs/params.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Functions for encoding/decoding parameter strings.

$Id: params.py,v 1.1 2003/03/01 20:42:59 shane Exp $
"""

import re

token_re = re.compile(r'([" \t]|\\["\\trn])')
token_replacements = {
    '\\"': '"',
    '\\\\': '\\',
    '\\t': '\t',
    '\\r': '\r',
    '\\n': '\n',
    }

key_re = re.compile(r'[A-Za-z_-][A-Za-z0-9_-]*$')


def splitParams(s):
    tokens = re.split(token_re, s)
    params = []
    param = []
    quoting = 0
    for tok in tokens:
        if tok:
            v = token_replacements.get(tok)
            if v:
                param.append(v)
            elif not quoting and (tok == ' ' or tok == '\t'):
                if param:
                    params.append(''.join(param))
                    param = []
            else:
                if tok == '"':
                    quoting = not quoting
                    if not quoting:
                        params.append(''.join(param))
                        param = []
                else:
                    param.append(tok)
    leftover = ''.join(param).strip()
    if leftover:
        params.append(leftover)
    return params


def escapeParam(s):
    return s.replace('\\', '\\\\').replace('"', '\\"').replace(
        '\r', '\\r').replace('\n', '\\n').replace('\t', '\\t')


def stringToParams(s):
    """Decodes a string of the format 'a="..." b="..."'.

    Returns a list of (key, value) pairs.
    """
    params = splitParams(s)
    res = []
    for param in params:
        p = param.split('=', 1)
        if len(p) == 1:
            k = p[0]
            v = ''
        else:
            k, v = p
        res.append((k, v))
    return res


def paramsToString(params):
    """Encodes a list of (key, value) pairs as a string."""
    parts = []
    for k, v in params:
        if not key_re.match(k):
            raise ValueError, 'Bad parameter name: %s' % repr(k)
        if v:
            parts.append('%s="%s"' % (k, escapeParam(v)))
        else:
            parts.append(k)
    return ' '.join(parts)



=== Products/AdaptableStorage/gateway_fs/public.py 1.4 => 1.5 ===
--- Products/AdaptableStorage/gateway_fs/public.py:1.4	Mon Jan  6 18:17:41 2003
+++ Products/AdaptableStorage/gateway_fs/public.py	Sat Mar  1 15:42:59 2003
@@ -25,4 +25,5 @@
 from FSFileData import FSFileData
 from FSProperties import FSProperties
 from FSSectionData import FSSectionData
+from FSSecurityAttributes import FSSecurityAttributes
 from FSUserList import FSUserList