Skip to content

Add auditlog helper script#3739

Open
hmpf wants to merge 5 commits intomasterfrom
add-auditlog-helper-script
Open

Add auditlog helper script#3739
hmpf wants to merge 5 commits intomasterfrom
add-auditlog-helper-script

Conversation

@hmpf
Copy link
Copy Markdown
Contributor

@hmpf hmpf commented Jan 27, 2026

Scope and purpose

Fixes #3729

Also adds some other useful tools for examining and using the auditlog.

Open questions:

  • is tools/ the right place for it?
  • is the name good enough?
  • should the delete-account repair be a migration instead?

Contributor Checklist

Every pull request should have this checklist filled out, no matter how small it is.
More information about contributing to NAV can be found in the
Hacker's guide to NAV.

  • Added a changelog fragment for towncrier
  • Added/amended tests for new/changed code
  • Added/changed documentation
  • Linted/formatted the code with ruff, easiest by using pre-commit
  • Wrote the commit message so that the first line continues the sentence "If applied, this commit will ...", starts with a capital letter, does not end with punctuation and is 50 characters or less long. See https://cbea.ms/git-commit/
  • Based this pull request on the correct upstream branch: For a patch/bugfix affecting the latest stable version, it should be based on that version's branch (<major>.<minor>.x). For a new feature or other additions, it should be based on master.
  • If applicable: Created new issues if this PR does not fix the issue completely/there is further work to be done
  • If it's not obvious from a linked issue, described how to interact with NAV in order for a reviewer to observe the effects of this change first-hand (commands, URLs, UI interactions)
  • If this results in changes in the UI: Added screenshots of the before and after
  • If this adds a new Python source code file: Added the boilerplate header to that file

@hmpf hmpf requested a review from a team January 27, 2026 11:58
@hmpf hmpf self-assigned this Jan 27, 2026
@hmpf hmpf added the auditlog label Jan 27, 2026
@hmpf hmpf marked this pull request as draft January 27, 2026 12:07
@github-actions
Copy link
Copy Markdown

github-actions bot commented Jan 27, 2026

Test results

    14 files      14 suites   25m 19s ⏱️
 2 973 tests  2 973 ✅ 0 💤 0 ❌
17 010 runs  17 010 ✅ 0 💤 0 ❌

Results for commit 7caa7a8.

♻️ This comment has been updated with latest results.

@codecov
Copy link
Copy Markdown

codecov bot commented Jan 27, 2026

Codecov Report

❌ Patch coverage is 28.57143% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.58%. Comparing base (40e206f) to head (7caa7a8).
⚠️ Report is 279 commits behind head on master.

Files with missing lines Patch % Lines
python/nav/auditlog/utils.py 28.57% 10 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3739      +/-   ##
==========================================
+ Coverage   63.14%   63.58%   +0.43%     
==========================================
  Files         614      614              
  Lines       45502    45764     +262     
  Branches       43       43              
==========================================
+ Hits        28734    29097     +363     
+ Misses      16758    16657     -101     
  Partials       10       10              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@hmpf hmpf force-pushed the add-auditlog-helper-script branch from 0da6f66 to 3ffaec4 Compare January 29, 2026 12:02
@hmpf hmpf marked this pull request as ready for review January 29, 2026 12:02
@hmpf hmpf force-pushed the add-auditlog-helper-script branch 2 times, most recently from 154c77e to bf15a09 Compare January 30, 2026 11:28
Copy link
Copy Markdown
Contributor

@johannaengland johannaengland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I try to run python tools/audit_auditlog.py fix -p delete-account with a copy of our production database I get the following error:

Traceback (most recent call last):
  File "/workspaces/nav/tools/audit_auditlog.py", line 173, in <module>
    main()
  File "/workspaces/nav/tools/audit_auditlog.py", line 50, in main
    repair_delete_account()
  File "/workspaces/nav/tools/audit_auditlog.py", line 164, in repair_delete_account
    free_ids = _find_unused_ids()
               ^^^^^^^^^^^^^^^^^^
  File "/workspaces/nav/tools/audit_auditlog.py", line 134, in _find_unused_ids
    max_id = max(used_ids)
             ^^^^^^^^^^^^^
TypeError: '>' not supported between instances of 'str' and 'int'

that happens because actor_ids are strings and account_ids are int

@hmpf hmpf force-pushed the add-auditlog-helper-script branch from 223198b to 6d8125b Compare February 4, 2026 11:49
@hmpf hmpf requested review from a team and johannaengland February 4, 2026 12:22
@hmpf hmpf force-pushed the add-auditlog-helper-script branch from 7c2a610 to f305d27 Compare February 6, 2026 07:52
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Feb 6, 2026

Copy link
Copy Markdown
Contributor

