Name Last modified Size Description
Parent Directory -
README.html 15-Jul-2007 16:14 10K
pybridge-0.1.tar.gz 15-Jul-2007 16:14 17K
PyBridge is a framework allowing Drupal page-generating modules to be written in Python.
It is intended for people who, like me, enjoy and respect the Drupal web framework, but enjoy Python much more than PHP.
Also, PyBridge could be helpful for integrating existing Python code into a Drupal environment.
PyBridge installation is pretty straightforward:
- Ensure that within your drupal web hosting environment, the shell command 'python' runs Python 2.4 or later
- Ensure the directory 'sites/all/modules' exists, where 'sites' is a subdirectory of the root drupal installation directory
- Unpack the tarball pybridge-x.x.tar.gz within sites/all/modules
- Create the subdirectory 'python' in the drupal root directory
- Within this 'python' directory, create a file .htaccess with the contents:
Deny from All- Log into drupal site as admin, go to Administer->Site Building->Modules and enable the module PyBridge
- Point your browser at http://mysite.com/pybridge. You should see a diagnostic page generated by the default Python handler.
Study the filehdlr_default.py(insites/all/modules/pybridge/python), especially the.handle()method of theHandlerclass.
This method is the default handler for PyBridge, and internally demonstrates much of what is available in the Python environment for Drupal PyBridge modules.
When you're ready, write your own handler module, eg, 'hdlr_foo.py', and put it into /path/to/drupal/root/sites/all/modules/pybridge/python or into /path/to/drupal/root/python.
Here's a minimal boilerplate for your module:The basic guts of it is:from drupal import Drupal class Handler(Drupal): def handle(self): self.funcs.drupal_set_title("My 'foo' handler") return "handler not implemented yet"1. Access to PHP variables
- You can read and write to Drupal PHP local and global variables by reading and writing to self.locals[varname] and self.globals[varname], respectively
- If you try to read anything from Drupal that contains a Drupal object, you'll cop an exception. Sorry, you can only read/write strings, ints, floats and dicts
2. Calling PHP functions
- you can call native PHP or drupal API functions with parameters by:
This call will return whatever is returned by the drupal function. You can call any function which is available in the drupal environment, including normal PHP functions, drupal api functions etcself.funcs.funcname(arg1, arg2...)3. Evaluating expressions in PHP
- you can evaluate arbitrary PHP expressions within the drupal PHP environment by doing:
This call will return the result of the PHP expression evaluationself.eval("any php expression")4. Executing arbitrary PHP code within PHP
- you can execute arbitrary PHP code within the drupal PHP environment by doing:
Note that this uses the PHP 'eval()' function, so your code block must end with a 'return [something];' statement.self.execute("any PHP code")5. Generating page content
- Whatever your
.handle()method returns will be served up as page content.
Most interaction with Drupal PHP environment is done through the following attributes of yourHandlerclass (inherited from theDrupalclass):
- get - a dict of values from the http GET request
- post - a dict of values from the http POST request
- cookies - a dict of cookie values - not that to set a cookie you need to call
self.funcs.setcookie()orself.funcs.setrawcookie()- isAdmin - a bool indicating whether the user visiting the site is logged in as an admin
- rootdir - string - the root directory at which the drupal site is installed
- pathbits - any uri path components in excess of the handler name
- roles - list - the drupal user roles to which the current user belongs
- locals - a dict-like object for reading/writing php local variables
- globals - a dict-like object for reading/writing php/drupal global variables
- funcs - used for calling PHP functions. Get an attribute from, or index, this attribute, and you'll get a callable object which you can call with arguments and get a return value from. For example:
self.funcs.drupal_set_title("New page title")- env - a dict-like object with all the drupal/PHP environment vars, including all the vars set by Apahe, such as
REQUEST_URI,SCRIPT_PATHetc. Note that setting any item in this object will have no effect
By default, any hit to the uri/pybridgewill cause the default python handler (inhdlr_default.py) to run.
You can implement n other handlers, calling themhdlr_foo.py,hdlr_bar.pyetc.
PyBridge decides which module to run in the following way:This scheme, of allowing for several python handlers, allows for several discrete python modules to work together on the one drupal site.
- If there are any path components beyond
pybridge, for instance if the URI is/pybridge/foo/fred, then the first path element afterpybridge(in this case,foo) will be taken as the name of the desired handler.- If there are no path components beyond
pybridge, but if there is aGETvariable calledhdlr, then the value of this variable will be taken as the name of the desired handler- If a handler has not been chosen by either of the two methods above, or if there is no corresponding file
hdlr_<handlername>.py, then pybridge will fall back to executing the default handler, fromhdlr_default.py
Note that several PyBridge features, especially those allowing for execution of arbitrary expressions and code, can introduce a potentially devastating security hole into your Drupal installation.
To mitigate the risks:
- Ensure both directories:
/path/to/site/root/sites/all/modules/pybridgeand/path/to/site/root/pythondirectories - both contain .htaccess files with aDeny from alldirective, to prevent HTTP access to these directories- Adjust the unix permissions of both these directories to reduce or eliminate the risk of unauthorised access
- Don't install PyBridge into a Drupal installation running on a shared host, unless the hosting environment is set up with SUEXEC, so that scripts within your account run with your user id, instead of a common user id such as
www-data.- Take extreme care in the coding of your python handler modules, especially with any trust you place in data coming from users via cookies, GET, POST.
Assume that any such data may be malformed (eg SQL injection attempts) as a deliberate attempt to compromise your site.
Note that all kinds of crap can turn up in user data, including but not limited to:Don't store any
- javascript code and cross-site-scripting attacks
- browser exploits
- fiddling with quotes to attempt access to the Drupal database
- fiddling with cookies to attempt execution of arbitrary python or PHP code
- other embedded nasties
GETorPOSTuser data into the database without carefully screening it first- Don't use pickled cookies without an HMAC signature
- Don't depend on security through obscurity. Assume that thousands of hackers have access to all your python source and have studied it for weaknesses