~cloudbuilders/nova/os-keypair-integration

« back to all changes in this revision

Viewing changes to nova/api/ec2/__init__.py

  • Committer: Jesse Andrews
  • Date: 2011-08-26 21:57:53 UTC
  • mfrom: (1455.1.45 nova)
  • Revision ID: anotherjesse@gmail.com-20110826215753-0sfp6dubujsl23wa
merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 
21
21
"""
22
22
 
 
23
import httplib2
23
24
import webob
24
25
import webob.dec
25
26
import webob.exc
37
38
 
38
39
FLAGS = flags.FLAGS
39
40
LOG = logging.getLogger("nova.api")
40
 
flags.DEFINE_boolean('use_forwarded_for', False,
41
 
                     'Treat X-Forwarded-For as the canonical remote address. '
42
 
                     'Only enable this if you have a sanitizing proxy.')
43
41
flags.DEFINE_integer('lockout_attempts', 5,
44
42
                     'Number of failed auths before lockout.')
45
43
flags.DEFINE_integer('lockout_minutes', 15,
46
44
                     'Number of minutes to lockout if triggered.')
47
45
flags.DEFINE_integer('lockout_window', 15,
48
46
                     'Number of minutes for lockout window.')
 
47
flags.DEFINE_string('keystone_ec2_url',
 
48
                    'http://localhost:5000/v2.0/ec2tokens',
 
49
                    'URL to get token from ec2 request.')
 
50
flags.DECLARE('use_forwarded_for', 'nova.api.auth')
49
51
 
50
52
 
51
53
class RequestLogging(wsgi.Middleware):
138
140
        return res
139
141
 
140
142
 
 
143
class ToToken(wsgi.Middleware):
 
144
    """Authenticate an EC2 request with keystone and convert to token."""
 
145
 
 
146
    @webob.dec.wsgify(RequestClass=wsgi.Request)
 
147
    def __call__(self, req):
 
148
        # Read request signature and access id.
 
149
        try:
 
150
            signature = req.params['Signature']
 
151
            access = req.params['AWSAccessKeyId']
 
152
        except KeyError:
 
153
            raise webob.exc.HTTPBadRequest()
 
154
 
 
155
        # Make a copy of args for authentication and signature verification.
 
156
        auth_params = dict(req.params)
 
157
        # Not part of authentication args
 
158
        auth_params.pop('Signature')
 
159
 
 
160
        # Authenticate the request.
 
161
        client = httplib2.Http()
 
162
        creds = {'ec2Credentials': {'access': access,
 
163
                                    'signature': signature,
 
164
                                    'host': req.host,
 
165
                                    'verb': req.method,
 
166
                                    'path': req.path,
 
167
                                    'params': auth_params,
 
168
                                   }}
 
169
        headers = {'Content-Type': 'application/json'},
 
170
        resp, content = client.request(FLAGS.keystone_ec2_url,
 
171
                                       'POST',
 
172
                                       headers=headers,
 
173
                                       body=utils.dumps(creds))
 
174
        # NOTE(vish): We could save a call to keystone by
 
175
        #             having keystone return token, tenant,
 
176
        #             user, and roles from this call.
 
177
        result = utils.loads(content)
 
178
        # TODO(vish): check for errors
 
179
        token_id = result['auth']['token']['id']
 
180
 
 
181
        # Authenticated!
 
182
        req.headers['X-Auth-Token'] = token_id
 
183
        return self.application
 
184
 
 
185
 
 
186
class NoAuth(wsgi.Middleware):
 
187
    """Add user:project as 'nova.context' to WSGI environ."""
 
188
 
 
189
    @webob.dec.wsgify(RequestClass=wsgi.Request)
 
190
    def __call__(self, req):
 
191
        if 'AWSAccessKeyId' not in req.params:
 
192
            raise webob.exc.HTTPBadRequest()
 
193
        user_id, _sep, project_id = req.params['AWSAccessKeyId'].partition(':')
 
194
        project_id = project_id or user_id
 
195
        remote_address = getattr(req, 'remote_address', '127.0.0.1')
 
196
        if FLAGS.use_forwarded_for:
 
197
            remote_address = req.headers.get('X-Forwarded-For', remote_address)
 
198
        ctx = context.RequestContext(user_id,
 
199
                                     project_id,
 
200
                                     is_admin=True,
 
201
                                     remote_address=remote_address)
 
202
 
 
203
        req.environ['nova.context'] = ctx
 
204
        return self.application
 
205
 
 
206
 
141
207
class Authenticate(wsgi.Middleware):
142
208
    """Authenticate an EC2 request and add 'nova.context' to WSGI environ."""
143
209
 
147
213
        try:
148
214
            signature = req.params['Signature']
149
215
            access = req.params['AWSAccessKeyId']
150
 
        except KeyError, e:
 
216
        except KeyError:
151
217
            raise webob.exc.HTTPBadRequest()
152
218
 
153
219
        # Make a copy of args for authentication and signature verification.