Commit c7aaa0d6 authored by Tres Seaver's avatar Tres Seaver

Wrong location

parent ac8caa89

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

./include/*
./bin
./develop-eggs
./.installed.cfg
./eggs
./parts
./build
*.egg-info
Zope Foundation and Contributors
\ No newline at end of file
Zope Public License (ZPL) Version 2.1
A copyright notice accompanies this license document that identifies the
copyright holders.
This license has been certified as open source. It has also been designated as
GPL compatible by the Free Software Foundation (FSF).
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions in source code must retain the accompanying copyright
notice, this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the accompanying copyright
notice, this list of conditions, and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Names of the copyright holders must not be used to endorse or promote
products derived from this software without prior written permission from the
copyright holders.
4. The right to distribute this software or to use it for any purpose does not
give you the right to use Servicemarks (sm) or Trademarks (tm) of the
copyright
holders. Use of them is covered by separate agreement with the copyright
holders.
5. If any files are modified, you must cause the modified files to carry
prominent notices stating that you changed the files and the date of any
change.
Disclaimer
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.. contents::
Introduction
============
Zope2 is an open-source web application server.
This document provides some general information about Zope2 and provides
links to other documents.
Installation information can be found in ``doc/INSTALL.rst``. Other
documentation is also in the "doc" directory and in the zope.org
documentation section at http://docs.zope.org/ .
General Zope information is available at http://www.zope.org/
Installation
============
Follow the instructions in ``doc/INSTALL.rst`` to install Zope.
License
=======
The Zope License is included in ``ZopePublicLicense.txt``. Send your
feedback about the license to zope-dev@zope.org.
Bug tracker
===========
Bugs reports should be made through the Zope bugtracker at
https://bugs.launchpad.net/zope2. A bug report should contain detailed
information about how to reproduce the bug, error messages (see
``/error_log`` within the ZMI or ``var/event.log``).
Mailing list
============
You can contact and discuss Zope2 on the Zope mailing list (zope@zope.org).
To subscribe to the list send mail to zope-request@zope.org with ``subscribe``
in the subject line.
You can also subscribe online from here:
http://mail.zope.org/mailman/listinfo/zope
##############################################################################
#
# Copyright (c) 2006 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
"""Bootstrap a buildout-based project
Simply run this script in a directory containing a buildout.cfg.
The script accepts buildout command-line options, so you can
use the -c option to specify an alternate configuration file.
$Id: bootstrap.py 115394 2010-08-03 00:03:02Z gary $
"""
import os, shutil, sys, tempfile, urllib2
from optparse import OptionParser
tmpeggs = tempfile.mkdtemp()
is_jython = sys.platform.startswith('java')
# parsing arguments
parser = OptionParser(
'This is a custom version of the zc.buildout %prog script. It is '
'intended to meet a temporary need if you encounter problems with '
'the zc.buildout 1.5 release.')
parser.add_option("-v", "--version", dest="version", default='1.4.4',
help='Use a specific zc.buildout version. *This '
'bootstrap script defaults to '
'1.4.4, unlike usual buildpout bootstrap scripts.*')
parser.add_option("-d", "--distribute",
action="store_true", dest="distribute", default=False,
help="Use Disribute rather than Setuptools.")
parser.add_option("-c", None, action="store", dest="config_file",
help=("Specify the path to the buildout configuration "
"file to be used."))
options, args = parser.parse_args()
# if -c was provided, we push it back into args for buildout' main function
if options.config_file is not None:
args += ['-c', options.config_file]
if options.version is not None:
VERSION = '==%s' % options.version
else:
VERSION = ''
USE_DISTRIBUTE = options.distribute
args = args + ['bootstrap']
to_reload = False
try:
import pkg_resources
if not hasattr(pkg_resources, '_distribute'):
to_reload = True
raise ImportError
except ImportError:
ez = {}
if USE_DISTRIBUTE:
exec urllib2.urlopen('http://python-distribute.org/distribute_setup.py'
).read() in ez
ez['use_setuptools'](to_dir=tmpeggs, download_delay=0, no_fake=True)
else:
exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
).read() in ez
ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
if to_reload:
reload(pkg_resources)
else:
import pkg_resources
if sys.platform == 'win32':
def quote(c):
if ' ' in c:
return '"%s"' % c # work around spawn lamosity on windows
else:
return c
else:
def quote (c):
return c
ws = pkg_resources.working_set
if USE_DISTRIBUTE:
requirement = 'distribute'
else:
requirement = 'setuptools'
env = dict(os.environ,
PYTHONPATH=
ws.find(pkg_resources.Requirement.parse(requirement)).location
)
cmd = [quote(sys.executable),
'-c',
quote('from setuptools.command.easy_install import main; main()'),
'-mqNxd',
quote(tmpeggs)]
if 'bootstrap-testing-find-links' in os.environ:
cmd.extend(['-f', os.environ['bootstrap-testing-find-links']])
cmd.append('zc.buildout' + VERSION)
if is_jython:
import subprocess
exitcode = subprocess.Popen(cmd, env=env).wait()
else: # Windows prefers this, apparently; otherwise we would prefer subprocess
exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
assert exitcode == 0
ws.add_entry(tmpeggs)
ws.require('zc.buildout' + VERSION)
import zc.buildout.buildout
zc.buildout.buildout.main(args)
shutil.rmtree(tmpeggs)
[buildout]
extensions = buildout.dumppickedversions
develop = .
parts =
test
scripts
zopepy
alltests
allpy
docs
checkversions
extends = versions.cfg
unzip = true
[test]
recipe = zc.recipe.testrunner
eggs = Zope2
[scripts]
recipe = zc.recipe.egg
eggs = Zope2
[zopepy]
recipe = zc.recipe.egg
eggs = Zope2
interpreter = zopepy
scripts = zopepy
[alltests]
recipe = zc.recipe.testrunner
eggs =
Zope2
Acquisition
DateTime
ExtensionClass
five.formlib
initgroups
Missing
MultiMapping
Persistence
Products.ZSQLMethods
Record
RestrictedPython
tempstorage
ThreadLock
zLOG
ZopeUndo
zope.annotation
zope.authentication
zope.broken
zope.browser
zope.cachedescriptors
zope.component
zope.componentvocabulary
zope.configuration
zope.container
zope.contentprovider
zope.contenttype
zope.copy
zope.datetime
zope.deferredimport
zope.deprecation
zope.dottedname
zope.dublincore
zope.error
zope.event
zope.exceptions
zope.filerepresentation
zope.hookable
zope.i18n
zope.i18nmessageid
zope.index
zope.interface
zope.lifecycleevent
zope.location
zope.minmax
zope.modulealias
zope.pagetemplate
zope.password
zope.processlifetime
zope.proxy
zope.publisher
zope.schema
zope.security
zope.sendmail
zope.sequencesort
zope.session
zope.site
zope.size
zope.structuredtext
zope.tal
zope.tales
zope.testbrowser
zope.thread
zope.traversing
zope.viewlet
zope.app.form
zope.app.pagetemplate
zope.app.publication
zope.app.publisher
zope.app.schema
# Fetch undeclared ftests dependencies
zope.app.applicationcontrol
zope.app.exception
zope.app.http
zope.app.principalannotation
zope.app.securitypolicy
zope.app.zptpage
zope.app.zcmlfiles
python-gettext
defaults = ['--module', '!^(zope[.]app)[.]']
[allpy]
recipe = zc.recipe.egg
eggs = ${alltests:eggs}
interpreter = allpy
scripts = allpy
[docs]
recipe = zc.recipe.egg
eggs = Sphinx
[checkversions]
recipe = zc.recipe.egg
eggs = z3c.checkversions [buildout]
[buildout]
extends = alltests.cfg
parts += dependencies
[dependencies]
recipe = z3c.recipe.depgraph
eggs = ${alltests:eggs}
variants = base tred
exclude =
ClientForm
docutils
mechanize
This diff is collapsed.
Running Zope in Debug Mode
==========================
If you wish to run Zope in debug mode, set the 'debug-mode'
configuration file parameter to 'on' (this is the default). This
will have the following effects:
- On UNIX, Zope will not detach from the controlling terminal.
- The Z_DEBUG_MODE environment variable gets set, which causes
behavioral changes to Zope appropriate for software development.
See the configuration file description of 'debug-mode' for more
information.
Using 'zopectl debug'
---------------------
A utility known as 'zopectl' is installed into generated instance homes.
You can use it to inspect a Zope instance's running state via an
interactive Python interpreter by passing zopectl the 'debug' parameter
on the command line. The 'top-level' Zope object (the root folder) will
be bound to the name 'app' within the interpreter. You can then use
normal Python method calls against app and use the Python interpreter
normally to inspect results::
[chrism@james Trunk]$ bin/zopectl debug
Starting debugger (the name "app" is bound to the top-level Zope object)
>>> app.objectIds()
['acl_users', 'Control_Panel', 'temp_folder', 'browser_id_manager', 'session_data_manager', 'error_log', 'index_html', 'standard_error_message']
>>>
Installing and Zope with ``zc.buildout``
========================================
.. highlight:: bash
This document descibes how to get going with Zope using ``zc.buildout``.
About ``zc.buildout``
---------------------
`zc.buildout <http://www.buildout.org/>`_ is a powerful tool for creating
repeatable builds of a given software configuration and environment. The
Zope developers use ``zc.buildout`` to develop Zope itself, as well as
the underlying packages it uses.
Prerequisites
-------------
In order to use Zope, you must have the following pre-requisites
available:
- A supported version of Python, including the development support if
installed from system-level packages. Supported versions include:
* 2.6.x
- Zope needs the Python ``zlib`` module to be importable. If you are
building your own Python from source, please be sure that you have the
headers installed which correspond to your system's ``zlib``.
- A C compiler capable of building extension modules for your Python
(gcc recommended). This is not necessary for Windows as binary
releases of the parts that would need compiling are always made
available.
- If you wish to install Zope as a Service on Windows, you will need
to have the `pywin32`__ package installed.
__ https://sourceforge.net/projects/pywin32/
Installing standalone Zope using zc.buildout
--------------------------------------------
In this configuration, we use ``zc.buildout`` to install the Zope software,
but then generate server "instances" outside the buildout environment.
Installing the Zope software
::::::::::::::::::::::::::::
Installing the Zope software using ``zc.buildout`` involves the following
steps:
- Download the Zope 2 source distribution from `PyPI`__
__ http://pypi.python.org/pypi/Zope2
- Bootstrap the buildout
- Run the buildout
On Linux, this can be done as follows::
$ wget http://pypi.python.org/packages/source/Z/Zope2/Zope2-<Zope version>.tar.gz
$ tar xfvz Zope2-<Zope version>.tar.gz
$ cd Zope2-<Zope version>
$ /path/to/your/python bootstrap/bootstrap.py
$ bin/buildout
Creating a Zope instance
::::::::::::::::::::::::
Once you've installed Zope, you will need to create an "instance
home". This is a directory that contains configuration and data for a
Zope server process. The instance home is created using the
``mkzopeinstance`` script::
$ bin/mkzopeinstance
You can specify the Python interpreter to use for the instance
explicitly::
$ bin/mkzopeinstance --python=$PWD/bin/zopepy
You will be asked to provide a user name and password for an
administrator's account during ``mkzopeinstance``. To see the available
command-line options, run the script with the ``--help`` option::
$ bin/mkzopeinstance --help
.. note::
The traditional "inplace" build is no longer supported. If using
``mkzopeinstance``, always do so outside the buildout environment.
Creating a buildout-based Zope instance
---------------------------------------
Rather than installing Zope separately from your instance, you may wish
to use ``zc.buildout`` to create a self-contained environment, containing
both the Zope software and the configuration and data for your server.
This procedure involves the following steps:
- Create the home directory for the buildout, including
``etc``, ``log`` and ``var`` subdirectories.
- Fetch the buildout bootstrap script into the environment.
- Create a buildout configuration as follows:
.. topic:: buildout.cfg
:class: file
::
[buildout]
parts = instance
extends = http://download.zope.org/Zope2/index/<Zope version>/versions.cfg
[instance]
recipe = zc.recipe.egg
eggs = Zope2
interpreter = py
scripts = runzope zopectl
initialization =
import sys
sys.argv[1:1] = ['-C',r'${buildout:directory}/etc/zope.conf']
This is the minimum but all the usual buildout techniques can be
used.
- Bootstrap the buildout
- Run the buildout
- Create a Zope configuration file. A minimal version would be:
.. topic:: etc/zope.cfg
:class: file
::
%define INSTANCE <path to your instance directory>
python $INSTANCE/bin/py[.exe on Windows]
instancehome $INSTANCE
A fully-annotated sample can be found in the Zope2 egg::
$ cat eggs/Zope2--*/Zope2/utilities/skel/etc/zope.conf.in
<rest of the stuff that goes into a zope.conf, e.g. databases and log files.>
.. highlight:: bash
An example session::
$ mkdir /path/to/instance
$ cd /path/to/instance
$ mkdir etc logs var
$ wget http://svn.zope.org/zc.buildout/trunk/bootstrap/bootstrap.py
$ vi buildout.cfg
$ /path/to/your/python bootstrap.py
$ bin/buildout
$ cat eggs/Zope2--*/Zope2/utilities/skel/etc/zope.conf.in > etc/zope.conf
$ vi etc/zope.conf # replace <<INSTANCE_HOME>> with buildout directory
$ bin/zopectl start
In the ``bin`` subdirectory of your instance directory, you will
find ``runzope`` and ``zopectl`` scripts that can be used as
normal.
You can use ``zopectl`` interactively as a command shell by just
calling it without any arguments. Try ``help`` there and ``help <command>``
to find out about additionally commands of zopectl. These commands
also work at the command line.
Note that there are there are recipes such as `plone.recipe.zope2instance
<http://pypi.python.org/pypi/plone.recipe.zope2instance>`_ which can be
used to automate this whole process.
After installation, refer to :doc:`operation` for documentation on
configuring and running Zope.
Installing Zope
===============
.. highlight:: bash
This document descibes how to get going with Zope.
Prerequisites
-------------
In order to use Zope, you must have the following pre-requisites
available:
- A supported version of Python, including the development support if
installed from system-level packages. Supported versions include:
* 2.6.x
- Zope needs the Python ``zlib`` module to be importable. If you are
building your own Python from source, please be sure that you have the
headers installed which correspond to your system's ``zlib``.
- A C compiler capable of building extension modules for your Python
(gcc recommended). This is not necessary for Windows as binary
releases of the parts that would need compiling are always made
available.
- If you wish to install Zope as a Service on Windows, you will need
to have the `pywin32`__ package installed.
__ https://sourceforge.net/projects/pywin32/
Installing Zope
---------------
The recommended way to install Zope is within a virtualized Python environment
using ``virtualenv`` as follows::
$ virtualenv --no-site-packages my_zope
$ cd my_zope
$ bin/easy_install -i http://download.zope.org/Zope2/index/<Zope version> Zope2
If you don't already have ``virtualenv`` installed on your system, download
the latest release from the `virtualenv PyPI page
<http://pypi.python.org/pypi/virtualenv>`_, unpack it, and install it, e.g.::
$ wget http://pypi.python.org/packages/source/v/virtualenv/virtualenv-1.4.6.tar.gz
$ tar xzf virtualenv-1.4.6.tar.gz
$ cd virtuaenv-1.4.6
$ /path/to/python2.6 setup.py install
If you wish to manage your Zope instance using
buildout, please see the :doc:`INSTALL-buildout`.
Creating a Zope Instance
------------------------
Once you've installed Zope, you will need to create an "instance
home". This is a directory that contains configuration and data for a
Zope server process. The instance home is created using the
``mkzopeinstance`` script::
$ bin/mkzopeinstance
You will be asked to provide a user name and password for an
administrator's account during ``mkzopeinstance``. To see the available
command-line options, run the script with the ``--help`` option::
$ bin/mkzopeinstance --help
.. note::
The traditional "inplace" build is no longer supported. Always use
``mkzopeinstance`` to create instances outside the virtualenv environment.
After installation, refer to :doc:`operation` for documentation on
configuring and running Zope.
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d .build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html web pickle htmlhelp latex changes linkcheck
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " changes to make an overview over all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
clean:
-rm -rf .build/*
html:
mkdir -p .build/html .build/doctrees
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) .build/html
@echo
@echo "Build finished. The HTML pages are in .build/html."
pickle:
mkdir -p .build/pickle .build/doctrees
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) .build/pickle
@echo
@echo "Build finished; now you can process the pickle files."
web: pickle
json:
mkdir -p .build/json .build/doctrees
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) .build/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
mkdir -p .build/htmlhelp .build/doctrees
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) .build/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in .build/htmlhelp."
latex:
mkdir -p .build/latex .build/doctrees
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) .build/latex
@echo
@echo "Build finished; the LaTeX files are in .build/latex."
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
"run these through (pdf)latex."
changes:
mkdir -p .build/changes .build/doctrees
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) .build/changes
@echo
@echo "The overview file is in .build/changes."
linkcheck:
mkdir -p .build/linkcheck .build/doctrees
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) .build/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in .build/linkcheck/output.txt."
Filesytem Permissions
=====================
You need to set permissions on the directory Zope uses to store its
data. This will normally be the `var` directory in the instance home.
Zope needs to read and write data to this directory. Before
running Zope you should ensure that you give adequate permissions
to this directory for the userid Zope will run under.
Depending on how you choose to run Zope you will need to give
different permissions to the directory. If you use Zope with an
existing web server, it will probably run Zope as 'nobody'. In this
case 'nobody' needs read and write permissions to the var directory.
If you change the way you run Zope, you may need to modify the permissions
of the directory and the files in it to allow Zope to read and write
under its changed userid.
Zope effective user support
===========================
.. note::
It is best practice to run Zope behind a reverse proxy like
Apache, Squid or Varnish. In this case, you do not need to run
or install Zope with root privileges, since the reverse proxy
will bind to port 80 and proxy back all request to Zope running
on an unpriviledged port.
Zope can bind its network service to low ports such as 21 (FTP) and
80 (HTTP). In order to bind to low ports, Zope must be started as
the root user. However, Zope will only run as root long enough to
bind to these low ports. It will then attempt to setuid to a less
privileged user.
You must specify the user to which Zope will attempt to setuid by
changing the 'effective-user' parameter in the zope.conf
configuration file to an existing username or UID. All runtime
files will be written as this user. If you do not specify an
'effective-user' in the configuration file, and you attempt to start
Zope, it will refuse to start.
Zope additionally emits a warning if you specify 'nobody' as the
'effective-user'. The rationale for this warning stems from the
fact that, historically, many other UNIX services dropped privileges
to the 'nobody' account after starting as root. Any security
defects in these services could cause someone to gain access as the
'nobody' account on your system. If someone was to gain control of
your 'nobody' account they could compromise your Zope files.
The most important thing to remember about effective user support is
that you don't have to start Zope as root unless you want to listen
for requests on low ports (ports beneath 1024). In fact, if you
don't have this need, you are much better off just starting Zope
under a dedicated user account.
Signals (POSIX only)
====================
Signals are a POSIX inter-process communications mechanism.
If you are using Windows then this documentation does not apply.
Zope responds to signals which are sent to the process id
specified in the file '$INSTANCE_HOME/var/Z2.pid'::
SIGHUP - close open database connections, then restart the server
process. A idiom for restarting a Zope server is:
kill -HUP `cat $INSTANCE_HOME/var/z2.pid`
SIGTERM - close open database connections then shut down. A common
idiom for shutting down Zope is:
kill -TERM `cat $INSTANCE_HOME/var/Z2.pid`
SIGINT - same as SIGTERM
SIGUSR2 - close and re-open all Zope log files (z2.log, event log,
detailed log.) A common idiom after rotating Zope log files
is:
kill -USR2 `cat $INSTANCE_HOME/var/z2.pid`
Special Users
=============
Because Zope is managed through the web, user names and passwords must be
used to assure that only authorized people can make changes to a Zope
installation.
Adding Managers
---------------
If you need to add a Manager to an existing Zope instance, you can do
this using `zopectl` as follows::
zopectl adduser `name` `password`
The Initial User
----------------
An initial username and password is needed to "bootstrap" the creation of
normal managers of your Zope site. This is accomplished through the
use of the 'inituser' file in the directory specified as the instance
home.
The first time Zope starts, it will detect
that no users have been defined in the root user folder. It will search
for the 'inituser' file and, if it exists, will add the user defined
in the file to the root user folder.
Normally, 'inituser' is created by the Zope install scripts. Either
the installer prompts for the password or a randomly generated
password is created and displayed at the end of the build script.
You can use the 'zpasswd.py' script to create 'inituser' yourself.
Execute 'zpasswd.py' like this::
python zpasswd.py inituser
The script will prompt you for the name, password, and allowed
domains. The default is to encode the password with SHA, so please
remember this password as there is no way to recover it (although
'zpasswd.py' lets you reset it.)
The Emergency User
------------------
In some situations you may need to bypass normal security controls
because you have lost your password or because the security settings
have been mixed up. Zope provides a facility called an "emergency
user" so that you can reset passwords and correct security
settings.
The emergency user password must be defined outside the application
user interface. It is defined in the 'access' file located
in the Zope directory. It should be readable only by the user
as which your web server runs.
To create the emergency user, use 'zpasswd.py' to create the
'access' file like this::
python zpasswd.py access
In order to provide a somewhat higher level of security, various
encoding schemes are supported which provide access to either SHA-1
encryption or the standard UNIX crypt facility if it has been compiled
into Python. Unless you have some special requirements (see below),
you should use the SHA-1 facility, which is the default.
Format of 'inituser' and 'access'
---------------------------------
A password file should consist of a single line of the form::
name:password
Note that you may also add an optional third component to the line in the
access file to restrict access by domain. For example, the line::
mario:nintendoRules:*.mydomain.com
in your 'access' file will only allow permit emergency user access
from `*.mydomain.com` machines. Attempts to access the system from
other domains will fail, even if the correct emergency user name
and password are used.
Please note that if you use the ZServer monitor capability, you will
need to run with a clear text password.
This diff is collapsed.
# -*- coding: utf-8 -*-
#
# Zope docs documentation build configuration file, created by
# sphinx-quickstart on Fri Feb 20 16:22:03 2009.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# The contents of this file are pickled, so don't put values in the namespace
# that aren't pickleable (module imports are okay, they're removed automatically).
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
# If your extensions are in another directory, add it here. If the directory
# is relative to the documentation root, use os.path.abspath to make it
# absolute, like shown here.
#sys.path.append(os.path.abspath('.'))
# General configuration
# ---------------------
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = []
# Add any paths that contain templates here, relative to this directory.
templates_path = ['.templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Zope 2 documentation'
copyright = u'2009, The Zope Developers Community'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '2.12'
# The full version, including alpha/beta/rc tags.
release = '2.12'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of documents that shouldn't be included in the build.
#unused_docs = []
# List of directories, relative to source directory, that shouldn't be searched
# for source files.
exclude_trees = ['.build']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# Options for HTML output
# -----------------------
# The style sheet to use for HTML and HTML Help pages. A file of that name
# must exist either in Sphinx' static/ path, or in one of the custom paths
# given in html_static_path.
html_style = 'default.css'
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['.static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_use_modindex = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, the reST sources are included in the HTML build as _sources/<name>.
#html_copy_source = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = ''
# Output file base name for HTML help builder.
htmlhelp_basename = 'Zopedocsdoc'
# Options for LaTeX output
# ------------------------
# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, document class [howto/manual]).
latex_documents = [
('index', 'Zope2docs.tex', ur'Zope 2 Documentation',
ur'Zope Developers Community', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# Additional stuff for the LaTeX preamble.
#latex_preamble = ''
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_use_modindex = True
Zope 2.12 specific documentation
================================
Contents:
.. toctree::
:maxdepth: 2
WHATSNEW.rst
INSTALL.rst
INSTALL-buildout.rst
operation.rst
USERS.rst
SECURITY.rst
SETUID.rst
SIGNALS.rst
DEBUGGING.rst
CHANGES.rst
@ECHO OFF
REM Command file for Sphinx documentation
set SPHINXBUILD=..\bin\sphinx-build
set ALLSPHINXOPTS=-d .build/doctrees %SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. changes to make an overview over all changed/added/deprecated items
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (.build\*) do rmdir /q /s %%i
del /q /s .build\*
goto end
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% .build/html
echo.
echo.Build finished. The HTML pages are in .build/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% .build/dirhtml
echo.
echo.Build finished. The HTML pages are in .build/dirhtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% .build/pickle
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% .build/json
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% .build/htmlhelp
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in .build/htmlhelp.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% .build/latex
echo.
echo.Build finished; the LaTeX files are in .build/latex.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% .build/changes
echo.
echo.The overview file is in .build/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% .build/linkcheck
echo.
echo.Link check complete; look for any errors in the above output ^
or in .build/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% .build/doctest
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in .build/doctest/output.txt.
goto end
)
:end
Configuring and Running Zope
============================
.. highlight:: bash
Whichever method you used to install Zope and create a server instance (see
:doc:`INSTALL` and :doc:`INSTALL-buildout`), the end result is configured
and operated the same way.
Configuring Zope
----------------
Your instance's configuration is defined in its ``etc/zope.conf`` file.
Unless you created the file manually, that file should contain fully-
annotated examples of each directive.
You can also pass an explicit configuration file on the commandline::
$ /path/to/zope/instance/bin/zopectl -c /tmp/other.conf show
...
Config file: /tmp/other.conf
When starting Zope, if you see errors indicating that an address is in
use, then you may have to change the ports Zope uses for HTTP or FTP.
The default HTTP and FTP ports used by Zope are
8080 and 8021 respectively. You can change the ports used by
editing ./etc/zope.conf appropriately.
The section in the configuration file looks like this::
<http-server>
# valid keys are "address" and "force-connection-close"
address 8080
# force-connection-close on
</http-server>
The address can just be a port number as shown, or a host:port
pair to bind only to a specific interface.
After making any changes to the configuration file, you need to restart any
running Zope server for the affected instance before changes are in effect.
Running Zope in the Foreground
------------------------------
To run Zope without detaching from the console, use the ``fg``
command (short for ``foreground``)::
$ /path/to/zope/instance/bin/zopectl fg
In this mode, Zope emits its log messages to the console, and does not
detach from the terminal.
Running Zope as a Daemon
------------------------
Once an instance home has been created, the Zope server can now be
started using this command::
$ /path/to/zope/instance/bin/zopectl start
During startup, Zope emits log messages into
`/path/to/zope/instance/log/event.log`. You can examine it with the usual
tools (``cat``, ``more``, ``tail``, etc) and see if there are any errors
preventing Zope from starting.
.. highlight:: none
.. note::
For this to work on Windows, the Zope instance must be installed as
a Service. This is done with::
bin\zopectl install
If you later want to remove this Service, do the following::
bin\zopectl remove
For the full list of options available for setting up Zope as a
Windows Service, do::
bin\zopectl install --help
.. highlight:: bash
Integrating with System Startup
-------------------------------
zopectl can be linked as rc-script in the usual start directories
on linux or other System V unix variants.
You can use ``zopectl`` interactively as a command shell by just
calling it without any arguments. Try ``help`` there and ``help <command>``
to find out about additionally commands of zopectl. These commands
also work at the command line.
.. note::
On Windows, a Service can be installed and set to start
automatically with the following:
.. code-block:: none
bin\zopectl install --startup=auto
Logging In To Zope
------------------
Once you've started Zope, you can then connect to the Zope webserver
by directing your browser to::
http://yourhost:8080/manage
where 'yourhost' is the DNS name or IP address of the machine
running Zope. If you changed the HTTP port as described, use the port
you configured.
You will be prompted for a user name and password. Use the user name
and password you provided in response to the prompts issued during
the "make instance" process.
Now you're off and running! You should be looking at the Zope
management screen which is divided into two frames. On the left you
can navigate between Zope objects and on the right you can edit them
by selecting different management functions with the tabs at the top
of the frame.
If you haven't used Zope before, you should head to the Zope web
site and read some documentation. The Zope Documentation section is
a good place to start. You can access it at http://docs.zope.org/
Troubleshooting
---------------
- This version of Zope requires Python 2.6.4 or better.
It will *not* run with Python 3.x.
- The Python you run Zope with *must* have threads compiled in,
which is the case for a vanilla build. Warning: Zope will not run
with a Python version that uses ``libpth``. You *must* use
``libpthread``.
- To build Python extensions you need to have Python configuration
information available. If your Python comes from an RPM you may
need the python-devel (or python-dev) package installed too. If
you built Python from source all the configuration information
should already be available.
- See the :doc:`CHANGES` for important notes on this version of Zope.
Adding extra commands to Zope
-----------------------------
It is possible to add extra commands to ``zopectl`` by defining *entry points*
in ``setup.py``. Commands have to be put in the ``zopectl.command`` group:
.. code-block:: python
setup(name="MyPackage",
....
entry_points="""
[zopectl.command]
init_app = mypackage.commands:init_application
""")
.. note::
Due to an implementation detail of ``zopectl`` you can not use a minus
character (``-``) in the command name.
This adds a ``init_app`` command that can be used directly from the command
line::
bin\zopectl init_app
The command must be implemented as a Python callable. It will be called with
two parameters: the Zope2 application and a list with all command line
arguments. Here is a basic example:
.. code-block:: python
def init_application(app, args):
print 'Initializing the application'
Make sure the callable can be imported without side-effects, such as setting
up the database connection used by Zope 2.
##############################################################################
#
# Copyright (c) 2007 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
import os
from setuptools import setup, find_packages, Extension
setup(name='Zope2',
version='2.12.15',
url='http://www.zope.org',
license='ZPL 2.1',
description='Zope2 application server / web framework',
author='Zope Foundation and Contributors',
author_email='zope-dev@zope.org',
long_description=file("README.txt").read() + "\n" +
file(os.path.join("doc", "CHANGES.rst")).read(),
packages=find_packages('src'),
namespace_packages=['Products', 'Shared', 'Shared.DC'],
package_dir={'': 'src'},
ext_modules=[
# AccessControl
Extension(
name='AccessControl.cAccessControl',
include_dirs=['include', 'src'],
sources=['src/AccessControl/cAccessControl.c'],
depends=['include/ExtensionClass/ExtensionClass.h',
'include/Acquisition/Acquisition.h']),
# DocumentTemplate
Extension(
name='DocumentTemplate.cDocumentTemplate',
include_dirs=['include', 'src'],
sources=['src/DocumentTemplate/cDocumentTemplate.c'],
depends=['include/ExtensionClass/ExtensionClass.h']),
# indexes
Extension(
name='Products.ZCTextIndex.stopper',
sources=['src/Products/ZCTextIndex/stopper.c']),
Extension(
name='Products.ZCTextIndex.okascore',
sources=['src/Products/ZCTextIndex/okascore.c']),
],
install_requires=[
'Acquisition',
'DateTime',
'ExtensionClass',
'Missing',
'MultiMapping',
'Persistence',
'Products.ZSQLMethods',
'Record',
'RestrictedPython',
'ThreadLock',
'ZConfig',
'ZODB3',
'ZopeUndo',
'docutils',
'five.formlib',
'initgroups',
'pytz',
'setuptools',
'tempstorage',
'transaction',
'zdaemon',
'zLOG',
'zope.component',
'zope.configuration',
'zope.container',
'zope.contentprovider',
'zope.contenttype',
'zope.deferredimport',
'zope.event',
'zope.exceptions',
'zope.i18n [zcml]',
'zope.i18nmessageid',
'zope.interface',
'zope.lifecycleevent',
'zope.location',
'zope.mkzeoinstance',
'zope.pagetemplate',
'zope.processlifetime',
'zope.proxy',
'zope.publisher',
'zope.schema',
'zope.security',
'zope.sendmail<3.7.0',
'zope.sequencesort',
'zope.site',
'zope.size',
'zope.structuredtext',
'zope.tal',
'zope.tales',
'zope.testbrowser [zope-functional-testing]',
'zope.testing',
'zope.traversing',
'zope.viewlet',
'zope.app.publication',
'zope.app.publisher',
'zope.app.schema',
],
include_package_data=True,
zip_safe=False,
entry_points={
'console_scripts': [
'mkzeoinstance=zope.mkzeoinstance:main',
'mkzopeinstance=Zope2.utilities.mkzopeinstance:main',
'runzope=Zope2.Startup.run:run',
'zopectl=Zope2.Startup.zopectl:run',
'zpasswd=Zope2.utilities.zpasswd:main',
],
},
)
Security Architecture
---------------------
Users
-----
Objects representing users may be created in Principia
User Folder objects. User objects maintain the information
used to authenticate users, and allow roles to be associated
with a user.
Permissions
-----------
A "permission" is the smallest unit of access to an object,
roughly equivalent to the atomic permissions seen in NT:
R (Read), W(Write), X(Execute), etc. In Principia, a permission
usually describes a fine-grained logical operation on an object,
such as "View Management Screens", "Add Properties", etc.
Different types of objects will define different permissions
as appropriate for the object.
Types of access
---------------
A "type of access" is a named grouping of 0 or more of the
permissions defined by an object. All objects have one predefined
type of access called Full Access (all permissions defined by that
object). A user who has the special role "Manager" always has Full
Access to all objects at or below the level in the object hierarchy
at which the user is defined.
New types of access may be defined as combinations of the
various permissions defined by a given object. These new
types of access may be defined by the programmer, or by
users at runtime.
Roles
-----
A role is a name that ties users (authentication of identity)
to permissions (authorization for that identity) in the system.
Roles may be defined in any Folder (or Folderish) object in the
system. Sub folders can make use of roles defined higher in the
hierarchy. These roles can be assigned to users. All users,
including non-authenticated users have the built-in role of
"Anonymous".
Principia objects allow the association of defined roles
with a single "type of access" each, in the context of that
object. A single role is associated with one and only one
type of access in the context of a given object.
Examples
--------
User Object1
o has the role "RoleA" o has given "RoleA" Full Access
Result: the user has Full Access to Object1.
User Object2
o has the role "RoleA" o has given "RoleB" Full Access
o has given the role "RoleA" View Access,
a custom type of access that allows only
viewing of the object.
Result: the user has only View Access.
Notes
-----
All objects define a permission called "Default permission". If this
permission is given to a role, users with that role will be able to
access subobjects which do not explicitly restrict access.
Technical
---------
Objects define their permissions as logical operations.
Programmers have to determine the appropriate operations
for their object type, and provide a mapping of permission
name to attribute names. It is important to note that permissions
cannot overlap - none of the attributes named in a permission
can occur in any of the other permissions. The following are
proposed permissions for some current principia objects:
Folder
o View management screens
o Change permissions
o Undo changes
o Add objects
o Delete objects
o Add properties
o Change properties
o Delete properties
o Default permission
Confera Topic
o View management screens
o Change permissions
o Undo changes
o Add objects
o Delete objects
o Add properties
o Change properties
o Delete properties
o Default permission
o Change Configuration
o Add Messages
o Change Messages
o Delete Messages
Tabula Collection
o View management screens
o Change permissions
o Undo changes
o Add objects
o Delete objects
o Add properties
o Change properties
o Delete properties
o Default permission
o Change schema
o Upload data
o Add computed fields
o Change computed fields
o Delete computed fields
Document/Image/File
o View management screens
o Change permissions
o Change/upload data
o View
Session
o View management screens
o Change permissions
o Change session config
o Join/leave session
o Save/discard session
Mail Host
o View management screens
o Change permissions
o Change configuration
To support the architecture, developers must derive an
object from the AccessControl.RoleManager mixin class,
and define in their class an __ac_permissions__ attribute.
This should be a tuple of tuples, where each tuple represents
a permission and contains a string permission name as its first
element and a list of attribute names as its second element.
Example:
__ac_permissions__=(
('View management screens',
['manage','manage_menu','manage_main','manage_copyright',
'manage_tabs','manage_propertiesForm','manage_UndoForm']),
('Undo changes', ['manage_undo_transactions']),
('Change permissions', ['manage_access']),
('Add objects', ['manage_addObject']),
('Delete objects', ['manage_delObjects']),
('Add properties', ['manage_addProperty']),
('Change properties', ['manage_editProperties']),
('Delete properties', ['manage_delProperties']),
('Default permission', ['']),
)
The developer may also predefine useful types of access, by
specifying an __ac_types__ attribute. This should be a tuple of
tuples, where each tuple represents a type of access and contains
a string name as its first element and a list of permission names
as its second element.
By default, only "Full Access" is defined (by the RoleManager mixin).
If you wish to override __ac_types__ to provide convenient types of
access, you must always be sure to define "Full Access" as containing
the names of all possible permissions for your object.
Example:
__ac_types__=(
('Full Access', map(lambda x: x[0], __ac_permissions__)),
('Change', ['Add Objects', 'Add Properties', 'Change Properties']),
)
Developers may also provide pre-defined role names that are
not deletable via the interface by specifying an __ac_roles__
attribute. This is probably not something we'll ever use under
the new architecture, but it's there if you need it.
Example:
__ac_roles__=('Manager', 'Anonymous')
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
__version__='$Revision: 1.9 $'[11:-2]
try:
from hashlib import sha1 as sha
except:
from sha import new as sha
import binascii
from binascii import b2a_base64, a2b_base64
from random import choice, randrange
class PasswordEncryptionScheme: # An Interface
def encrypt(pw):
"""
Encrypt the provided plain text password.
"""
def validate(reference, attempt):
"""
Validate the provided password string. Reference is the
correct password, which may be encrypted; attempt is clear text
password attempt.
"""
_schemes = []
def registerScheme(id, s):
'''
Registers an LDAP password encoding scheme.
'''
_schemes.append((id, '{%s}' % id, s))
def listSchemes():
r = []
for id, prefix, scheme in _schemes:
r.append(id)
return r
class SSHADigestScheme:
'''
SSHA is a modification of the SHA digest scheme with a salt
starting at byte 20 of the base64-encoded string.
'''
# Source: http://developer.netscape.com/docs/technote/ldap/pass_sha.html
def generate_salt(self):
# Salt can be any length, but not more than about 37 characters
# because of limitations of the binascii module.
# 7 is what Netscape's example used and should be enough.
# All 256 characters are available.
salt = ''
for n in range(7):
salt += chr(randrange(256))
return salt
def encrypt(self, pw):
pw = str(pw)
salt = self.generate_salt()
return b2a_base64(sha(pw + salt).digest() + salt)[:-1]
def validate(self, reference, attempt):
try:
ref = a2b_base64(reference)
except binascii.Error:
# Not valid base64.
return 0
salt = ref[20:]
compare = b2a_base64(sha(attempt + salt).digest() + salt)[:-1]
return (compare == reference)
registerScheme('SSHA', SSHADigestScheme())
class SHADigestScheme:
def encrypt(self, pw):
return b2a_base64(sha(pw).digest())[:-1]
def validate(self, reference, attempt):
compare = b2a_base64(sha(attempt).digest())[:-1]
return (compare == reference)
registerScheme('SHA', SHADigestScheme())
# Bogosity on various platforms due to ITAR restrictions
try:
from crypt import crypt
except ImportError:
crypt = None
if crypt is not None:
class CryptDigestScheme:
def generate_salt(self):
choices = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789./")
return choice(choices) + choice(choices)
def encrypt(self, pw):
return crypt(pw, self.generate_salt())
def validate(self, reference, attempt):
a = crypt(attempt, reference[:2])
return (a == reference)
registerScheme('CRYPT', CryptDigestScheme())
class MySQLDigestScheme:
def encrypt(self, pw):
nr = 1345345333L
add = 7
nr2 = 0x12345671L
for i in pw:
if i == ' ' or i == '\t':
continue
nr ^= (((nr & 63) + add) * ord(i)) + (nr << 8)
nr2 += (nr2 << 8) ^ nr
add += ord(i)
r0 = nr & ((1L << 31) - 1L)
r1 = nr2 & ((1L << 31) - 1L)
return "%08lx%08lx" % (r0, r1)
def validate(self, reference, attempt):
a = self.encrypt(attempt)
return (a == reference)
registerScheme('MYSQL', MySQLDigestScheme())
def pw_validate(reference, attempt):
"""Validate the provided password string, which uses LDAP-style encoding
notation. Reference is the correct password, attempt is clear text
password attempt."""
for id, prefix, scheme in _schemes:
lp = len(prefix)
if reference[:lp] == prefix:
return scheme.validate(reference[lp:], attempt)
# Assume cleartext.
return (reference == attempt)
def is_encrypted(pw):
for id, prefix, scheme in _schemes:
lp = len(prefix)
if pw[:lp] == prefix:
return 1
return 0
def pw_encrypt(pw, encoding='SSHA'):
"""Encrypt the provided plain text password using the encoding if provided
and return it in an LDAP-style representation."""
for id, prefix, scheme in _schemes:
if encoding == id:
return prefix + scheme.encrypt(pw)
raise ValueError, 'Not supported: %s' % encoding
pw_encode = pw_encrypt # backward compatibility
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
"""Add security system support to Document Templates
$Id$
"""
from DocumentTemplate import DT_Util
import SecurityManagement, string, math, random, sets
import DocumentTemplate.sequence
from ZopeGuards import safe_builtins
# RestrictedDTML is inserted by AccessControl.Implementation.
# Allow access to unprotected attributes
DT_Util.TemplateDict.__allow_access_to_unprotected_subobjects__=1
string.__allow_access_to_unprotected_subobjects__=1
math.__allow_access_to_unprotected_subobjects__=1
random.__allow_access_to_unprotected_subobjects__=1
sets.__allow_access_to_unprotected_subobjects__=1
DocumentTemplate.sequence.__allow_access_to_unprotected_subobjects__=1
# Add security testing capabilities
class DTMLSecurityAPI:
"""API for performing security checks in DTML using '_' methods.
"""
def SecurityValidate(md, inst, parent, name, value):
"""Validate access.
Arguments:
accessed -- the object that was being accessed
container -- the object the value was found in
name -- The name used to access the value
value -- The value retrieved though the access.
The arguments may be provided as keyword arguments. Some of these
arguments may be ommitted, however, the policy may reject access
in some cases when arguments are ommitted. It is best to provide
all the values possible.
"""
return (SecurityManagement
.getSecurityManager()
.validate(inst, parent, name, value)
)
def SecurityCheckPermission(md, permission, object):
"""Check whether the security context allows the given permission on
the given object.
Arguments:
permission -- A permission name
object -- The object being accessed according to the permission
"""
return (SecurityManagement
.getSecurityManager()
.checkPermission(permission, object)
)
def SecurityGetUser(md):
"""Gen the current authenticated user"""
return (SecurityManagement
.getSecurityManager()
.getUser()
)
def SecurityCalledByExecutable(md):
"""Return a boolean value indicating if this context was called
by an executable"""
r = (SecurityManagement
.getSecurityManager()
.calledByExecutable()
)
if r > 0: return r-1
return r
for name, v in DTMLSecurityAPI.__dict__.items():
if name[0] != '_':
setattr(DT_Util.TemplateDict, name, v)
from types import FunctionType
for name, v in safe_builtins.items():
if type(v) is FunctionType:
v = DT_Util.NotBindable(v)
if name.startswith('__'):
continue
setattr(DT_Util.TemplateDict, name, v)
##############################################################################
#
# Copyright (c) 2003 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
"""C implementation of the access control machinery."""
try:
from AccessControl.cAccessControl import rolesForPermissionOn
from AccessControl.cAccessControl import PermissionRole
from AccessControl.cAccessControl import imPermissionRole
from AccessControl.cAccessControl import _what_not_even_god_should_do
from AccessControl.cAccessControl import RestrictedDTMLMixin
from AccessControl.cAccessControl import aq_validate
from AccessControl.cAccessControl import guarded_getattr
from AccessControl.cAccessControl import setDefaultBehaviors
from AccessControl.cAccessControl import ZopeSecurityPolicy \
as cZopeSecurityPolicy
from AccessControl.cAccessControl import SecurityManager \
as cSecurityManager
except ImportError:
import sys
# make sure a partial import doesn't pollute sys.modules
del sys.modules[__name__]
raise
from AccessControl.ImplPython import RestrictedDTML
from AccessControl.ImplPython import SecurityManager
from AccessControl.ImplPython import ZopeSecurityPolicy
class RestrictedDTML(RestrictedDTMLMixin, RestrictedDTML):
"""A mix-in for derivatives of DT_String.String that adds Zope security."""
class ZopeSecurityPolicy(cZopeSecurityPolicy, ZopeSecurityPolicy):
"""A security manager provides methods for checking access and managing
executable context and policies
"""
class SecurityManager(cSecurityManager, SecurityManager):
"""A security manager provides methods for checking access and managing
executable context and policies
"""
This diff is collapsed.
##############################################################################
#
# Copyright (c) 2003 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
"""Controller that can switch between security machinery implementations.
This module allows configuration of the security implementation after
the initial import of the modules. It is intended to allow runtime
selection of the machinery based on Zope's configuration file.
The helper function defined here switches between the 'C' and 'PYTHON'
security implementations by loading the appropriate implementation
module and wiring the implementation into the other modules of the
AccessControl package that defined the various components before this
module was introduced.
"""
def getImplementationName():
"""Return the name of the implementation currently being used."""
return _implementation_name
def setImplementation(name):
"""Select the policy implementation to use. The 'name' must be either
'PYTHON' or 'C'. NOTE: this function is intended to be called
exactly once, so that the Zope config file can dictate the policy
implementation to be used. Subsequent calls to this function will
have no effect!!
"""
import sys
global _implementation_name
global _implementation_set
if _implementation_set:
return
name = name.upper()
if name == _implementation_name:
return
if name == "C":
from AccessControl import ImplC as impl
elif name == "PYTHON":
from AccessControl import ImplPython as impl
else:
raise ValueError("unknown policy implementation: %r" % name)
_implementation_name = name
for modname, names in _policy_names.items():
__import__(modname)
mod = sys.modules[modname]
for n in names:
setattr(mod, n, getattr(impl, n))
if hasattr(mod, "initialize"):
mod.initialize(impl)
from AccessControl.SecurityManager import setSecurityPolicy
policy = impl.ZopeSecurityPolicy(True, True)
setSecurityPolicy(policy)
_implementation_set = 1
_implementation_name = None
_implementation_set = 0
_policy_names = {
"AccessControl": ("setDefaultBehaviors",
),
"AccessControl.DTML": ("RestrictedDTML",
),
"AccessControl.PermissionRole": ("_what_not_even_god_should_do",
"rolesForPermissionOn",
"PermissionRole",
"imPermissionRole",
),
"AccessControl.SecurityManagement": ("SecurityManager",
),
"AccessControl.SecurityManager": ("SecurityManager",
),
"AccessControl.ZopeGuards": ("aq_validate",
"guarded_getattr",
),
"AccessControl.ZopeSecurityPolicy": ("ZopeSecurityPolicy",
),
}
# start with the default, mostly because we need something for the tests
setImplementation("C")
# allow the implementation to change from the default
_implementation_set = 0
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
'''Objects that implement Permission-based roles.
$Id$'''
# The following names are inserted by AccessControl.Implementation:
#
# rolesForPermissionOn, PermissionRole, imPermissionRole,
# _what_not_even_god_should_do
This diff is collapsed.
This diff is collapsed.
<extension cAccessControl>
source cAccessControl.c
</extension>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
# A wrapper to replace the usage of the zLOG module in cAccessControl without
# having the need to change the C code significantly.
from logging import getLogger
LOG = getLogger('AccessControl')
warn = LOG.warn
This diff is collapsed.
This diff is collapsed.
Architecture of the Zope SecuritySuite
The base class of the suite is "SecurityBase" and contains
the basic function of perform tests for permissions, roles
and perform ZPublisher request:
- _checkPermission()
- _checkRoles()
- _request()
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment