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

GH-2054 Cover #2054 with test case #2055

Merged
merged 7 commits into from
Feb 28, 2024
Merged

GH-2054 Cover #2054 with test case #2055

merged 7 commits into from
Feb 28, 2024

Conversation

dzikoysk
Copy link
Owner

No description provided.

}

@Test
fun `should authenticate mykola`() {
Copy link

@mstup mstup Feb 16, 2024

Choose a reason for hiding this comment

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

@dzikoysk Please correct me if I'm wrong but understand this test like only "mykola" is allowed to login. But as I described it in the ticket, only "readonly" should be allowed to connect LDAP and all other should be blocked. This is how BindDN works.
Here is more details how it works, hope this can help to understand
https://github.com/osixia/docker-openldap#defaultstartupyaml

Copy link
Owner Author

Choose a reason for hiding this comment

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

Okay, so that's not how I understood the issue. From the logs you've provided I thought you can successfully login with readonly (conn=1021), but you cannot do this with mykola (conn=1022). Could you specify your LDAP server config that I can use in this test to go through your issue? I feel like it can be done in multiple ways and I'm currently trying to guess what setup you actually have 🤔

Copy link

@mstup mstup Feb 16, 2024

Choose a reason for hiding this comment

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

ldap.txt

Only three users are allowed:

  • admin - administration tasks (add/remove).
  • config - Ldap configuration.
  • readonly - used by external services to bind to the server.

Copy link

Choose a reason for hiding this comment

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

Okay, so that's not how I understood the issue. From the logs you've provided I thought you can successfully login with readonly (conn=1021), but you cannot do this with mykola (conn=1022).

Yes, you understand it correct. User "mykola" shouldn't have expected to LDAP server. Access is granted only for user specified in Reposilite configuration and none other.

@dzikoysk
Copy link
Owner Author

So this is your configuration:

"baseDn": "ou=people,dc=domain,dc=com",
"searchUserDn": "cn=readonly,dc=domain,dc=com",
"searchUserPassword": "nopassword",
"typeAttribute": "posixAccount",
"userAttribute": "uid",
"userFilter": "(memberOf=cn=users,ou=reposilite,dc=domain,dc=com)",
"userType": "PERSISTENT"

Let's go through this:

  1. Base distinguished name has been set to ou=people,dc=domain,dc=com, it means that search base will only examine ou=people subtree in the dc=domain,dc=com directory
  2. Search user has been set to cn=readonly,dc=domain,dc=com - this user will be used by Reposilite to check credentials of users that are trying to login to Reposilite
  3. Password of search user (cn=readonly,dc=domain,dc=com in this case)
  4. typeAttribute objectClass filter, so we will only check for records that posixAccount objects
  5. userAttribute property that will contain username for a token that Reposilite will generate, e.g. uid=dzikoysk
  6. User filter selects entries that are allowed to use Reposilite, in this case it has to contain (memberOf=cn=users,ou=reposilite,dc=domain,dc=com) trait

Having that in mind, I've updated our test:

  1. cn=readonly,dc=domain,dc=com is properly authenticated on Reposilite's side and can perform search queries
  2. uid=mykola,ou=people,dc=domain,dc=com is not authenticated, because memberOf is not matched
  3. uid=panda,ou=people,dc=domain,dc=com is authenticated, because it's a part of Reposilite group

@mstup
Copy link

mstup commented Feb 17, 2024

Yes that's correct now.
No one other user shouldn't try to bind LDAP server only one defined in Reposilite settings. Users authorization is made by search user is memberOf certain OU. If user is memeber of certain OU the next step is password validation.

This code which you have now (v 3.5.6) is suitable for the case when each user connect server separately. But on user interface there is way to setup BindDN connection (only one user have to do all work).

Here is good screenshots for Gitea to understand what I'm talking about.

==============> Simple Auth
image

==============> BindDN
image

@dzikoysk
Copy link
Owner Author

Okay, I think I got what you assume the bug is here. You're trying to reuse cn=readonly,dc=domain,dc=com as an actual user, not the authorization credentials for server-side ldap connection that queries your directories, right?

If that's correct, then you should modify your userAttribute in Reposilite's configuration - probably to cn, because that was the expected name you used here: #2054. There's no option to login to the dashboard without the username - that's because Reposilite does not really have a concept of users, it's directly mapped to access token on our side & the name is automatically fetched from the LDAP settings (we don't have complete registration form, or something like that, so we can't simply skip this attribute for now).

Also, if you'll confirm this is valid, I see that we could improve our integration - especially considering changes that are coming in 4.x:

@mstup
Copy link

mstup commented Feb 21, 2024

Okay, I think I got what you assume the bug is here. You're trying to reuse cn=readonly,dc=domain,dc=com as an actual user, not the authorization credentials for server-side ldap connection that queries your directories, right?

Yes, this is what page design is propose to do (at least how I understood that with my previous experience with Gitea page design of integration with LDAP).

@mstup
Copy link

mstup commented Feb 21, 2024

the name is automatically fetched from the LDAP settings

But, user which connect to server again to fetch the name should remains the first one, but not this one the name of which you want to receive.

  1. You connect first time with readonoly user and checking if user mykola exist.
  2. If user mykola exist you connected second time to check his memberOf value. But to do this needs again connect to LDAP as readonly user. Any other user can't login to LDAP server it is prohibited by LDAP server configuration.

@dzikoysk
Copy link
Owner Author

dzikoysk commented Feb 21, 2024

So now, memberOf (user filter) is checked already in the first query. Later on, the only thing we do for mykola is a construction of LDAP context (so we can check credentials), but we're not trying to query the server with that user anymore. I'm not quite sure why it was actually implemented like that before, if we're able to do it all within just one search request 🤔

@mstup
Copy link

mstup commented Feb 23, 2024

@dzikoysk
As I understood this code and as I already mentioned in the ticket. I see problem in this line.
Method createDirContext is preparing connection parameters and execute method InitialDirContext and this is the second attempt to connect to LDAP server with user's received credentials (mykola's credentials).
Why?

@dzikoysk
Copy link
Owner Author

dzikoysk commented Feb 23, 2024

Like I said before, this is the limitation of our current implementation in 3.x - password is required to create a new secret associated with generated access token. What you're asking for is a passwordless logging form for users working in the internal network - we don't have a concept of users nor the token management panel in the UI. This kind of work is scheduled for 4.x:

On the other hand, if we'd keep username + password in the logging form & we'd not validate the user's credentials, we'd silently create a new token on the first logging attempt. It's a bit dirty, since it's not covered at any point by current UI.

What we did in the past for this kind of edge cases, is an internal flag. I could disable user's authentication behind a feature flag, like e.g. reposilite.ldap.disable-user-password-authentication. Do you think it'd work for you?

@mstup
Copy link

mstup commented Feb 25, 2024

Yes, looks like acceptable solution at this moment.

@dzikoysk dzikoysk merged commit 827eb57 into main Feb 28, 2024
5 checks passed
@dzikoysk dzikoysk deleted the GH2054-mykola-ldap branch February 28, 2024 01:00
@mstup
Copy link

mstup commented Mar 3, 2024

Tested and works fine. Thank you.

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.

2 participants