Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor user management #1052

Merged
merged 31 commits into from May 2, 2024
Merged

Refactor user management #1052

merged 31 commits into from May 2, 2024

Conversation

JelteF
Copy link
Member

@JelteF JelteF commented Apr 18, 2024

Based upon #1039, but changed a lot by splitting the PgUser type into two different types. First we introduce a PgGlobalUser type which stores user settings from the ini file, credentials in auth_file and connection count tracking. And secondly we introduce PgCredentials which only stores user credentials, these could either come from the auth_file or auth_query. This type is embedded in the PgGlobalUser to store any global credentials from auth_file, and it also links back to the matching PgGlobalUser.

This makes user configuration work for dynamically created users and will also list dynamically created users in the output of SHOW USERS.

Fixes #484
Fixes #706
Resolves #1039

Ben Chobot and others added 21 commits March 8, 2024 15:24
As described in pgbouncer#484, if a user is defined in the [users] section of
the config file (perhaps to take advantage of per-user overrides)
but then that user is *not* defined in auth_file, pgBouncer currently
gets confused when trying to check their password. It sees the user
exists, but fails to notice a password was never defined, resulting
in no running of auth_query.
As described in pgbouncer#484, if a user is defined in the [users] section of
the config file (perhaps to take advantage of per-user overrides)
but then that user is *not* defined in auth_file, pgBouncer currently
gets confused when trying to check their password. It sees the user
exists, but fails to notice a password was never defined, resulting
in no running of auth_query.

Add a test case to catch this. The case successfully fails before
this patchset and succeeds after it.
As described in pgbouncer#484, if a user is defined in the [users] section of
the config file (perhaps to take advantage of per-user overrides)
but then that user is *not* defined in auth_file, pgBouncer currently
gets confused when trying to check their password. It sees the user
exists, but fails to notice a password was never defined, resulting
in no running of auth_query.

Add a test case to catch this. The case successfully fails before
this patchset and succeeds after it.
As described in pgbouncer#484, if a user is defined in the [users] section of
the config file (perhaps to take advantage of per-user overrides)
but then that user is *not* defined in auth_file, pgBouncer currently
gets confused when trying to check their password. It sees the user
exists, but fails to notice a password was never defined, resulting
in no running of auth_query.t

Add a test case to catch this. The case successfully fails before
this patchset and succeeds after it.
This reduces checks that must be made throughout the code, though
it does not reduce the need to know which record is the proper
one (user or user->cf_user) to use.

Also, pre-emptively make uncrustify happy *before* github has a go
at it.
The comments are more accurate, and the unit test now runs against
freebsd as well as other OSs.
Copy link
Contributor

@benchub benchub left a comment

Choose a reason for hiding this comment

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

I think it's a fine refactor. I do think there's more work to do if this is the direction - a lot of field names that used to be of type PgUser are still named some permutation of "user", even though they are now storing credential info instead of the new GlobalUser type.

include/bouncer.h Outdated Show resolved Hide resolved
@@ -326,7 +327,7 @@ struct PgPool {
struct List map_head; /* entry in user->pool_list */

PgDatabase *db; /* corresponding database */
PgUser *user; /* user logged in as, this field is NULL for peer pools */
PgAuthInfo *user; /* user logged in as, this field is NULL for peer pools */
Copy link
Contributor

Choose a reason for hiding this comment

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

Given GlobalUser as a type, I am tempted to suggest this field should be called auth_info or credentials instead of user, to reduce confusion. (And yes, this implies a fair amount of substitutions elsewhere.)

In general, how do you feel about never using "user" for pgAuthInfo data, and keeping that reserved for GlobalUser types?

Copy link
Member Author

@JelteF JelteF Apr 18, 2024

Choose a reason for hiding this comment

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

Yeah, it's definitely something I think we should be consistent about and was originally trying to do what you are suggesting. But when I got to the auth_user field, I didn't really like the resulting auth_user_auth_info name.

So I held off on changing everything for now, because maybe it fits better to rename PgAuthInfo to PgUser

Copy link
Contributor

Choose a reason for hiding this comment

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

What about s/PgAuthInfo/PgCredentials/, so that you end up with auth_user_credentials or the like?

Copy link
Member Author

Choose a reason for hiding this comment

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

I like that suggestion. I'll try that out tomorrow.

Copy link
Member Author

Choose a reason for hiding this comment

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

Okay, I finally found the time to do this. Could you take another look? I'm pretty happy with the result.

src/client.c Outdated Show resolved Hide resolved
@JelteF JelteF marked this pull request as ready for review April 29, 2024 10:10
Copy link
Contributor

@benchub benchub left a comment

Choose a reason for hiding this comment

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

It's a lot of changes, but it looks good enough at this point that I unleashed my inner grammar nazi for some nits. Assuming the unit tests pass I think it's good enough to get it out there.

doc/config.md Outdated
@@ -1255,6 +1256,12 @@ Example:

Only a few settings are available here.

Note that when `auth_file` configured, if a user is defined in this section but
Copy link
Contributor

Choose a reason for hiding this comment

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

...auth_file is configured...

bool dynamic_passwd; /* does the password need to be refreshed every use */

/*
* global_user points at the global user that is used for configuration
Copy link
Contributor

Choose a reason for hiding this comment

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

...global user which is used...


/*
* The global user is used for configuration settings and connection count. It
* includes credentials, but this are empty if the user is not configured in
Copy link
Contributor

Choose a reason for hiding this comment

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

...but these are empty...

@JelteF JelteF enabled auto-merge (squash) May 2, 2024 08:36
@JelteF JelteF merged commit b003f7b into pgbouncer:master May 2, 2024
7 checks passed
@eulerto eulerto mentioned this pull request May 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

pgbouncer didn't even try auth_query to verify user password
2 participants