For encrypting and decrypting files using a validator works quite well.

In our model we have something like:
              Field('data',
                    'upload',
                    requires=[IS_NOT_EMPTY(),
                              IS_LENGTH(26214400, 0, error_message="File 
too large."),
                              TypeValidator(),         # use libmagic to 
test file type
                              AVValidator(),             # run antivirus
                              SecureValidator(KEY)],

Where SecureValidator is something like:
class SecureValidator:
    '''
    Encrypts files
    '''
    def __init__(self, phrase, error_message="Error"):
        self.phrase = phrase
        self.e = error_message

    def __call__(self, value):
        # Encrypt data here prior to passing to defualt web2py store method
        val = buffer(value.file.read())
        value.file.seek(0, os.SEEK_SET)
        value.file.truncate()   # Remove old data
        val = encrypt_binary(val, phrase=self.phrase)   # This is the 
actual encryption
        value.file.write(val)
        value.file.seek(0, os.SEEK_SET)
        return (value, None)

Although as you can see, the files are already stored on disk prior to this 
method call.


We also have a method for downloading the files as follows:

def decrypt_download(request, db, key, chunk_size = DEFAULT_CHUNK_SIZE, 
attachment=True):
    """
    downloads from http://..../download/filename
    """
    import contenttype as c
    if not request.args:
        raise HTTP(404)
    name = request.args[-1]
    items = re.compile('(?P<table>.*?)\.(?P<field>.*?)\..*')\
                       .match(name)
    if not items:
        raise HTTP(404)
    (t, f) = (items.group('table'), items.group('field'))
    field = db[t][f]
    try:
        (filename, stream) = field.retrieve(name)
        # Decrypt stream here
        retfile = cStringIO.StringIO()
        val,error = decrypt_binary(stream.read(), key)
        stream.close()
        if error:
            # Decryption Error encountered 
            raise HTTP(500, error)
        retfile.write(str(val))
        retfile.seek(0, os.SEEK_SET)
    except IOError:
        logger.error(loghelper(auth, request)+'IO error encountered when 
decrypting download')
        raise HTTP(404)
    response.headers['Content-Type'] = c.contenttype(name)
    if attachment:
        response.headers['Content-Disposition'] = \
            "attachment; filename=%s" % filename
    logger.info(loghelper(auth, request)+'File downloaded')
    return response.stream(retfile, chunk_size = chunk_size, 
request=request)


Majority of the above is replication of web2py's 'file download' method.

There is probably a better way of doing this, but it seems to work well for 
us.

Hope this helps,

-- Richard


On Thursday, April 26, 2012 11:50:10 AM UTC-5, minhcd wrote:
>
> Edit: I want to temporarily store uploaded file in memory, *then* call 
> API to put this in-memory file to my Key/Value storage. When I put this 
> in-memory file (Value) to Key/Value storage, i will get back a *Key* from 
> it, and save this Key to RDBMS. When i want retrieve this "blob", i will 
> get this Key from RDBMS, then query Key/Value storage to get file(Value) 
> and streaming back to browser.
>
> On Thursday, April 26, 2012 11:41:18 PM UTC+7, minhcd wrote:
>>
>> Hi, I think your recipe will work ;)
>>
>> My situation is different a bit from Naveed. My database is RDBMS, but i 
>> want to store uploaded file in a Key/Value storage(NoSQL). How can I 
>> intervent to store/retrieve process? 
>> I want to temporarily store uploaded file in memory, *then* call API to 
>> put this in-memory file to my Key/Value storage. (and similar when have 
>> "retrieve" request)
>>
>> Could you have me figure it out pls? 
>> Thanks in advance!
>>
>> On Friday, April 13, 2012 8:22:02 PM UTC+7, Massimo Di Pierro wrote:
>>>
>>> I have not tried it but you can do
>>>
>>> class EncryptedField(Field):
>>>      def __init__(self,*a,**b):
>>>            self.password = b['password']
>>>            del b['password']
>>>            Field.__init__(self,*a,**b)
>>>      def store(self,file, filename=None, path=None):
>>>            newfile = encrypt(file,self.password)
>>>            return Field.store(self,file,filename,path)
>>>      def retrieve(self, name, path=None):
>>>            (filename, file) = Field.retrieve(self,name,path)
>>>            newfile = decrypt(file,self.password)
>>>            return (filename, newfile)
>>>
>>> the use
>>>
>>> db.define_table('person',Field('name'),EncryptedField('secret','upload',password='too
>>>  
>>> many secrets!'))
>>>
>>> On Thursday, 12 April 2012 16:35:36 UTC-5, naveed wrote:
>>>>
>>>>   I wasn’t asking as how to encrypt the file itself, but how to 
>>>> incorporate it in to web2py’s existing excellent form upload and download 
>>>> system. Assuming that we have functions encrypt(file, password) and 
>>>> decrypt(file, password) which return the encrypted and decrypted file 
>>>> respectively.
>>>>  
>>>>   
>>>>  *From:* Massimo Di Pierro <massimo.dipie...@gmail.com> 
>>>> *Sent:* Wednesday, April 11, 2012 13.31
>>>> *To:* web2py@googlegroups.com 
>>>> *Subject:* Re: [web2py] Re: web2py: encrypt uploaded files
>>>>  
>>>> Perhaps this can be useful: 
>>>>
>>>> http://stackoverflow.com/questions/6309958/encrypting-a-file-with-rsa-in-python
>>>> (look at code in first answer)
>>>>
>>>> On Wednesday, 11 April 2012 12:35:05 UTC-5, naveed wrote: 
>>>>>
>>>>>   Thanks Massimo for getting back. I can’t use an encrypted file 
>>>>> system as when the file system is mounted, it’s totally open. Every file 
>>>>> can be encrypted with the same master password. I’m thinking of storing 
>>>>> this master password which is itself encrypted using the user’s password 
>>>>> (or it’s hash) in the auth_user table.
>>>>>  
>>>>> On a related note, I am planning to encrypt some columns of other 
>>>>> tables using the same master password. Your thoughts on this approach?
>>>>>  
>>>>>   
>>>>>  *From:* Massimo Di Pierro <massimo.dipie...@gmail.com> 
>>>>> *Sent:* Wednesday, April 11, 2012 12.13
>>>>> *To:* web2py@googlegroups.com 
>>>>> *Subject:* [web2py] Re: web2py: encrypt uploaded files
>>>>>  
>>>>> What are the specs? Can you store them in an encrypted file system? 
>>>>> can you encrypt them with the same password? Should every file be 
>>>>> encrypted 
>>>>> with a different password? Where should the passwords be stored?
>>>>>
>>>>> On Wednesday, 11 April 2012 11:54:24 UTC-5, naveed wrote: 
>>>>>>
>>>>>> I need to encrypt uploaded files in web2py (for a HIPAA compliant 
>>>>>> application) preferably with AES. How can I accomplish this?
>>>>>>
>>>>>

Reply via email to