'Adds a membership to the image, or updates an existing one.
If a body is present, it is a dict with the following format
{\'member\': {
\'can_share\': [True|False]
If `can_share` is provided, the member\'s ability to share is
set accordingly.  If it is not provided, existing memberships
remain unchanged and new memberships default to False.'

@utils.mutating
def update(self, req, image_id, id, body=None):

    self._check_can_access_image_members(req.context)
    self._enforce(req, 'modify_member')
    self._raise_404_if_image_deleted(req, image_id)
    new_number_of_members = (len(registry.get_image_members(req.context, image_id)) + 1)
    self._enforce_image_member_quota(req, new_number_of_members)
    can_share = None
    if (body and ('member' in body) and ('can_share' in body['member'])):
        can_share = bool(body['member']['can_share'])
    try:
        registry.add_member(req.context, image_id, id, can_share)
        self._update_store_acls(req, image_id)
    except exception.Invalid as e:
        LOG.debug(encodeutils.exception_to_unicode(e))
        raise webob.exc.HTTPBadRequest(explanation=e.msg)
    except exception.NotFound as e:
        LOG.debug(encodeutils.exception_to_unicode(e))
        raise webob.exc.HTTPNotFound(explanation=e.msg)
    except exception.Forbidden as e:
        LOG.debug(encodeutils.exception_to_unicode(e))
        raise webob.exc.HTTPNotFound(explanation=e.msg)
    return webob.exc.HTTPNoContent()
