Skip to content

Commit 7fc1721

Browse files
committed
TempURL and FormPost Middleware
Change-Id: I8d2ce2abdfe3a44605c9441ad7b1abc6c77e282d
1 parent 338be6a commit 7fc1721

File tree

11 files changed

+3359
-16
lines changed

11 files changed

+3359
-16
lines changed

Diff for: bin/swift-form-signature

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/env python
2+
3+
import hmac
4+
from hashlib import sha1
5+
from os.path import basename
6+
from sys import argv, exit
7+
from time import time
8+
9+
10+
if __name__ == '__main__':
11+
if len(argv) != 7:
12+
prog = basename(argv[0])
13+
print 'Syntax: %s <path> <redirect> <max_file_size> ' \
14+
'<max_file_count> <seconds> <key>' % prog
15+
print
16+
print 'Where:'
17+
print ' <path> The prefix to use for form uploaded'
18+
print ' objects. For example:'
19+
print ' /v1/account/container/object_prefix_ would'
20+
print ' ensure all form uploads have that path'
21+
print ' prepended to the browser-given file name.'
22+
print ' <redirect> The URL to redirect the browser to after'
23+
print ' the uploads have completed.'
24+
print ' <max_file_size> The maximum file size per file uploaded.'
25+
print ' <max_file_count> The maximum number of uploaded files'
26+
print ' allowed.'
27+
print ' <seconds> The number of seconds from now to allow'
28+
print ' the form post to begin.'
29+
print ' <key> The X-Account-Meta-Temp-URL-Key for the'
30+
print ' account.'
31+
print
32+
print 'Example output:'
33+
print ' Expires: 1323842228'
34+
print ' Signature: 18de97e47345a82c4dbfb3b06a640dbb'
35+
exit(1)
36+
path, redirect, max_file_size, max_file_count, seconds, key = argv[1:]
37+
try:
38+
max_file_size = int(max_file_size)
39+
except ValueError:
40+
max_file_size = -1
41+
if max_file_size < 0:
42+
print 'Please use a <max_file_size> value greater than or equal to 0.'
43+
exit(1)
44+
try:
45+
max_file_count = int(max_file_count)
46+
except ValueError:
47+
max_file_count = 0
48+
if max_file_count < 1:
49+
print 'Please use a positive <max_file_count> value.'
50+
exit(1)
51+
try:
52+
expires = int(time() + int(seconds))
53+
except ValueError:
54+
expires = 0
55+
if expires < 1:
56+
print 'Please use a positive <seconds> value.'
57+
exit(1)
58+
parts = path.split('/', 4)
59+
# Must be four parts, ['', 'v1', 'a', 'c'], must be a v1 request, have
60+
# account and container values, and optionally have an object prefix.
61+
if len(parts) < 4 or parts[0] or parts[1] != 'v1' or not parts[2] or \
62+
not parts[3]:
63+
print '<path> must point to a container at least.'
64+
print 'For example: /v1/account/container'
65+
print ' Or: /v1/account/container/object_prefix'
66+
exit(1)
67+
sig = hmac.new(key, '%s\n%s\n%s\n%s\n%s' % (path, redirect, max_file_size,
68+
max_file_count, expires), sha1).hexdigest()
69+
print ' Expires:', expires
70+
print 'Signature:', sig

