@gen.coroutine
def UnlinkIdentity(client, obj_store, user_id, device_id, request):
  """Unlink an existing identity from the requesting account."""
  # Validate identity key.
  Identity.ValidateKey(request['identity'])

  unlink_ident = yield gen.Task(Identity.Query, client, request['identity'], None, must_exist=False)

  # If the identity is missing, then assume unlink is being re-called, and do a no-op. If the
  # user_id does not match, raise a permission error. Otherwise, if request is for an authorized
  # id, we must query to ensure this won't be last one remaining.
  if unlink_ident is not None:
    if unlink_ident.user_id != user_id:
      raise PermissionError('Identity "%s" not linked to this account' % request['identity'])

    if unlink_ident.authority is not None:
      query_expr = 'identity.user_id=%d' % user_id
      all_identities = yield gen.Task(Identity.IndexQuery, client, query_expr, ['key', 'authority'])

      # Verify there is at least one identity remaining with an authority.
      if not any([one_identity.authority is not None and one_identity.key != unlink_ident.key
                  for one_identity in all_identities]):
        raise PermissionError('Removing this identity authorized by %s, would leave you '
                              'with no way to access your account' % unlink_ident.authority)

    request['user_id'] = user_id
    yield gen.Task(Operation.CreateAndExecute,
                   client,
                   user_id,
                   device_id,
                   'Identity.UnlinkIdentityOperation',
                   request)

  logging.info('IDENTITY UNLINK: user: %d, device: %d, identity: %s' %
               (user_id, device_id, request['identity']))
  raise gen.Return({})
dataset/ETHPy150Open viewfinderco/viewfinder/backend/www/service.py/UnlinkIdentity/original