Example #1
0
def ldap_sync(self: MonitoredTask, source_pk: str, sync_class: str):
    """Synchronization of an LDAP Source"""
    self.result_timeout_hours = 2
    try:
        source: LDAPSource = LDAPSource.objects.get(pk=source_pk)
    except LDAPSource.DoesNotExist:
        # Because the source couldn't be found, we don't have a UID
        # to set the state with
        return
    sync = path_to_class(sync_class)
    self.set_uid(
        f"{source.slug}_{sync.__name__.replace('LDAPSynchronizer', '').lower()}"
    )
    try:
        sync_inst = sync(source)
        count = sync_inst.sync()
        messages = sync_inst.messages
        messages.append(f"Synced {count} objects.")
        self.set_status(TaskResult(
            TaskResultStatus.SUCCESSFUL,
            messages,
        ))
    except LDAPException as exc:
        # No explicit event is created here as .set_status with an error will do that
        LOGGER.debug(exc)
        self.set_status(TaskResult(TaskResultStatus.ERROR).with_error(exc))
Example #2
0
def authenticate(request: HttpRequest, backends: list[str],
                 **credentials: dict[str, Any]) -> Optional[User]:
    """If the given credentials are valid, return a User object.

    Customized version of django's authenticate, which accepts a list of backends"""
    for backend_path in backends:
        try:
            backend: BaseBackend = path_to_class(backend_path)()
        except ImportError:
            LOGGER.warning("Failed to import backend", path=backend_path)
            continue
        LOGGER.debug("Attempting authentication...", backend=backend_path)
        user = backend.authenticate(request, **credentials)
        if user is None:
            LOGGER.debug("Backend returned nothing, continuing",
                         backend=backend_path)
            continue
        # Annotate the user object with the path of the backend.
        user.backend = backend_path
        LOGGER.debug("Successful authentication",
                     user=user,
                     backend=backend_path)
        return user

    # The credentials supplied are invalid to all backends, fire signal
    user_login_failed.send(sender=__name__,
                           credentials=_clean_credentials(credentials),
                           request=request)
Example #3
0
def outpost_post_save(model_class: str, model_pk: Any):
    """If an Outpost is saved, Ensure that token is created/updated

    If an OutpostModel, or a model that is somehow connected to an OutpostModel is saved,
    we send a message down the relevant OutpostModels WS connection to trigger an update"""
    model: Model = path_to_class(model_class)
    try:
        instance = model.objects.get(pk=model_pk)
    except model.DoesNotExist:
        LOGGER.warning("Model does not exist", model=model, pk=model_pk)
        return

    if isinstance(instance, Outpost):
        LOGGER.debug("Ensuring token for outpost", instance=instance)
        _ = instance.token
        LOGGER.debug("Trigger reconcile for outpost")
        outpost_controller.delay(instance.pk)

    if isinstance(instance, (OutpostModel, Outpost)):
        LOGGER.debug("triggering outpost update from outpostmodel/outpost",
                     instance=instance)
        outpost_send_update(instance)

    if isinstance(instance, OutpostServiceConnection):
        LOGGER.debug("triggering ServiceConnection state update",
                     instance=instance)
        outpost_service_connection_state.delay(instance.pk)

    for field in instance._meta.get_fields():
        # Each field is checked if it has a `related_model` attribute (when ForeginKeys or M2Ms)
        # are used, and if it has a value
        if not hasattr(field, "related_model"):
            continue
        if not field.related_model:
            continue
        if not issubclass(field.related_model, OutpostModel):
            continue

        field_name = f"{field.name}_set"
        if not hasattr(instance, field_name):
            continue

        LOGGER.debug("triggering outpost update from from field",
                     field=field.name)
        # Because the Outpost Model has an M2M to Provider,
        # we have to iterate over the entire QS
        for reverse in getattr(instance, field_name).all():
            outpost_send_update(reverse)
 def test_path_to_class(self):
     """Test path_to_class"""
     self.assertIsNone(path_to_class(None))
     self.assertEqual(path_to_class("datetime.datetime"), datetime)