@johannaengland johannaengland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I try to run python tools/audit_auditlog.py fix -r delete-account-fix-object then I get the following traceback:

Traceback (most recent call last):
  File "/workspaces/nav/tools/audit_auditlog.py", line 267, in <module>
    main()
  File "/workspaces/nav/tools/audit_auditlog.py", line 74, in main
    elif args.repair in KNOWN_REPAIRS:
         ^^^^^^^^^^^
AttributeError: 'Namespace' object has no attribute 'repair'



def get_lurkers():
"Get a list of current accounts that have no actor entries in the audit log"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"Get a list of current accounts that have no actor entries in the audit log"
"Get a list of current accounts that have not been recorded as actors in the audit log"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed


def list_available_fixes():
"List avaliable fixes"
print("delete-account: Attempts to set the pk of the object if it is missing")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
print("delete-account: Attempts to set the pk of the object if it is missing")
print("delete-account: Attempts to set the pk of the object if it is missing to malformed delete-account entries")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

),
"-r",
"--report",
help="Generate and print the named report",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be consistent - all should either start with a lowercase or uppercase letter

Suggested change
help="Generate and print the named report",
help="generate and print the named report",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

"zombies",
(
"List currently existing accounts that according to the audit log "
"should no longer exist."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"should no longer exist."
"should no longer exist"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@hmpf hmpf requested a review from johannaengland March 19, 2026 08:01
@sonarqubecloud
Copy link
Copy Markdown

@lunkwill42
Copy link
Copy Markdown
Member

lunkwill42 commented Mar 23, 2026

is tools/ the right place for it?

If this is a tool you intend for end-users to run manually to clean up broken auditlog history, then the answer is no.

If it is purely meant as a tool for developers to manipulate data in their development installations, then the answer is yes.

The point being: tools/ is for developer tools; these are never installed in a NAV system.

@lunkwill42
Copy link
Copy Markdown
Member

should the delete-account repair be a migration instead?

Absolutely not. I don't want to see something that automatically deletes user accounts without user intervention on upgrades. We cannot know the admin's current intent from looking at old, potentially broken or incorrect audit log entries.

Copy link
Copy Markdown
Member

@lunkwill42 lunkwill42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found this tool a bit confusing (it doesn't help that the PR includes commits that just refactor previous commits from the same PR, I did spend time commenting on stuff that was removed later).

If this is a tool that we want to make available to actual end users, I think we need some better documentation about what the actual issues are that this script is trying help fix. If it is not a tool for end users, what good is it really?



def get_all_historical_actors():
"List all recorded actors (need not be accounts!), including deleted ones"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this mean? What kind of actors will the audit log refer to that are not accounts?

And why only single quotes? PEP-257 (which we try to adopt in NAV) suggest to always use triple quotes, for consistency. I know there is some old code in NAV that doesn't follow it properly, but that's no excuse to drop it from new code :)

Comment on lines +125 to +133
actor = tuple(
filter(lambda x: x is not None, (entry.actor_model, entry.actor_pk))
)
obj = tuple(
filter(lambda x: x is not None, (entry.object_model, entry.object_pk))
)
target = tuple(
filter(lambda x: x is not None, (entry.target_model, entry.target_pk))
)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just

Suggested change
actor = tuple(
filter(lambda x: x is not None, (entry.actor_model, entry.actor_pk))
)
obj = tuple(
filter(lambda x: x is not None, (entry.object_model, entry.object_pk))
)
target = tuple(
filter(lambda x: x is not None, (entry.target_model, entry.target_pk))
)
actor = tuple(x for x in (entry.actor_model, entry.actor_pk) if x is not None)
obj = tuple(x for x in (entry.object_model, entry.object_pk) if x is not None)
target = tuple(x for x in (entry.target_model, entry.target_pk) if x is not None)

? (plus ruff-formatting, of course)



def get_lurkers():
"Get a list of current accounts that have no actor entries in the audit log"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PEP-257



def view_dump():
"Print dump suitable for further processing"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PEP-257



def view_lurkers():
"Print list of current accounts never recorded as actors in the audit log"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PEP-257



def delete_account_remove_zombies():
"Delete accounts that have an entry in the object column of delete-account"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PEP-257

Comment on lines +163 to +164
"List currently existing accounts that have not done anything "
"in this NAV instance"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"List currently existing accounts that have not done anything "
"in this NAV instance"
"List currently existing accounts that have no logged activity in this NAV "
"instance"

Comment on lines +208 to +209
"Lurkers" are accounts that have no entries in the actor-column.
Their pk's are faked because there is no way to recover them.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought lurkers were accounts that exist but have never been logged as having had any activity?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Repair auditlogs where account has been deleted

3 participants