'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)
    try:
        image = self.db_api.image_get(req.context, image_id, v1_mode=True)
    except exception.NotFound:
        msg = (_('Image    %(id)s    not    found') % {'id': image_id})
        LOG.warn(msg)
        raise webob.exc.HTTPNotFound(msg)
    except exception.Forbidden:
        msg = (_LW("Access    denied    to    image    %(id)s    but    returning    'not    found'") % {'id': image_id})
        LOG.warn(msg)
        raise webob.exc.HTTPNotFound()
    if (not self.is_image_sharable(req.context, image)):
        msg = (_LW('User    lacks    permission    to    share    image    %(id)s') % {'id': image_id})
        LOG.warn(msg)
        msg = _('No    permission    to    share    that    image')
        raise webob.exc.HTTPForbidden(msg)
    can_share = None
    if body:
        try:
            can_share = bool(body['member']['can_share'])
        except Exception as e:
            msg = (_LW('Invalid    membership    association    specified    for    image    %(id)s') % {'id': image_id})
            LOG.warn(msg)
            msg = (_('Invalid    membership    association:    %s') % encodeutils.exception_to_unicode(e))
            raise webob.exc.HTTPBadRequest(explanation=msg)
    members = self.db_api.image_member_find(req.context, image_id=image_id, member=id, include_deleted=True)
    if members:
        if (can_share is not None):
            values = dict(can_share=can_share)
            self.db_api.image_member_update(req.context, members[0]['id'], values)
    else:
        values = dict(image_id=image['id'], member=id, can_share=bool(can_share))
        self.db_api.image_member_create(req.context, values)
    LOG.info(_LI('Successfully    updated    a    membership    for    image    %(id)s'), {'id': image_id})
    return webob.exc.HTTPNoContent()