Diff for: bin/swift-temp-url

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#!/usr/bin/env python
2+
3+
import hmac
4+
from hashlib import sha1
5+
from os.path import basename
6+
from sys import argv, exit
7+
from time import time
8+
9+
10+
if __name__ == '__main__':
11+
if len(argv) != 5:
12+
prog = basename(argv[0])
13+
print 'Syntax: %s <method> <seconds> <path> <key>' % prog
14+
print
15+
print 'Where:'
16+
print ' <method> The method to allow, GET or PUT.'
17+
print ' Note: HEAD will also be allowed.'
18+
print ' <seconds> The number of seconds from now to allow requests.'
19+
print ' <path> The full path to the resource.'
20+
print ' Example: /v1/AUTH_account/c/o'
21+
print ' <key> The X-Account-Meta-Temp-URL-Key for the account.'
22+
print
23+
print 'Example output:'
24+
print ' /v1/AUTH_account/c/o?temp_url_sig=34d49efc32fe6e3082e411e' \
25+
'eeb85bd8a&temp_url_expires=1323482948'
26+
print
27+
print 'This can be used to form a URL to give out for the access '
28+
print 'allowed. For example:'
29+
print ' echo https://swift-cluster.example.com`%s GET 60 ' \
30+
'/v1/AUTH_account/c/o mykey`' % prog
31+
print
32+
print 'Might output:'
33+
print ' https://swift-cluster.example.com/v1/AUTH_account/c/o?' \
34+
'temp_url_sig=34d49efc32fe6e3082e411eeeb85bd8a&' \
35+
'temp_url_expires=1323482948'
36+
exit(1)
37+
method, seconds, path, key = argv[1:]
38+
if method not in ('GET', 'PUT'):
39+
print 'Please use either the GET or PUT method.'
40+
exit(1)
41+
try:
42+
expires = int(time() + int(seconds))
43+
except ValueError:
44+
expires = 0
45+
if expires < 1:
46+
print 'Please use a positive <seconds> value.'
47+
exit(1)
48+
parts = path.split('/', 4)
49+
# Must be five parts, ['', 'v1', 'a', 'c', 'o'], must be a v1 request, have
50+
# account, container, and object values, and the object value can't just
51+
# have '/'s.
52+
if len(parts) != 5 or parts[0] or parts[1] != 'v1' or not parts[2] or \
53+
not parts[3] or not parts[4].strip('/'):
54+
print '<path> must point to an object.'
55+
print 'For example: /v1/account/container/object'
56+
exit(1)
57+
sig = hmac.new(key, '%s\n%s\n%s' % (method, expires, path),
58+
sha1).hexdigest()
59+
print '%s?temp_url_sig=%s&temp_url_expires=%s' % (path, sig, expires)

Diff for: doc/source/misc.rst

+14
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,17 @@ StaticWeb
143143
.. automodule:: swift.common.middleware.staticweb
144144
:members:
145145
:show-inheritance:
146+
147+
TempURL
148+
=======
149+
150+
.. automodule:: swift.common.middleware.tempurl
151+
:members:
152+
:show-inheritance:
153+
154+
FormPost
155+
========
156+
157+
.. automodule:: swift.common.middleware.formpost
158+
:members:
159+
:show-inheritance:

Diff for: etc/proxy-server.conf-sample

+35
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ use = egg:swift#tempauth
6969
# This is a comma separated list of hosts allowed to send X-Container-Sync-Key
7070
# requests.
7171
# allowed_sync_hosts = 127.0.0.1
72+
# This allows middleware higher in the WSGI pipeline to override auth
73+
# processing, useful for middleware such as tempurl and formpost. If you know
74+
# you're not going to use such middleware and you want a bit of extra security,
75+
# you can set this to false.
76+
# allow_overrides = true
7277
# Lastly, you need to list all the accounts/users you want here. The format is:
7378
# user_<account>_<user> = <key> [group] [group] [...] [storage_url]
7479
# There are special groups of:
@@ -185,3 +190,33 @@ use = egg:swift#staticweb
185190
# set access_log_facility = LOG_LOCAL0
186191
# set access_log_level = INFO
187192
# set log_headers = False
193+
194+
# Note: Put tempurl just before your auth filter(s) in the pipeline
195+
[filter:tempurl]
196+
use = egg:swift#tempurl
197+
#
198+
# The headers to remove from incoming requests. Simply a whitespace delimited
199+
# list of header names and names can optionally end with '*' to indicate a
200+
# prefix match. incoming_allow_headers is a list of exceptions to these
201+
# removals.
202+
# incoming_remove_headers = x-timestamp
203+
#
204+
# The headers allowed as exceptions to incoming_remove_headers. Simply a
205+
# whitespace delimited list of header names and names can optionally end with
206+
# '*' to indicate a prefix match.
207+
# incoming_allow_headers =
208+
#
209+
# The headers to remove from outgoing responses. Simply a whitespace delimited
210+
# list of header names and names can optionally end with '*' to indicate a
211+
# prefix match. outgoing_allow_headers is a list of exceptions to these
212+
# removals.
213+
# outgoing_remove_headers = x-object-meta-*
214+
#
215+
# The headers allowed as exceptions to outgoing_remove_headers. Simply a
216+
# whitespace delimited list of header names and names can optionally end with
217+
# '*' to indicate a prefix match.
218+
# outgoing_allow_headers = x-object-meta-public-*
219+
220+
# Note: Put formpost just before your auth filter(s) in the pipeline
221+
[filter:formpost]
222+
use = egg:swift#formpost

