示例#1
0
    def expire_edges(self, session):
        """Mark expired edges as inactive and log to the audit log.

        Edges are immediately excluded from the permission graph once they've
        expired, but we also want to note the expiration in the audit log and send
        an email notification.  This function finds all expired edges, logs the
        expiration to the audit log, and sends a notification message.  It's meant
        to be run from the background processing thread.

        Args:
            session (session): database session
        """
        now = datetime.utcnow()

        # Pull the expired edges.
        edges = session.query(GroupEdge).filter(
            GroupEdge.group_id == Group.id, Group.enabled == True,
            GroupEdge.active == True,
            and_(GroupEdge.expiration <= now,
                 GroupEdge.expiration != None)).all()

        # Expire each one.
        for edge in edges:
            notify_edge_expiration(self.settings, session, edge)
            edge.active = False
            session.commit()
示例#2
0
    def expire_edges(self, session):
        """Mark expired edges as inactive and log to the audit log.

        Edges are immediately excluded from the permission graph once they've
        expired, but we also want to note the expiration in the audit log and send
        an email notification.  This function finds all expired edges, logs the
        expiration to the audit log, and sends a notification message.  It's meant
        to be run from the background processing thread.

        Args:
            session (session): database session
        """
        now = datetime.utcnow()

        # Pull the expired edges.
        edges = session.query(GroupEdge).filter(
            GroupEdge.group_id == Group.id,
            Group.enabled == True,
            GroupEdge.active == True,
            and_(
                GroupEdge.expiration <= now,
                GroupEdge.expiration != None
            )
        ).all()

        # Expire each one.
        for edge in edges:
            notify_edge_expiration(self.settings, session, edge)
            edge.active = False
            session.commit()
示例#3
0
def test_actor_for_edge_expiration(setup):
    # type: (SetupTest) -> None
    """Test choice of actor ID when expiring an edge.

    Our current audit log model has no concept of a system-generated change and has to map every
    change to a user ID that performed that change.  We previously had a bug where we would try to
    grab the first owner of the group and use them as the actor when someone expired out of a
    group, which caused uncaught exceptions if the group somehow ended up in a state with no
    owners.  Test that we do something sane when expiring edges if possible.

    Everything we're testing here is a workaround for a bug.  Once the audit log has been fixed so
    that we can log entries for system actions without attributing them to some user in the system,
    this test and all of the logic it's testing can go away.
    """
    settings = Settings()
    now_minus_one_second = datetime.utcfromtimestamp(int(time() - 1))
    audit_log_service = setup.service_factory.create_audit_log_service()

    # An expiring individual user should be logged with an actor ID of the user.
    with setup.transaction():
        setup.add_user_to_group("*****@*****.**", "some-group", expiration=now_minus_one_second)
    edge = setup.session.query(GroupEdge).filter_by(expiration=now_minus_one_second).one()
    notify_edge_expiration(settings, setup.session, edge)
    log_entries = audit_log_service.entries_affecting_user("*****@*****.**", 1)
    assert log_entries
    assert log_entries[0].actor == "*****@*****.**"
    assert log_entries[0].action == "expired_from_group"
    assert log_entries[0].on_user == "*****@*****.**"
    with setup.transaction():
        edge.delete(setup.session)

    # An expiring group should be logged with an actor ID of the owner of the parent group.
    with setup.transaction():
        setup.add_user_to_group("*****@*****.**", "parent-group", role="owner")
        setup.add_user_to_group("*****@*****.**", "child-group", role="owner")
        setup.add_group_to_group("child-group", "parent-group", expiration=now_minus_one_second)
    edge = setup.session.query(GroupEdge).filter_by(expiration=now_minus_one_second).one()
    notify_edge_expiration(settings, setup.session, edge)
    log_entries = audit_log_service.entries_affecting_group("child-group", 1)
    assert log_entries
    assert log_entries[0].actor == "*****@*****.**"
    assert log_entries[0].action == "expired_from_group"
    assert log_entries[0].on_group == "child-group"
    log_entries = audit_log_service.entries_affecting_group("parent-group", 1)
    assert log_entries
    assert log_entries[0].actor == "*****@*****.**"
    assert log_entries[0].action == "expired_from_group"
    assert log_entries[0].on_group == "parent-group"
    with setup.transaction():
        edge.delete(setup.session)

    # If the parent group has no owner, it should be logged with an actor ID of the owner of the
    # child group.
    with setup.transaction():
        setup.add_user_to_group("*****@*****.**", "a-group", role="owner")
        setup.add_group_to_group("a-group", "ownerless-group", expiration=now_minus_one_second)
    edge = setup.session.query(GroupEdge).filter_by(expiration=now_minus_one_second).one()
    notify_edge_expiration(settings, setup.session, edge)
    log_entries = audit_log_service.entries_affecting_group("a-group", 1)
    assert log_entries
    assert log_entries[0].actor == "*****@*****.**"
    assert log_entries[0].action == "expired_from_group"
    assert log_entries[0].on_group == "a-group"
    log_entries = audit_log_service.entries_affecting_group("ownerless-group", 1)
    assert log_entries
    assert log_entries[0].actor == "*****@*****.**"
    assert log_entries[0].action == "expired_from_group"
    assert log_entries[0].on_group == "ownerless-group"
    with setup.transaction():
        edge.delete(setup.session)

    # If neither group has an owner, raise an exception.
    with setup.transaction():
        setup.add_group_to_group("other-group", "ownerless-group", expiration=now_minus_one_second)
    edge = setup.session.query(GroupEdge).filter_by(expiration=now_minus_one_second).one()
    with pytest.raises(UnknownActorDuringExpirationException):
        notify_edge_expiration(settings, setup.session, edge)
