jessepeterson / margarita

Web frontend for reposado
The Unlicense
245 stars 40 forks source link

Secure web application #3

Open martinvandiemen opened 12 years ago

martinvandiemen commented 12 years ago

When running margarita every visitor of the web application is able to make changes. Please integrate a simple authentication form: http://packages.python.org/Flask-Login/

jessepeterson commented 12 years ago

You may want to check out Tim Sutton's work on this: https://github.com/timsutton/margarita/tree/flask-basic-auth

I'm not yet sure of an architecture for authentication. At some point there'll be documentation on running this as a FastCGI app then authentication, encryption (SSL), etc. could all be handled at that higher level like Apache or Lighttpd.

martinvandiemen commented 12 years ago

Thanks for the suggestion. Tim's solutions will work for now.

timsutton commented 12 years ago

I missed seeing this earlier, but I'd like to know if anyone happens to test loading margarita via a WSGI server instead, and handle the auth there. I'm not experienced with WSGI or web apps in general, so I'll just post my results, and maybe someone with more knowledge than I can comment.

I tested adding the app using mod_wsgi on Apache, using the following wsgi.py script:

import sys sys.path.insert(0, "/path/to/my/margarita/checkout") from margarita import app as application

loaded into my VirtualHost using:

WSGIScriptAlias / /path/to/my/margarita/checkout/wsgi.py
WSGIDaemonProcess margarita user=reposado group=www-data threads=1

The template loaded, but the content area was empty. Checking the JavaScript debugger I saw an error that traced back to jQuery. The VirtualHost is configured to use port 8666.

POST http://sus.my.org:8666/list_branches 500 (INTERNAL SERVER ERROR)

f.support.ajax.f.ajaxTransport.send     jquery-1.7.2.min.js:4
f.extend.ajax                           jquery-1.7.2.min.js:4
f.each.f.(anonymous function)           jquery-1.7.2.min.js:4
refresh_updates_table                   margarita.js:65
(anonymous function)                    :8666/:49
f.Callbacks.o                           jquery-1.7.2.min.js:2
f.Callbacks.p.fireWith                  jquery-1.7.2.min.js:2
e.extend.ready                          jquery-1.7.2.min.js:2
c.addEventListener.B                    jquery-1.7.2.min.js:2
jessepeterson commented 12 years ago

This was exactly the idea above on extending architecture so I'd probably want to have that supported. Not sure about the error, though there is a 500 error so that indicates a problem in the "server side" I'd think. The anonymous function is probably the jQuery ajax call that's done asynchronously. Is there anything in the logs? A Python traceback perhaps?

timsutton commented 12 years ago

Nothing I can see. I've enabled debug-level logging for both Apache's and my vhost, and can see that if I add something to stderr in margarita.py it definitely shows up in the Apache log.

I added the sample debugging script to my wsgi.py to trigger a stack trace as suggested at the end of the mod_wsgi Debugging page:

http://code.google.com/p/modwsgi/wiki/DebuggingTechniques

However when I touch the file to trigger a stack trace I can't get it to dump anything besides the first thread which is doing the traceback itself. I don't know if that's because it's 'missing' the thread (a timing issue) or something else that I'm equally unfamiliar with. Doesn't help if I change the timing interval.

I'll paste my VirtualHost config just in case there's something obvious that jumps out to anyone.

<VirtualHost *:8666>
    ServerName sus.my.org
    DocumentRoot /home/reposado/git/margarita
    LogLevel debug
    WSGIDaemonProcess margarita user=reposado group=www-data threads=1
    WSGIScriptAlias / /home/reposado/git/margarita/wsgi.py

    Options -Indexes
    <Directory "/home/reposado/git/margarita">
        WSGIProcessGroup margarita
        WSGIApplicationGroup %{GLOBAL}
        Order deny,allow
        Allow from all
    </Directory>
    <Location "/">
        SetHandler None
    </Location>
    ErrorLog ${APACHE_LOG_DIR}/margarita-error.log
    CustomLog ${APACHE_LOG_DIR}/margarita-access.log combined
</VirtualHost>
jessepeterson commented 12 years ago

What does your wsgi.py look like? Is Flask's debugging turned on?

timsutton commented 12 years ago

