Ejemplo n.º 1
0
    def _resolved_entry_phase_affordancesets(self, phase, affordances):

        upstream_affordancesets = _set()
        downstream_affordances = affordances.unfrozen_copy()
        downstream_affordances.inputs = '*'
        downstream_affordances.outputs = '*'
        for resolved_input_affordances \
                in self._resolved_phase_input_affordancesets\
                    (phase, 'upstream',
                     reverse_affordances=downstream_affordances):
            upstream_affordances = resolved_input_affordances.unfrozen()
            upstream_affordances.inputs = '*'
            upstream_affordances.outputs = affordances.outputs
            upstream_affordancesets.add(upstream_affordances.frozen())

        self.logger.cond((_logging.DEBUG,
                          lambda: 'resolved upstream affordance sets {}'
                                   .format(upstream_affordancesets)))

        downstream_affordancesets = \
            _frozenset(_chain(*[self._resolved_phase_output_affordancesets
                                 (phase, 'downstream',
                                  reverse_affordances=upstream_affordances)
                                for upstream_affordances
                                in upstream_affordancesets]))

        self.logger.cond((_logging.DEBUG,
                          lambda: 'resolved downstream affordance sets {}'
                                   .format(downstream_affordancesets)))

        return downstream_affordancesets
Ejemplo n.º 2
0
    def _resolved_phase_output_affordancesets(self, phase, direction,
                                              reverse_affordances):

        if direction == 'upstream':
            if phase.output_target == 'supplicant':
                connector_outputs = reverse_affordances.outputs
            elif phase.output_target == 'end':
                phase_affordances = \
                    phase.affordances(downstream=reverse_affordances)
            else:
                connector_outputs = reverse_affordances.inputs
            phase_inputs = None
        elif direction == 'downstream':
            phase_affordances = \
                _affordances.FrozenProcessProspectiveAffordanceSet\
                 .from_general\
                  (phase.affordances(upstream=reverse_affordances),
                   scanners=reverse_affordances.scanners,
                   clerks=reverse_affordances.clerks,
                   supplicants=reverse_affordances.supplicants)

            connector_outputs = None
            phase_inputs = reverse_affordances.outputs
            phase_outputs = phase_affordances.outputs
            try:
                phase_outputs = phase_outputs.set()
            except _coll.UnsupportedUniversalSetOperation:
                raise RuntimeError\
                       ('invalid acceptable outputs {!r} for authentication'
                         ' algorithm phase {!r}; expected a finite set of'
                         ' token sets'
                         .format(phase_outputs, phase))
        else:
            raise ValueError('invalid direction {!r}: expecting {!r} or {!r}'
                              .format(direction, 'upstream', 'downstream'))

        def resolving_logmessage():
            message = 'walking {}, resolving output affordances for phase {}'\
                       ' (input from {}, output to {})'\
                       .format(direction, phase, phase.input_source,
                               phase.output_target)
            if connector_outputs:
                message += ' with {} outputs {}'.format(phase.output_target,
                                                        connector_outputs)
            elif phase_inputs:
                message += ' with inputs {}'.format(phase_inputs)
            return message
        self.logger.cond((_logging.DEBUG, resolving_logmessage))

        reverse_affordances = reverse_affordances.unfrozen_copy()
        if phase.output_target == 'clerk':
            reverse_affordances.clerks = \
                reverse_affordances.clerks.unfrozen_copy()
            connectors = reverse_affordances.clerks
        elif phase.output_target == 'supplicant':
            reverse_affordances.supplicants = \
                reverse_affordances.supplicants.unfrozen_copy()
            connectors = reverse_affordances.supplicants
        elif phase.output_target == 'end':
            if direction == 'downstream':
                return _frozenset((phase_affordances,))
            else:
                assert False
        else:
            assert False, \
                   'invalid output target {!r} for authentication'\
                   ' algorithm phase {!r}; expecting one of {}'\
                    .format(phase.input_source, phase,
                            ('clerk', 'supplicant', 'end'))

        affordancesets = _set()
        for connector in connectors.frozen():
            connector_useful = False
            if direction == 'upstream':
                if phase.output_target == 'clerk':
                    connector_affordances = \
                        _affordances.FrozenProcessProspectiveAffordanceSet\
                         .from_general\
                          (connector.affordances(downstream=
                                                     reverse_affordances),
                           scanners=reverse_affordances.scanners,
                           clerks=(connector,),
                           supplicants=reverse_affordances.supplicants)
                elif phase.output_target == 'supplicant':
                    connector_affordances = reverse_affordances
                else:
                    assert False

                if connector_affordances:
                    connector_inputs = connector_affordances.inputs
                    for connector_input in connector_inputs:
                        if phase.supports_output(connector_input,
                                                 downstream_affordances=
                                                     connector_affordances):
                            connector_useful = True
                            self.logger.cond\
                             ((_logging.DEBUG,
                               _partial(self._considering_handlers_logmessage,
                                        phase, connector_input, connector)))
                            connection_affordances = \
                                connector_affordances.unfrozen_copy()
                            connection_affordances.inputs = (connector_input,)
                            affordancesets |= \
                                self._resolved_phase_input_affordancesets\
                                 (phase, 'upstream',
                                  reverse_affordances=connector_affordances)
            else:
                for phase_output in phase_outputs:
                    if connector.supports_input(phase_output,
                                                upstream_affordances=
                                                    phase_affordances):
                        self.logger.cond\
                         ((_logging.DEBUG,
                           _partial(self._considering_handlers_logmessage,
                                    phase, phase_output, connector)))
                        phase_connection_affordances = \
                            phase_affordances.unfrozen_copy()
                        phase_connection_affordances.outputs = (phase_output,)
                        connector_affordances = \
                            _affordances.ProcessProspectiveAffordanceSet\
                             .from_general\
                              (connector.affordances
                                (upstream=phase_connection_affordances),
                               scanners=reverse_affordances.scanners,
                               clerks=reverse_affordances.clerks,
                               supplicants=reverse_affordances.supplicants)
                        setattr(connector_affordances,
                                '{}s'.format(phase.output_target),
                                (connector,))

                        if connector_affordances:
                            connector_useful = True
                            next_phase = phase.next_phase
                            if next_phase:
                                next_phase_affordancesets = \
                                    self._resolved_phase_input_affordancesets\
                                     (next_phase, 'downstream',
                                      reverse_affordances=
                                          connector_affordances)
                                for next_affordances \
                                        in next_phase_affordancesets:
                                    affordances = next_affordances.unfrozen()
                                    affordances.inputs = phase_inputs
                                    affordances.outputs = \
                                        connector_affordances.inputs
                                    affordancesets.add(affordances.frozen())
                            else:
                                affordancesets.add(connector_affordances
                                                    .frozen())

            if not connector_useful:
                connectors.remove(connector)
        return affordancesets