Fix #1154: replace gevent by gunicorn, improve README.txt and
create a mandaye_admin.py script
This commit is contained in:
parent
8992e2007d
commit
417b837019
112
README.rst
112
README.rst
|
@ -18,18 +18,18 @@ version 3 for distribution.
|
|||
Features
|
||||
--------
|
||||
|
||||
TODO: improve this part
|
||||
|
||||
* Filters: You can filter the request or the response with one or many filters.
|
||||
You can serve static response in a filter.
|
||||
There 3 types of filters:
|
||||
* on_request
|
||||
* on_response
|
||||
* reponse
|
||||
* Dispatcher: This will call the right filters
|
||||
* Authentification management
|
||||
* Sql and ldap authentification
|
||||
* Authentification through Authentic2 idp (SAML2 and CAS)
|
||||
* Mapping / dispatching::
|
||||
With Mandaye you can define your own mapping files. This allows you to call your own filters
|
||||
on the right HTTP requests. See the config part for more details.
|
||||
* Filters::
|
||||
You can define your own filters with Mandaye. This filter have access to the WSGI environment and
|
||||
could modify the HTTP requests and / or responses.
|
||||
* Local authentification::
|
||||
Mandaye provide a sql local authentification but you can also implement your own
|
||||
local authentification.
|
||||
* Distant authentification::
|
||||
At the moment Mandaye only support form replay for a distant authentification but we will provide
|
||||
SAML 2.0, OpenID and CAS support.
|
||||
|
||||
|
||||
Installation
|
||||
|
@ -40,52 +40,72 @@ Dependencies
|
|||
|
||||
You must install the following packages to use Mandaye
|
||||
|
||||
* Gevent 0.13::
|
||||
|
||||
From sources: http://pypi.python.org/pypi/gevent
|
||||
Debian based distribution: apt-get install python-gevent
|
||||
|
||||
* Poster 0.8::
|
||||
|
||||
From sources: http://pypi.python.org/pypi/poster/
|
||||
Debian based distribution: apt-get install python-poster
|
||||
|
||||
* SQLAlchemy 0.7.2::
|
||||
|
||||
From sources: http://pypi.python.org/pypi/SQLAlchemy
|
||||
|
||||
* Beaker 1.5.4::
|
||||
|
||||
From sources: http://pypi.python.org/pypi/Beaker
|
||||
|
||||
* Mako 0.4.2::
|
||||
|
||||
From sources: http://pypi.python.org/pypi/Mako
|
||||
|
||||
* lxml 2.3.1::
|
||||
|
||||
From sources: http://pypi.python.org/pypi/lxml
|
||||
* Python >= 2.5:: http://python.org/
|
||||
* Setuptools >= 0.6:: http://pypi.python.org/pypi/setuptools
|
||||
* Gunicorn >= 0.13:: http://pypi.python.org/pypi/gunicorn
|
||||
* Poster >= 0.8:: http://pypi.python.org/pypi/poster/
|
||||
* SQLAlchemy >= 0.7:: http://pypi.python.org/pypi/SQLAlchemy
|
||||
* Beaker >= 1.6:: http://pypi.python.org/pypi/Beaker
|
||||
* Mako >= 0.4:: http://pypi.python.org/pypi/Mako
|
||||
* lxml >= 2.3:: http://pypi.python.org/pypi/lxml
|
||||
|
||||
You can install all those dependencies quickly using pip::
|
||||
|
||||
pip install gevent poster SQLAlchemy Beaker Mako lxml
|
||||
pip install gevent poster SQLAlchemy Beaker Mako lxml gunicorn
|
||||
|
||||
or easy_install::
|
||||
|
||||
easy_install gevent poster SQLAlchemy Beaker Mako lxml
|
||||
easy_install gevent poster SQLAlchemy Beaker Mako lxml gunicorn
|
||||
|
||||
or apt-get (Debian based distributions)::
|
||||
|
||||
apt-get install gunicorn python-poster python-sqlalchemy python-beaker python-mako python-lxml python-setuptools
|
||||
|
||||
It's recommanded to install the following modules
|
||||
|
||||
* PyCrypto >= 2.3:: http://pypi.python.org/pypi/pycrypto
|
||||
* Static >= 0.4:: http://pypi.python.org/pypi/static
|
||||
|
||||
You can install this Python modules with pip::
|
||||
|
||||
pip install pycrypto static
|
||||
|
||||
Quick installation
|
||||
------------------
|
||||
|
||||
Install at least Python >=2.5 and setuptools or distribute and enter this command in a shell::
|
||||
|
||||
$ python setup.py install
|
||||
|
||||
If you want to develop use this command line::
|
||||
|
||||
$ python setup.py develop
|
||||
|
||||
|
||||
Quick Start
|
||||
-----------
|
||||
|
||||
Configure mandaye/config.py
|
||||
Configure MANDAYE_PATH/mandaye/config.py with your own preferences.
|
||||
You must configure the database uri and the log file.
|
||||
|
||||
Then launch the following commands::
|
||||
First create your database::
|
||||
|
||||
./mandayectl --createdb
|
||||
./mandayectl --start
|
||||
$ mandaye_admin.py --createdb
|
||||
|
||||
You should see the following output::
|
||||
Launch mandaye server:::
|
||||
|
||||
Database created
|
||||
Starting Mandaye x.x.x.x:xx ...
|
||||
$ mandaye_server.py
|
||||
|
||||
mandaye_server.py use gunicorn and gunicorn options (please read http://gunicorn.org/configure.html)
|
||||
|
||||
You could alse use gunicorn.conf.py-sample (in the mandaye files)::
|
||||
|
||||
$ mandaye_server.py -c PATH_TO_THE_FILE/gunicorn.conf.py
|
||||
|
||||
or::
|
||||
|
||||
$ mandaye_server.py -c PATH_TO_THE_FILE/gunicorn.conf.py -b 0.0.0.0:4242
|
||||
|
||||
Configuration
|
||||
=============
|
||||
TODO
|
||||
|
|
35
crypt_pwd.py
35
crypt_pwd.py
|
@ -1,35 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" Script to crypt mandaye passwords
|
||||
"""
|
||||
|
||||
import base64
|
||||
import logging
|
||||
|
||||
from Crypto.Cipher import AES
|
||||
from mandaye import config
|
||||
from mandaye.models import ExtUser
|
||||
from mandaye.db import sql_session
|
||||
|
||||
def encrypt_pwd(pwd):
|
||||
logging.debug("Encrypt password")
|
||||
enc_pwd = pwd
|
||||
if config.encrypt_secret:
|
||||
try:
|
||||
cipher = AES.new(config.encrypt_secret, AES.MODE_CFB)
|
||||
enc_pwd = cipher.encrypt(pwd)
|
||||
enc_pwd = base64.b64encode(enc_pwd)
|
||||
except Exception, e:
|
||||
if config.debug:
|
||||
traceback.print_exc()
|
||||
logging.warning('Password encrypting failed %s' % e)
|
||||
else:
|
||||
logging.warning("You must set a secret to use pwd encryption")
|
||||
return enc_pwd
|
||||
|
||||
for user in sql_session().query(ExtUser).all():
|
||||
user.password = encrypt_pwd(user.password)
|
||||
|
||||
sql_session().commit()
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
PID_DIR = '/var/run/'
|
||||
|
||||
# Gunicorn configuration (http://gunicorn.org/configure.html)
|
||||
#bind = '127.0.0.1:8000' # Default bind
|
||||
#bind = 'unix:%s/mandaye.sock' % PID_DIR # Unix socket
|
||||
|
||||
#pidfile = '%s/mandaye.pid' % PID_DIR
|
||||
timeout = 60
|
||||
worker = 4
|
||||
worker_class = 'sync'
|
||||
#worker_connections = 1000 # The maximum number of simultaneous clients
|
||||
#max_requests = 0 # The maximum number of requests a worker will process before restarting
|
||||
|
||||
# User / Group
|
||||
#user = 'www-data'
|
||||
#group = 'www-data'
|
||||
|
||||
# Log
|
||||
loglevel = "info"
|
||||
accesslog = '/var/log/mandaye/mandaye-access.log'
|
||||
errorlog = "/var/log/mandaye/mandaye-gunicorn.log"
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
VERSION=0.1
|
||||
VERSION=0.2
|
||||
|
||||
import logging
|
||||
from logging import FileHandler
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
from logging import DEBUG
|
||||
import logging
|
||||
from mandaye.exceptions import ImproperlyConfigured
|
||||
|
||||
# Mandaye configuration
|
||||
host = '127.0.0.1'
|
||||
port = 8088
|
||||
|
||||
# Needed if ssl is activated
|
||||
ssl = False
|
||||
keyfile = ''
|
||||
|
@ -13,8 +9,8 @@ certfile = ''
|
|||
# Log configuration
|
||||
debug = False
|
||||
syslog = False
|
||||
log_level = DEBUG
|
||||
log_file = '/tmp/mandaye.log'
|
||||
log_file = '/var/log/mandaye/mandaye.log'
|
||||
log_level = logging.INFO
|
||||
|
||||
# Template directory
|
||||
template_directory = 'mandaye/templates'
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
|
||||
# gevent patching
|
||||
#from gevent import monkey
|
||||
#monkey.patch_all()
|
||||
|
||||
import Cookie
|
||||
import config
|
||||
import logging
|
||||
|
@ -16,7 +12,6 @@ import time
|
|||
|
||||
from beaker.middleware import SessionMiddleware
|
||||
from cgi import escape
|
||||
from gevent.pywsgi import WSGIServer, WSGIHandler
|
||||
from static import Cling
|
||||
|
||||
from mandaye.config import debug
|
||||
|
@ -172,23 +167,3 @@ class MandayeApp(object):
|
|||
response.headers.items())
|
||||
return [response.msg]
|
||||
|
||||
class ServerHandler(WSGIHandler):
|
||||
|
||||
def log_request(self):
|
||||
logging.info(self.format_request())
|
||||
|
||||
def serve():
|
||||
"""Convenience function to immediately start a server instance."""
|
||||
wsgi_app = SessionMiddleware(MandayeApp(), config.session_opts)
|
||||
if config.ssl:
|
||||
s = WSGIServer((config.host, config.port), wsgi_app,
|
||||
keyfile=config.keyfile, certfile=config.certfile,
|
||||
handler_class=ServerHandler)
|
||||
else:
|
||||
s = WSGIServer((config.host, config.port), wsgi_app,
|
||||
handler_class=ServerHandler)
|
||||
try:
|
||||
s.serve_forever()
|
||||
except KeyboardInterrupt:
|
||||
s.stop()
|
||||
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" Script to administrate mandaye server
|
||||
"""
|
||||
|
||||
import base64
|
||||
import logging
|
||||
|
||||
from optparse import OptionParser
|
||||
|
||||
from Crypto.Cipher import AES
|
||||
from mandaye import config
|
||||
from mandaye.models import ExtUser
|
||||
from mandaye.db import sql_session
|
||||
|
||||
|
||||
def get_cmd_options():
|
||||
usage = "usage: %prog --createdb|--cryptpwd"
|
||||
parser = OptionParser(usage=usage)
|
||||
parser.add_option("--createdb",
|
||||
dest="createdb",
|
||||
default=False,
|
||||
action="store_true",
|
||||
help="Create the Mandaye database"
|
||||
)
|
||||
parser.add_option("--cryptpwd",
|
||||
dest="cryptpwd",
|
||||
default=False,
|
||||
action="store_true",
|
||||
help="Crypt external password in Mandaye's database"
|
||||
)
|
||||
(options, args) = parser.parse_args()
|
||||
if not options.createdb:
|
||||
parser.error("You must use option --createdb")
|
||||
return options
|
||||
|
||||
def encrypt_pwd(pwd):
|
||||
logging.debug("Encrypt password")
|
||||
enc_pwd = pwd
|
||||
if config.encrypt_secret:
|
||||
try:
|
||||
cipher = AES.new(config.encrypt_secret, AES.MODE_CFB)
|
||||
enc_pwd = cipher.encrypt(pwd)
|
||||
enc_pwd = base64.b64encode(enc_pwd)
|
||||
except Exception, e:
|
||||
if config.debug:
|
||||
traceback.print_exc()
|
||||
logging.warning('Password encrypting failed %s' % e)
|
||||
else:
|
||||
logging.warning("You must set a secret to use pwd encryption")
|
||||
return enc_pwd
|
||||
|
||||
def main():
|
||||
options = get_cmd_options()
|
||||
if options.createdb:
|
||||
logging.info("Creating database...")
|
||||
if config.db_url:
|
||||
from mandaye.models import Base
|
||||
from sqlalchemy import create_engine
|
||||
engine = create_engine(config.db_url)
|
||||
Base.metadata.create_all(engine)
|
||||
logging.info("Database created")
|
||||
if options.cryptpwd:
|
||||
for user in sql_session().query(ExtUser).all():
|
||||
user.password = encrypt_pwd(user.password)
|
||||
sql_session().commit()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,29 @@
|
|||
#!/home/jschneider/temp/test/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" Script to launch mandaye with gunicorn server
|
||||
"""
|
||||
|
||||
import logging
|
||||
import sys
|
||||
import os
|
||||
|
||||
from gunicorn.app.wsgiapp import WSGIApplication
|
||||
|
||||
class WSGIApplication(WSGIApplication):
|
||||
|
||||
def init(self, parser, opts, args):
|
||||
self.cfg.set("default_proc_name", "mandaye.wsgi:application")
|
||||
self.app_uri = "mandaye.wsgi:application"
|
||||
|
||||
sys.path.insert(0, os.getcwd())
|
||||
|
||||
def main():
|
||||
""" The ``gunicorn`` command line runner for launcing Gunicorn with
|
||||
generic WSGI applications.
|
||||
"""
|
||||
logging.info('Launching Mandaye ...')
|
||||
WSGIApplication("%prog [OPTIONS]").run()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
50
mandayectl
50
mandayectl
|
@ -1,50 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" Script to start and stop mandaye server
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
from optparse import OptionParser
|
||||
|
||||
from mandaye import config
|
||||
from mandaye import server
|
||||
|
||||
def get_cmd_options():
|
||||
usage = "usage: %prog --start|--createdb"
|
||||
parser = OptionParser(usage=usage)
|
||||
parser.add_option("--start",
|
||||
dest="start",
|
||||
default=False,
|
||||
action="store_true",
|
||||
help="Start Mandaye server"
|
||||
)
|
||||
parser.add_option("--createdb",
|
||||
dest="createdb",
|
||||
default=False,
|
||||
action="store_true",
|
||||
help="Create the Mandaye database"
|
||||
)
|
||||
(options, args) = parser.parse_args()
|
||||
if not options.start and not options.createdb:
|
||||
parser.error("You must use option --start | --createdb")
|
||||
return options
|
||||
|
||||
def main():
|
||||
options = get_cmd_options()
|
||||
if options.createdb:
|
||||
logging.info("Creating database...")
|
||||
if config.db_url:
|
||||
from mandaye.models import Base
|
||||
from sqlalchemy import create_engine
|
||||
engine = create_engine(config.db_url)
|
||||
Base.metadata.create_all(engine)
|
||||
print "Database created"
|
||||
|
||||
if options.start:
|
||||
print "Starting Mandaye %s:%d .." % (config.host, config.port)
|
||||
server.serve()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
4
setup.py
4
setup.py
|
@ -17,12 +17,12 @@ setup(name="mandaye",
|
|||
author_email="info@entrouvert.org",
|
||||
maintainer="Jerome Schneider",
|
||||
maintainer_email="jschneider@entrouvert.com",
|
||||
scripts=['mandayectl'],
|
||||
scripts=['mandaye_server.py', 'mandaye_admin.py'],
|
||||
packages=find_packages(),
|
||||
package_data={},
|
||||
install_requires=[
|
||||
'beaker>=1.5',
|
||||
'gevent>=0.13',
|
||||
'gunicorn>=0.13',
|
||||
'mako>=0.3',
|
||||
'poster>=0.8',
|
||||
'pycrypto>=2.0',
|
||||
|
|
Reference in New Issue