Let's say you have a model to store media files (images, movies, etc)
db.define_table('album',SQLField('media','upload'))
and you have Auth and Crud enabled via:
from gluon.tools import *
auth=Auth(globals(),db)
auth.define_tables()
crud=Crud(globals(),db)
In order to allow login/logout, post media files and retrieve them, in the controller you have:
@auth.requires_login()
def post(): return dict(form=crud.create(db.album))
def download(): return response.download(request,db)
def user(): return dict(form=auth())
How do make sure that only the user who posted a media file can download the file that he/she posted?
You can in two steps:
This is accomplished by the following complete controller:
def give_permission(form):
auth.add_permission(0,'read',db.album,form.vars.id)
def check_permission(row):
return auth.is_logged_in() and auth.has_permission('read',db.album,row.id)
db.album.media.authorize=check_permission
@auth.requires_login()
def post(): return dict(form=crud.create(db.album,onaccept=give_permission))
def download(): return response.download(request,db)
def user(): return dict(form=auth())
Notice that web2py by default streams all large files in upload and download and supports range requests for partial content. This means you can use the above code to upload and serve (with access control) not just images but also movies of arbitrary length.
The first argument 0 of auth.add_permission refers to the unique group of the current logged in user.
This example code works on the Google App Engine (GAE) with the size limitations imposed by GAE. In the GAE case uploaded media files are stored in Google Big Table.