Wow, I should've thought to look up debug options within Flask itself. It revealed the issue right away:

 [error] mod_wsgi (pid=32312): Exception occurred processing WSGI script '/home/reposado/git/margarita/wsgi.py'.
 [error] Traceback (most recent call last):
 [error]   File "/usr/local/lib/python2.6/dist-packages/flask/app.py", line 1518, in __call__
 [error]     return self.wsgi_app(environ, start_response)
 [error]   File "/usr/local/lib/python2.6/dist-packages/flask/app.py", line 1506, in wsgi_app
 [error]     response = self.make_response(self.handle_exception(e))
 [error]   File "/usr/local/lib/python2.6/dist-packages/flask/app.py", line 1504, in wsgi_app
 [error]     response = self.full_dispatch_request()
 [error]   File "/usr/local/lib/python2.6/dist-packages/flask/app.py", line 1264, in full_dispatch_request
 [error]     rv = self.handle_user_exception(e)
 [error]   File "/usr/local/lib/python2.6/dist-packages/flask/app.py", line 1262, in full_dispatch_request
 [error]     rv = self.dispatch_request()
 [error]   File "/usr/local/lib/python2.6/dist-packages/flask/app.py", line 1248, in dispatch_request
 [error]     return self.view_functions[rule.endpoint](**req.view_args)
 [error]   File "/home/reposado/git/margarita/margarita.py", line 48, in list_branches
 [error]     catalog_branches = reposadocommon.getCatalogBranches()
 [error]   File "/home/reposado/git/margarita/reposadolib/reposadocommon.py", line 253, in getCatalogBranches
 [error]     return getDataFromPlist('CatalogBranches.plist')
 [error]   File "/home/reposado/git/margarita/reposadolib/reposadocommon.py", line 236, in getDataFromPlist
 [error]     os.path.join(metadata_dir, filename))
 [error]   File "/usr/lib/python2.6/posixpath.py", line 67, in join
 [error]     elif path == '' or path.endswith('/'):
 [error] AttributeError: 'NoneType' object has no attribute 'endswith'

The function reposadolib uses to determine the directory that a script using reposadolib is run from ( get_main_dir() ) was just returning None. The WSGIDaemonProcess assumes different working directories depending on the version of mod_wsgi, if it's not specified.

To specify using the reposado code dirrectory as that to be used for the process, I added the 'home' option to the WSGIDaemonProcess Apache directive in my VirtualHost:

WSGIDaemonProcess margarita user=reposado group=www-data threads=1 home=/home/reposado/git/reposado/code

And that was enough. I quickly tested the functionality of adding and removing updates from branches and it seems fine.

When I get a chance I'll throw together a quick doc and sample wsgi.py and submit a pull request. I can't recommend any 'best practice' as this is very new to me, but I can at least post what I've done in my setup once I've had time to test it a bit more.

jessepeterson commented 12 years ago

Great! Thanks for tracking that down! I'll look forward to your doc. I'd probably want the WSGI docs to be in the main docs FWIW. But perhaps finally a break-out into a Wiki page will be due.

ghost commented 12 years ago

using the -b 127.0.0.1 flag limits the access to the web from the server only. Not a real auth but does the trick for me

timsutton commented 12 years ago

Would you prefer to have this appended to the existing readme, or a topic-specific one? (ie. 'README-WSGI.md')

On 2012-04-29, at 5:24 PM, Jesse Peterson reply@reply.github.com wrote:

Great! Thanks for tracking that down! I'll look forward to your doc. I'd probably want the WSGI docs to be in the main docs FWIW. But perhaps finally a break-out into a Wiki page will be due.


Reply to this email directly or view it on GitHub: https://github.com/jessepeterson/margarita/issues/3#issuecomment-5408840

ghost commented 11 years ago

I'm interested by the WSGI setup. I'm unable to make it working with CentOS.

timsutton commented 11 years ago

I had let this issue die, unfortunately, but Joe Wollard (@buffalo) has just put together a great walkthrough on his blog:

http://denisonmac.wordpress.com/2013/02/28/running-margarita-in-apache

He's using Ubuntu in the guide. @natewalck put together directions for running MunkiWebAdmin on CentOS based on my notes for Debian, and he found that on CentOS one extra item required was the WSGISocketPrefix Apache directive and manually creating a socket directory for it:

https://code.google.com/p/munki/wiki/MunkiWebAdminLinuxSetup

Hope that helps someone.

jessepeterson commented 11 years ago

Wow, fantastic! Thanks for sharing!

jelockwood commented 10 years ago

For what its worth Apple's Server.app only accepts WSGI webapps if the file extension is .wsgi Server.app has the benefit of including mod_wsgi as standard.

I have not yet tried setting up Margarita in Server.app but have successfully done Crypt Server and MunkiWebAdmin. I have written some general notes on defining a webapp in Server.app here http://jelockwood.blogspot.co.uk/2013/06/running-django-webapps-with-os-x.html

I now also define them using virtualenv and this works fine even with Server.app, in fact it usually makes things a little easier as I don't have to alter the paths in the .wsgi file provided by the developer.

majorsl commented 10 years ago

Has anyone got this working with OS X Server? I followed Joe Wollard's basic instructions on getting the .wsgi started and put it together with some of jelockwood's hints. I get the webapp shown in Server.app, but access denied when I try to go to the site. I feel like I'm very close, just missing something... permissions/user:group for the webserver/wsgi possibly.

cbrherms commented 9 years ago

Did anything come of this? Would be interested in having a secure login as well as getting it working with server.app

benbasscom commented 9 years ago

Same here - I would love to get some basic authentication for margarita - especially for OS X server.

benbasscom commented 9 years ago

Ok - I took some ideas from Tim Sutton's fork (https://github.com/timsutton/margarita/tree/flask-basic-auth )and poking around with the basic auth from (http://flask.pocoo.org/snippets/8/) and was able to get basic authentication working within the flask environment for the latest version of margarita.

https://github.com/benbasscom/margarita/tree/flask-basic-auth