'Invalidate access/refresh tokens belonging to a user
Args:
user_id (str):  ID of user the tokens belong to
except_token_id (str): list of access_tokens IDs which should
*not* be deleted
device_id (str|None):  ID of device the tokens are associated with.
If None, tokens associated with any device (or no device) will
be deleted
delete_refresh_tokens (bool):  True to delete refresh tokens as
well as access tokens.
Returns:
defer.Deferred:'

@defer.inlineCallbacks
def user_delete_access_tokens(self, user_id, except_token_id=None, device_id=None, delete_refresh_tokens=False):

    def f(txn):
        keyvalues = {'user_id': user_id}
        if (device_id is not None):
            keyvalues['device_id'] = device_id
        if delete_refresh_tokens:
            self._simple_delete_txn(txn, table='refresh_tokens', keyvalues=keyvalues)
        items = keyvalues.items()
        where_clause = '    AND    '.join(((k + '    =    ?') for (k, _) in items))
        values = [v for (_, v) in items]
        if except_token_id:
            where_clause += '    AND    id    !=    ?'
            values.append(except_token_id)
        txn.execute(('SELECT    token    FROM    access_tokens    WHERE    %s' % where_clause), values)
        rows = self.cursor_to_dict(txn)
        for row in rows:
            self._invalidate_cache_and_stream(txn, self.get_user_by_access_token, (row['token'],))
        txn.execute(('DELETE    FROM    access_tokens    WHERE    %s' % where_clause), values)
    (yield self.runInteraction('user_delete_access_tokens', f))
