david / django-storages
Support for many storages (S3, MogileFS, etc) in Django.
Clone this repository (size: 177.1 KB): HTTPS / SSH
$ hg clone http://code.welldev.org/django-storages
| commit 66: | 41cc5987a7fb |
| parent 61: | 7683dd9e9f35 |
| branch: | default |
S3: Add encryption option, depends on ezPyCrypto lib from http://www.freenet.org.nz/ezPyCrypto/, thanks @erikcw
6 months ago
Changed (Δ1.2 KB):
raw changeset »
AUTHORS (1 lines added, 0 lines removed)
backends/s3.py (39 lines added, 1 lines removed)
| … | … | @@ -14,6 +14,7 @@ By order of apparition, thanks: |
14 |
14 |
* Rich Leland (Mosso Cloud Files) |
15 |
15 |
* Jason Christa (patches) |
16 |
16 |
* Adam Nelson (patches) |
17 |
* Erik CW (S3 encryption) |
|
17 |
18 |
|
18 |
19 |
Extra thanks to Marty for adding this in Django, |
19 |
20 |
you can buy his very interesting book (Pro Django). |
Up to file-list backends/s3.py:
| … | … | @@ -33,9 +33,18 @@ class S3Storage(Storage): |
33 |
33 |
|
34 |
34 |
def __init__(self, bucket=settings.AWS_STORAGE_BUCKET_NAME, |
35 |
35 |
access_key=None, secret_key=None, acl=DEFAULT_ACL, |
36 |
calling_format=settings.AWS_CALLING_FORMAT |
|
36 |
calling_format=settings.AWS_CALLING_FORMAT, encrypt=False): |
|
37 |
37 |
self.bucket = bucket |
38 |
38 |
self.acl = acl |
39 |
self.encrypt = encrypt |
|
40 |
||
41 |
if encrypt: |
|
42 |
try: |
|
43 |
import ezPyCrypto |
|
44 |
except ImportError: |
|
45 |
raise ImproperlyConfigured, "Could not load ezPyCrypto.\ |
|
46 |
\nSee http://www.freenet.org.nz/ezPyCrypto/ to install it." |
|
47 |
self.crypto_key = ezPyCrypto.key |
|
39 |
48 |
|
40 |
49 |
if not access_key and not secret_key: |
41 |
50 |
access_key, secret_key = self._get_access_keys() |
| … | … | @@ -70,6 +79,22 @@ class S3Storage(Storage): |
70 |
79 |
return os.path.normpath(name).replace('\\', '/') |
71 |
80 |
|
72 |
81 |
def _put_file(self, name, content): |
82 |
if self.encrypt: |
|
83 |
||
84 |
# Create a key object |
|
85 |
key = self.crypto_key() |
|
86 |
||
87 |
# Read in a public key |
|
88 |
fd = open(settings.CRYPTO_KEYS_PUBLIC, "rb") |
|
89 |
public_key = fd.read() |
|
90 |
fd.close() |
|
91 |
||
92 |
# import this public key |
|
93 |
key.importKey(public_key) |
|
94 |
||
95 |
# Now encrypt some text against this public key |
|
96 |
content = key.encString(content) |
|
97 |
||
73 |
98 |
content_type = mimetypes.guess_type(name)[0] or "application/x-octet-stream" |
74 |
99 |
self.headers.update({ |
75 |
100 |
'x-amz-acl': self.acl, |
| … | … | @@ -95,6 +120,19 @@ class S3Storage(Storage): |
95 |
120 |
if response.http_response.status not in (200, 206): |
96 |
121 |
raise IOError("S3StorageError: %s" % response.message) |
97 |
122 |
headers = response.http_response.msg |
123 |
||
124 |
if self.encrypt: |
|
125 |
# Read in a private key |
|
126 |
fd = open(settings.CRYPTO_KEYS_PRIVATE, "rb") |
|
127 |
private_key = fd.read() |
|
128 |
fd.close() |
|
129 |
||
130 |
# Create a key object, and auto-import private key |
|
131 |
key = self.crypto_key(private_key) |
|
132 |
||
133 |
# Decrypt this file |
|
134 |
response.object.data = key.decString(response.object.data) |
|
135 |
||
98 |
136 |
return response.object.data, headers.get('etag', None), headers.get('content-range', None) |
99 |
137 |
|
100 |
138 |
def _save(self, name, content): |
