Search code examples
djangoapachepinax

Pinax & Apache: deliver Attachments only to authenticated users


I want that Apache and Pinax only deliver Attachments to authenticated users.

I found this post, but i can't make it work.

My Apache-conf-file:

WSGIPythonPath /usr/local/bin/python

<VirtualHost *:80>
    ServerName      www.domain.com
    ServerAlias     domain.com


    WSGIDaemonProcess k-production python-path=/path/to/app/pinax-env/lib/python2.6/site-packages
    WSGIProcessGroup k-production

    Alias /site_media  /path/to/app/cp/site_media    
    <Directory /path/to/app/cp/site_media>
    Order deny,allow
    Allow from all
    </Directory>

    WSGIScriptAlias /site_media/media/attachments /path/to/app/cp/deploy/pinax.wsgi
    <Directory /path/to/app/cp/site_media/media/attachments>
    Deny from all
    </Directory>

    XSendFile On
    XSendFileAllowAbove On

    WSGIScriptAlias / /path/to/app/cp/deploy/pinax.wsgi
    <Directory /path/to/app/cp/deploy>
        Order deny,allow
        Allow from all
    </Directory>

</VirtualHost>

and my (still rough) view, that should get called:

@login_required 
def sendfile(request, slug): 

    app, content_object_id, img = slug.split('/')
    project_file = get_object_or_404(Attachment, attachment_file = 'attachments/'+slug) 
    response = HttpResponse() 
    response['X-Sendfile'] =  os.path.join(settings.MEDIA_ROOT,   'attachments/'+slug) 
    content_type = 'application/octet-stream' 
    response['Content-Type'] = content_type 
    response['Content-Disposition'] = 'attachment; filename="%s"' %  os.path.basename(os.path.join(settings.MEDIA_ROOT,   'attachments/'+slug))
    return response 

Apache throws a 403 no matter if the user is logged in.

Via the develoment-server i can access the view, but no data will get transmitted.

What is wrong?


Solution

  • I was trying to do pretty much exactly the same thing, and the solution turned out to be not using WSGIScriptAlias, and instead using a regular Alias to a directory that defined a wsgi handler. For the view I basically just wrote a wrapper around django.views.static.serve.

    My apache conf ended up looking like this:

    # myproject
    <VirtualHost *:8080>
        #DocumentRoot /var/www/myproject/public
        ServerName myproject
        ErrorLog /var/www/myproject/logs/apache_error_log
        CustomLog /var/www/myproject/logs/apache_access_log common
    
        AliasMatch ^/(media/uploads/protected/.*) /var/www/myproject/src/myproject-trunk/server/django.wsgi/$1
        Alias /media/ /var/www/myproject/public/media/
        Alias / /var/www/myproject/src/myproject-trunk/server/django.wsgi/
    
        <Directory /var/www/myproject/src/myproject-trunk/server>
            Options ExecCGI
            AddHandler wsgi-script .wsgi
            # WSGIApplicationGroup %{GLOBAL}
            Order allow,deny
            Allow from all
        </Directory>
    
        <Directory /var/www/myproject/public/media>
            Order deny,allow
            Allow from all
        </Directory>
    </VirtualHost>