Diff for: setup.py

+32-15
Original file line numberDiff line numberDiff line change
@@ -41,25 +41,40 @@
4141
],
4242
install_requires=[], # removed for better compat
4343
scripts=[
44-
'bin/swift', 'bin/swift-account-auditor',
45-
'bin/swift-account-audit', 'bin/swift-account-reaper',
46-
'bin/swift-account-replicator', 'bin/swift-account-server',
44+
'bin/swift',
45+
'bin/swift-account-audit',
46+
'bin/swift-account-auditor',
47+
'bin/swift-account-reaper',
48+
'bin/swift-account-replicator',
49+
'bin/swift-account-server',
50+
'bin/swift-bench',
4751
'bin/swift-container-auditor',
48-
'bin/swift-container-replicator', 'bin/swift-container-sync',
49-
'bin/swift-container-server', 'bin/swift-container-updater',
50-
'bin/swift-drive-audit', 'bin/swift-get-nodes',
51-
'bin/swift-init', 'bin/swift-object-auditor',
52-
'bin/swift-object-expirer', 'bin/swift-object-info',
52+
'bin/swift-container-replicator',
53+
'bin/swift-container-server',
54+
'bin/swift-container-sync',
55+
'bin/swift-container-updater',
56+
'bin/swift-dispersion-populate',
57+
'bin/swift-dispersion-report',
58+
'bin/swift-drive-audit',
59+
'bin/swift-form-signature',
60+
'bin/swift-get-nodes',
61+
'bin/swift-init',
62+
'bin/swift-object-auditor',
63+
'bin/swift-object-expirer',
64+
'bin/swift-object-info',
5365
'bin/swift-object-replicator',
5466
'bin/swift-object-server',
55-
'bin/swift-object-updater', 'bin/swift-proxy-server',
56-
'bin/swift-ring-builder', 'bin/swift-stats-populate',
67+
'bin/swift-object-updater',
68+
'bin/swift-oldies',
69+
'bin/swift-orphans',
70+
'bin/swift-proxy-server',
71+
'bin/swift-recon',
72+
'bin/swift-recon-cron',
73+
'bin/swift-ring-builder',
74+
'bin/swift-stats-populate',
5775
'bin/swift-stats-report',
58-
'bin/swift-dispersion-populate', 'bin/swift-dispersion-report',
59-
'bin/swift-bench',
60-
'bin/swift-recon', 'bin/swift-recon-cron', 'bin/swift-orphans',
61-
'bin/swift-oldies'
62-
],
76+
'bin/swift-temp-url',
77+
],
6378
entry_points={
6479
'paste.app_factory': [
6580
'proxy=swift.proxy.server:app_factory',
@@ -78,6 +93,8 @@
7893
'staticweb=swift.common.middleware.staticweb:filter_factory',
7994
'tempauth=swift.common.middleware.tempauth:filter_factory',
8095
'recon=swift.common.middleware.recon:filter_factory',
96+
'tempurl=swift.common.middleware.tempurl:filter_factory',
97+
'formpost=swift.common.middleware.formpost:filter_factory',
8198
],
8299
},
83100
)

0 commit comments

Comments
 (0)