示例#4
0
def test_actor_for_edge_expiration(setup):
    # type: (SetupTest) -> None
    """Test choice of actor ID when expiring an edge.

    Our current audit log model has no concept of a system-generated change and has to map every
    change to a user ID that performed that change.  We previously had a bug where we would try to
    grab the first owner of the group and use them as the actor when someone expired out of a
    group, which caused uncaught exceptions if the group somehow ended up in a state with no
    owners.  Test that we do something sane when expiring edges if possible.

    Everything we're testing here is a workaround for a bug.  Once the audit log has been fixed so
    that we can log entries for system actions without attributing them to some user in the system,
    this test and all of the logic it's testing can go away.
    """
    settings = Settings()
    now_minus_one_second = datetime.utcfromtimestamp(int(time() - 1))
    audit_log_service = setup.service_factory.create_audit_log_service()

    # An expiring individual user should be logged with an actor ID of the user.
    with setup.transaction():
        setup.add_user_to_group("*****@*****.**",
                                "some-group",
                                expiration=now_minus_one_second)
    edge = setup.session.query(GroupEdge).filter_by(
        expiration=now_minus_one_second).one()
    notify_edge_expiration(settings, setup.session, edge)
    log_entries = audit_log_service.entries_affecting_user("*****@*****.**", 1)
    assert log_entries
    assert log_entries[0].actor == "*****@*****.**"
    assert log_entries[0].action == "expired_from_group"
    assert log_entries[0].on_user == "*****@*****.**"
    with setup.transaction():
        edge.delete(setup.session)

    # An expiring group should be logged with an actor ID of the owner of the parent group.
    with setup.transaction():
        setup.add_user_to_group("*****@*****.**", "parent-group", role="owner")
        setup.add_user_to_group("*****@*****.**", "child-group", role="owner")
        setup.add_group_to_group("child-group",
                                 "parent-group",
                                 expiration=now_minus_one_second)
    edge = setup.session.query(GroupEdge).filter_by(
        expiration=now_minus_one_second).one()
    notify_edge_expiration(settings, setup.session, edge)
    log_entries = audit_log_service.entries_affecting_group("child-group", 1)
    assert log_entries
    assert log_entries[0].actor == "*****@*****.**"
    assert log_entries[0].action == "expired_from_group"
    assert log_entries[0].on_group == "child-group"
    log_entries = audit_log_service.entries_affecting_group("parent-group", 1)
    assert log_entries
    assert log_entries[0].actor == "*****@*****.**"
    assert log_entries[0].action == "expired_from_group"
    assert log_entries[0].on_group == "parent-group"
    with setup.transaction():
        edge.delete(setup.session)

    # If the parent group has no owner, it should be logged with an actor ID of the owner of the
    # child group.
    with setup.transaction():
        setup.add_user_to_group("*****@*****.**", "a-group", role="owner")
        setup.add_group_to_group("a-group",
                                 "ownerless-group",
                                 expiration=now_minus_one_second)
    edge = setup.session.query(GroupEdge).filter_by(
        expiration=now_minus_one_second).one()
    notify_edge_expiration(settings, setup.session, edge)
    log_entries = audit_log_service.entries_affecting_group("a-group", 1)
    assert log_entries
    assert log_entries[0].actor == "*****@*****.**"
    assert log_entries[0].action == "expired_from_group"
    assert log_entries[0].on_group == "a-group"
    log_entries = audit_log_service.entries_affecting_group(
        "ownerless-group", 1)
    assert log_entries
    assert log_entries[0].actor == "*****@*****.**"
    assert log_entries[0].action == "expired_from_group"
    assert log_entries[0].on_group == "ownerless-group"
    with setup.transaction():
        edge.delete(setup.session)

    # If neither group has an owner, raise an exception.
    with setup.transaction():
        setup.add_group_to_group("other-group",
                                 "ownerless-group",
                                 expiration=now_minus_one_second)
    edge = setup.session.query(GroupEdge).filter_by(
        expiration=now_minus_one_second).one()
    with pytest.raises(UnknownActorDuringExpirationException):
        notify_edge_expiration(settings, setup.session, edge)