Skip to content

Commit

Permalink
Complete fix for modification of unowned image
Browse files Browse the repository at this point in the history
* Fully fixes bug 923941

Change-Id: Ia155a4d76e75498629996aaddfc8fe0b41ce6760
  • Loading branch information
bcwaldon committed Feb 27, 2012
1 parent d26f66b commit 7db2075
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 9 deletions.
6 changes: 6 additions & 0 deletions bin/glance
Expand Up @@ -380,6 +380,9 @@ to spell field names correctly. :)"""
except exception.NotFound:
print "No image with ID %s was found" % image_id
return FAILURE
except exception.NotAuthorized:
print "You do not have permission to update image %s" % image_id
return FAILURE
except Exception, e:
print "Failed to update image. Got error:"
pieces = unicode(e).split('\n')
Expand Down Expand Up @@ -420,6 +423,9 @@ Deletes an image from Glance"""
except exception.NotFound:
print "No image with ID %s was found" % image_id
return FAILURE
except exception.NotAuthorized:
print "You do not have permission to delete image %s" % image_id
return FAILURE


def image_show(options, args):
Expand Down
12 changes: 12 additions & 0 deletions glance/api/v1/images.py
Expand Up @@ -651,6 +651,12 @@ def update(self, req, id, image_meta, image_data):
logger.info(line)
self.notifier.info('image.update', msg)
raise HTTPNotFound(msg, request=req, content_type="text/plain")
except exception.NotAuthorized, e:
msg = ("Unable to update image: %(e)s" % locals())
for line in msg.split('\n'):
logger.info(line)
self.notifier.info('image.update', msg)
raise HTTPForbidden(msg, request=req, content_type="text/plain")
else:
self.notifier.info('image.update', image_meta)

Expand Down Expand Up @@ -701,6 +707,12 @@ def delete(self, req, id):
logger.info(line)
self.notifier.info('image.delete', msg)
raise HTTPNotFound(msg, request=req, content_type="text/plain")
except exception.NotAuthorized, e:
msg = ("Unable to delete image: %(e)s" % locals())
for line in msg.split('\n'):
logger.info(line)
self.notifier.info('image.delete', msg)
raise HTTPForbidden(msg, request=req, content_type="text/plain")
else:
self.notifier.info('image.delete', id)

Expand Down
11 changes: 7 additions & 4 deletions glance/registry/api/v1/images.py
Expand Up @@ -397,13 +397,16 @@ def update(self, req, id, body):
raise exc.HTTPNotFound(body='Image not found',
request=req,
content_type='text/plain')
except exception.NotAuthorizedPublicImage:
msg = _("Access by %(user)s to update public image %(id)s denied")
logger.info(msg % {'user': req.context.user, 'id': id})
raise exc.HTTPForbidden()

except exception.NotAuthorized:
# If it's private and doesn't belong to them, don't let on
# that it exists
msg = _("Access by %(user)s to image %(id)s "
"denied") % ({'user': req.context.user,
'id': id})
logger.info(msg)
msg = _("Access by %(user)s to update private image %(id)s denied")
logger.info(msg % {'user': req.context.user, 'id': id})
raise exc.HTTPNotFound(body='Image not found',
request=req,
content_type='text/plain')
Expand Down
2 changes: 1 addition & 1 deletion glance/tests/functional/test_bin_glance.py
Expand Up @@ -863,7 +863,7 @@ def test_protected_image(self):
exitcode, out, err = execute(cmd, raise_error=False)

self.assertNotEqual(0, exitcode)
self.assertTrue('Image is protected' in err)
self.assertTrue(out.startswith('You do not have permission'))

# 4. Remove image protection
cmd = "bin/glance --port=%d --force update %s" \
Expand Down
8 changes: 4 additions & 4 deletions glance/tests/functional/test_private_images.py
Expand Up @@ -256,12 +256,12 @@ def test_private_images_notadmin(self):

# Froggy still can't change is-public
headers = {'X-Auth-Token': keystone_utils.froggy_token,
'X-Image-Meta-Is-Public': 'True'}
'X-Image-Meta-Is-Public': 'False'}
path = "http://%s:%d/v1/images/%s" % ("0.0.0.0", self.api_port,
image_id)
http = httplib2.Http()
response, content = http.request(path, 'PUT', headers=headers)
self.assertEqual(response.status, 404)
self.assertEqual(response.status, 403)

# Or give themselves ownership
headers = {'X-Auth-Token': keystone_utils.froggy_token,
Expand All @@ -270,15 +270,15 @@ def test_private_images_notadmin(self):
image_id)
http = httplib2.Http()
response, content = http.request(path, 'PUT', headers=headers)
self.assertEqual(response.status, 404)
self.assertEqual(response.status, 403)

# Froggy can't delete it, either
headers = {'X-Auth-Token': keystone_utils.froggy_token}
path = "http://%s:%d/v1/images/%s" % ("0.0.0.0", self.api_port,
image_id)
http = httplib2.Http()
response, content = http.request(path, 'DELETE', headers=headers)
self.assertEqual(response.status, 404)
self.assertEqual(response.status, 403)

# But pattieblack can
headers = {'X-Auth-Token': keystone_utils.pattieblack_token}
Expand Down

0 comments on commit 7db2075

Please sign in to comment.