~rlane/nova/lp773690

« back to all changes in this revision

Viewing changes to nova/auth/manager.py

  • Committer: rlane at wikimedia
  • Date: 2011-04-29 22:30:40 UTC
  • mfrom: (382.1.655 nova)
  • Revision ID: rlane@wikimedia.org-20110429223040-i0x3ds9eqwrabyru
MergeĀ fromĀ trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
223
223
        if driver or not getattr(self, 'driver', None):
224
224
            self.driver = utils.import_class(driver or FLAGS.auth_driver)
225
225
 
 
226
        if FLAGS.memcached_servers:
 
227
            import memcache
 
228
        else:
 
229
            from nova import fakememcache as memcache
 
230
        self.mc = memcache.Client(FLAGS.memcached_servers,
 
231
                                  debug=0)
 
232
 
226
233
    def authenticate(self, access, signature, params, verb='GET',
227
234
                     server_string='127.0.0.1:8773', path='/',
228
235
                     check_type='ec2', headers=None):
268
275
        LOG.debug(_('Looking up user: %r'), access_key)
269
276
        user = self.get_user_from_access_key(access_key)
270
277
        LOG.debug('user: %r', user)
271
 
        if user == None:
 
278
        if user is None:
272
279
            LOG.audit(_("Failed authorization for access key %s"), access_key)
273
 
            raise exception.NotFound(_('No user found for access key %s')
274
 
                                     % access_key)
 
280
            raise exception.AccessKeyNotFound(access_key=access_key)
275
281
 
276
282
        # NOTE(vish): if we stop using project name as id we need better
277
283
        #             logic to find a default project for user
280
286
            project_id = user.name
281
287
 
282
288
        project = self.get_project(project_id)
283
 
        if project == None:
 
289
        if project is None:
284
290
            pjid = project_id
285
291
            uname = user.name
286
292
            LOG.audit(_("failed authorization: no project named %(pjid)s"
287
293
                    " (user=%(uname)s)") % locals())
288
 
            raise exception.NotFound(_('No project called %s could be found')
289
 
                                     % project_id)
 
294
            raise exception.ProjectNotFound(project_id=project_id)
290
295
        if not self.is_admin(user) and not self.is_project_member(user,
291
296
                                                                  project):
292
297
            uname = user.name
295
300
            pjid = project.id
296
301
            LOG.audit(_("Failed authorization: user %(uname)s not admin"
297
302
                    " and not member of project %(pjname)s") % locals())
298
 
            raise exception.NotFound(_('User %(uid)s is not a member of'
299
 
                    ' project %(pjid)s') % locals())
 
303
            raise exception.ProjectMembershipNotFound(project_id=pjid,
 
304
                                                      user_id=uid)
300
305
        if check_type == 's3':
301
306
            sign = signer.Signer(user.secret.encode())
302
307
            expected_signature = sign.s3_authorization(headers, verb, path)
360
365
            if self.has_role(user, role):
361
366
                return True
362
367
 
 
368
    def _build_mc_key(self, user, role, project=None):
 
369
        key_parts = ['rolecache', User.safe_id(user), str(role)]
 
370
        if project:
 
371
            key_parts.append(Project.safe_id(project))
 
372
        return '-'.join(key_parts)
 
373
 
 
374
    def _clear_mc_key(self, user, role, project=None):
 
375
        # NOTE(anthony): it would be better to delete the key
 
376
        self.mc.set(self._build_mc_key(user, role, project), None)
 
377
 
 
378
    def _has_role(self, user, role, project=None):
 
379
        mc_key = self._build_mc_key(user, role, project)
 
380
        rslt = self.mc.get(mc_key)
 
381
        if rslt is None:
 
382
            with self.driver() as drv:
 
383
                rslt = drv.has_role(user, role, project)
 
384
                self.mc.set(mc_key, rslt)
 
385
                return rslt
 
386
        else:
 
387
            return rslt
 
388
 
363
389
    def has_role(self, user, role, project=None):
364
390
        """Checks existence of role for user
365
391
 
383
409
        @rtype: bool
384
410
        @return: True if the user has the role.
385
411
        """
386
 
        with self.driver() as drv:
387
 
            if role == 'projectmanager':
388
 
                if not project:
389
 
                    raise exception.Error(_("Must specify project"))
390
 
                return self.is_project_manager(user, project)
391
 
 
392
 
            global_role = drv.has_role(User.safe_id(user),
393
 
                                        role,
394
 
                                        None)
395
 
            if not global_role:
396
 
                return global_role
397
 
 
398
 
            if not project or role in FLAGS.global_roles:
399
 
                return global_role
400
 
 
401
 
            return drv.has_role(User.safe_id(user),
402
 
                                 role,
403
 
                                 Project.safe_id(project))
 
412
        if role == 'projectmanager':
 
413
            if not project:
 
414
                raise exception.Error(_("Must specify project"))
 
415
            return self.is_project_manager(user, project)
 
416
 
 
417
        global_role = self._has_role(User.safe_id(user),
 
418
                                     role,
 
419
                                     None)
 
420
 
 
421
        if not global_role:
 
422
            return global_role
 
423
 
 
424
        if not project or role in FLAGS.global_roles:
 
425
            return global_role
 
426
 
 
427
        return self._has_role(User.safe_id(user),
 
428
                              role,
 
429
                              Project.safe_id(project))
404
430
 
405
431
    def add_role(self, user, role, project=None):
406
432
        """Adds role for user
420
446
        @param project: Project in which to add local role.
421
447
        """
422
448
        if role not in FLAGS.allowed_roles:
423
 
            raise exception.NotFound(_("The %s role can not be found") % role)
 
449
            raise exception.UserRoleNotFound(role_id=role)
424
450
        if project is not None and role in FLAGS.global_roles:
425
 
            raise exception.NotFound(_("The %s role is global only") % role)
 
451
            raise exception.GlobalRoleNotAllowed(role_id=role)
426
452
        uid = User.safe_id(user)
427
453
        pid = Project.safe_id(project)
428
454
        if project:
432
458
            LOG.audit(_("Adding sitewide role %(role)s to user %(uid)s")
433
459
                    % locals())
434
460
        with self.driver() as drv:
 
461
            self._clear_mc_key(uid, role, pid)
435
462
            drv.add_role(uid, role, pid)
436
463
 
437
464
    def remove_role(self, user, role, project=None):
460
487
            LOG.audit(_("Removing sitewide role %(role)s"
461
488
                    " from user %(uid)s") % locals())
462
489
        with self.driver() as drv:
 
490
            self._clear_mc_key(uid, role, pid)
463
491
            drv.remove_role(uid, role, pid)
464
492
 
465
493
    @staticmethod
646
674
        @rtype: User
647
675
        @return: The new user.
648
676
        """
649
 
        if access == None:
 
677
        if access is None:
650
678
            access = str(uuid.uuid4())
651
 
        if secret == None:
 
679
        if secret is None:
652
680
            secret = str(uuid.uuid4())
653
681
        with self.driver() as drv:
654
682
            user_dict = drv.create_user(name, access, secret, admin)