# Copyright 2017 Canonical Ltd.
# Licensed under the LGPLv3, see LICENCE file for details.
import abc
from collections import namedtuple
WEB_BROWSER_INTERACTION_KIND = 'browser-window'
class Interactor(object):
''' Represents a way of persuading a discharger that it should grant a
discharge macaroon.
'''
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def kind(self):
'''Returns the interaction method name. This corresponds to the key in
the Error.interaction_methods type.
@return {str}
'''
raise NotImplementedError('kind method must be defined in subclass')
def interact(self, client, location, interaction_required_err):
''' Performs the interaction, and returns a token that can be
used to acquire the discharge macaroon. The location provides
the third party caveat location to make it possible to use
relative URLs. The client holds the client being used to do the current
request.
If the given interaction isn't supported by the client for
the given location, it may raise an InteractionMethodNotFound
which will cause the interactor to be ignored that time.
@param client The client being used for the current request {Client}
@param location Third party caveat location {str}
@param interaction_required_err The error causing the interaction to
take place {Error}
@return {DischargeToken} The discharge token.
'''
raise NotImplementedError('interact method must be defined in subclass')
class LegacyInteractor(object):
''' May optionally be implemented by Interactor implementations that
implement the legacy interaction-required error protocols.
'''
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def legacy_interact(self, client, location, visit_url):
''' Implements the "visit" half of a legacy discharge
interaction. The "wait" half will be implemented by httpbakery.
The location is the location specified by the third party
caveat. The client holds the client being used to do the current
request.
@param client The client being used for the current request {Client}
@param location Third party caveat location {str}
@param visit_url The visit_url field from the error {str}
@return None
'''
raise NotImplementedError('legacy_interact method must be defined in subclass')
class DischargeToken(namedtuple('DischargeToken', 'kind, value')):
''' Holds a token that is intended to persuade a discharger to discharge
a third party caveat.
@param kind holds the kind of the token. By convention this
matches the name of the interaction method used to
obtain the token, but that's not required {str}
@param value holds the token data. {bytes}
'''