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

Identity providers: Pagination in account console (and account REST API) #21261

Open
Tracked by #21071 ...
mposolda opened this issue Jun 27, 2023 · 19 comments · May be fixed by #33019
Open
Tracked by #21071 ...

Identity providers: Pagination in account console (and account REST API) #21261

mposolda opened this issue Jun 27, 2023 · 19 comments · May be fixed by #33019
Assignees
Labels
kind/enhancement Categorizes a PR related to an enhancement team/core-iam

Comments

@mposolda
Copy link
Contributor

Description

See https://issues.redhat.com/browse/KEYCLOAK-18061 and #8609

Discussion

#8609

Motivation

No response

Details

No response

@cgeorgilakis
Copy link
Contributor

@mposolda @sguilhen I am thinking that we can separate REST API and ui PRs keeping backward compatibility for REST API as mentioned in the previous PR.

Moreover, linked IdPs are little (max 3 even for us) . So, I am thinking that we could have pager only for unlinked IdPs and get linked IdPs from federated identity similar as in admin console. Do you agree?

Could we have in your IdP search criteria a way to exclude linked IdPs ids (or alias)?
What does it mean for IdPs that a user belongs in an organization? I do know the organization part.

@sguilhen
Copy link
Contributor

sguilhen commented Aug 2, 2024

@cgeorgilakis I agree with separating the changes... I wouldn't differentiate between linked vs unliked for pagination, even if the number of linked idps should likely be a low one.

Regarding the criteria, I think we can make something work for that using the search by attributes if I change the Map<String, String> to Map<String, Object> and check if the value is a collection. If it is, then it is a IN search, which would come in handy when getting the IDPs linked to the federated identities.

Then we could have an option in the attributes map (something like ALIAS_FETCHING_MODE = EQUALS or NOT_EQUALS) that we can check to actually find all IDPs except the one(s) that have the specified alias(es).

So code would look something like this:

session.identityProviders().getAllStream(Map.of(
                     IdentityProviderModel.ALIAS, aliasCollection,
                     IdentityProviderMOdel.ALIAS_FETCHING_MODE, IdentityProviderModel.NOT_EQUALS, first, max);
                     

And this would simply do a SELECT * FROM IDENTITY_PROVIDER WHERE PROVIDER_ALIAS NOT IN ('alias-a', 'alias-b', 'alias-z')

About orgs, I would like to discuss this with @pedroigor next week - I don't recall what we thought would be a good idea when the user is member of an org or has a domain that matches an org. We probably only want to show the realm IDPs (not linked to any org), and IDPs linked to the org(s) the user belongs to. Every other IDP should probably not be available for linking.

@sguilhen
Copy link
Contributor

sguilhen commented Aug 2, 2024

If the number of linked accounts is really expected to be a low one, we can create a stream out of the aliases found in the federated identities and map them using getByAlias (which will be cached) instead of using a more complex query with the IN operator, but that has to be studied.

@pedroigor
Copy link
Contributor

@sguilhen @cgeorgilakis What do you think about these requirements around orgs and the account console?

@sguilhen
Copy link
Contributor

sguilhen commented Aug 6, 2024

Given that the plan is to have a separate section for the the organizations in the account console, I agree that the IDPs related to orgs should not be visible for linking/unlinking.

@pedroigor
Copy link
Contributor

@sguilhen @cgeorgilakis I forgot to send the link in the comment #21261 (comment). See #31944.

@cgeorgilakis
Copy link
Contributor

So, @pedroigor we need to have different account ui and different REST API pager for organization users based on #31944.
@sguilhen At least for filtering unlinked user IdPs we need the mentioned change in IdPs search.
For linked IdPs you should decide for the best method. I vote for using getByAlias .

After having the change in IdPs search and decide about linked user IdPs, I could provide a PR for account REST API for users not belonging in organization. Ui changes will follow.

@sguilhen
Copy link
Contributor

@sguilhen At least for filtering unlinked user IdPs we need the mentioned change in IdPs search. For linked IdPs you should decide for the best method. I vote for using getByAlias .

Hi @cgeorgilakis I will be working on the changes to allow for a search that fetches the IDPs while excluding the federated aliases. Probably using a key like "ALIASES_NOT_IN" and a value being the list of aliases separated by something like , . For the unlinked providers we want to exclude the ones associated with orgs, so the search options map will also need the organization id set to empty or null.

Regarding the linked accounts, I agree we should simply fetch the federated identities, get federation link, which IIRC is the provider's alias, and then simply call getByAlias(), doing pagination using the skip and limit stream methods.

@cgeorgilakis
Copy link
Contributor

cgeorgilakis commented Sep 2, 2024

@sguilhen At least for filtering unlinked user IdPs we need the mentioned change in IdPs search. For linked IdPs you should decide for the best method. I vote for using getByAlias .

Hi @cgeorgilakis I will be working on the changes to allow for a search that fetches the IDPs while excluding the federated aliases. Probably using a key like "ALIASES_NOT_IN" and a value being the list of aliases separated by something like , . For the unlinked providers we want to exclude the ones associated with orgs, so the search options map will also need the organization id set to empty or null.

Regarding the linked accounts, I agree we should simply fetch the federated identities, get federation link, which IIRC is the provider's alias, and then simply call getByAlias(), doing pagination using the skip and limit stream methods.

How could I take the organization user belong?

@sguilhen I see that the method getAllStream(Map<String, String> attrs, Integer first, Integer max) from JpaIDPProvider searches only for config attributes. You could not search with alias or displayName.
Our previous PR filter IdP list based on alias or display name. We want both because display name is optional and alias maybe not user friendly. Take into account that display name of the LinkedAccountRepresentation is taken from KeycloakModelUtils.getIdentityProviderDisplayName.
Moreover, now we want to filter based on organization (if exists).

So I propose a new method that will search with and from :

  • x.alias like '%+search+%' or x.displayName like '%+search+%'
  • exclude list of alias
  • search for kc.org attribute if organization exists

@sguilhen
Copy link
Contributor

sguilhen commented Sep 2, 2024

How could I take the organization user belong?

@sguilhen I see that the method getAllStream(Map<String, String> attrs, Integer first, Integer max) from JpaIDPProvider searches only for config attributes. You could not search with alias or displayName. Our previous PR filter IdP list based on alias or display name. We want both because display name is optional and alias maybe not user friendly. Take into account that display name of the LinkedAccountRepresentation is taken from KeycloakModelUtils.getIdentityProviderDisplayName. Moreover, now we want to filter based on organization (if exists).

So I propose a new method that will search with and from :

  • x.alias like '%+search+%' or x.displayName like '%+search+%'
  • exclude list of alias
  • search for kc.org attribute if organization exists

@cgeorgilakis I've just opened a PR with all changes to the endpoint, based on the work you guys did but already using the provider to filter things. (see #32581). Once that is merged, all we will need is the UI changes to call the endpoint using the new parameters.

To search by alias (partial search or exact search) there's a param called SEARCH in IdentityProviderModel that can be put in the options map. It currently only tries to match the string with the alias, not the description, but this should be easy to change in the provider impl. I think we can do that as part of a separate issue.

For organizations we have another param called ORGANIZATION_ID in the IdentityProviderModel that can be set to the specific id or to an empty string (or null) if you want the IDPs not linked to orgs.

To find ids that don't match the federated ones, I've introduced another param called ALIAS_NOT_IN that takes a comma-separated string of the aliases we don't want.

@cgeorgilakis
Copy link
Contributor

How could I take the organization user belong?
@sguilhen I see that the method getAllStream(Map<String, String> attrs, Integer first, Integer max) from JpaIDPProvider searches only for config attributes. You could not search with alias or displayName. Our previous PR filter IdP list based on alias or display name. We want both because display name is optional and alias maybe not user friendly. Take into account that display name of the LinkedAccountRepresentation is taken from KeycloakModelUtils.getIdentityProviderDisplayName. Moreover, now we want to filter based on organization (if exists).
So I propose a new method that will search with and from :

  • x.alias like '%+search+%' or x.displayName like '%+search+%'
  • exclude list of alias
  • search for kc.org attribute if organization exists

@cgeorgilakis I've just opened a PR with all changes to the endpoint, based on the work you guys did but already using the provider to filter things. (see #32581). Once that is merged, all we will need is the UI changes to call the endpoint using the new parameters.

To search by alias (partial search or exact search) there's a param called SEARCH in IdentityProviderModel that can be put in the options map. It currently only tries to match the string with the alias, not the description, but this should be easy to change in the provider impl. I think we can do that as part of a separate issue.

For organizations we have another param called ORGANIZATION_ID in the IdentityProviderModel that can be set to the specific id or to an empty string (or null) if you want the IDPs not linked to orgs.

To find ids that don't match the federated ones, I've introduced another param called ALIAS_NOT_IN that takes a comma-separated string of the aliases we don't want.

Thank you.
Ok, I will create a nice to have issue for search based on alias or display name.
As I see the change will affect also Identity Provider pager in admin console.

@sguilhen
Copy link
Contributor

sguilhen commented Sep 2, 2024

As I see the change will affect also Identity Provider pager in admin console.

Yup, as far as I can see the change would be in tbe JpaIdentityProviderStorageProvider, when processing the SEARCH param, and also in the LinkedAccountsResource when filtering the linked IDPs - both should be pretty straightforward though. Feel free to send a PR for that if you have the time.

@sguilhen
Copy link
Contributor

sguilhen commented Sep 4, 2024

@cgeorgilakis The changes to the rest endpoint have been merged, so it is already possible to rework the console to invoke the endpoint and fetch linked/unlinked idps independently in paginated fashion. Do you think your team will be able to send a PR for the frontend?

@cgeorgilakis
Copy link
Contributor

@cgeorgilakis The changes to the rest endpoint have been merged, so it is already possible to rework the console to invoke the endpoint and fetch linked/unlinked idps independently in paginated fashion. Do you think your team will be able to send a PR for the frontend?

For sure. I believe my colleague will succeed to submit the PR next week.

@sguilhen
Copy link
Contributor

@cgeorgilakis Let me know if this is something you guys can deliver by the end of the week (in time for proper reviews before 26 is out) or if you need the Keycloak team to take this.

@cgeorgilakis
Copy link
Contributor

cgeorgilakis commented Sep 11, 2024

@cgeorgilakis Let me know if this is something you guys can deliver by the end of the week (in time for proper reviews before 26 is out) or if you need the Keycloak team to take this.

@sguilhen My colleague @linathedog will sumbit the PR until Friday.

@sguilhen
Copy link
Contributor

Excellent, thank you!

linathedog added a commit to eosc-kc/keycloak that referenced this issue Sep 13, 2024
Closes keycloak#21261

Signed-off-by: Andreas Kozadinos <koza-sparrow@hotmail.com>
@linathedog
Copy link
Contributor

@sguilhen Hello, i submitted the PR containing the UI changes to add pagination when displaying Identity Providers in Linked Accounts page on the account console.

@sguilhen
Copy link
Contributor

Hello @linathedog ! Thank you very much for the effort you and your team have put into it. I'll start chasing the necessary reviews!

@sguilhen sguilhen self-assigned this Sep 13, 2024
edewit added a commit to edewit/keycloak that referenced this issue Sep 17, 2024
in favour of: keycloak#32913
fixes: keycloak#21261

Co-authored-by: Andreas Kozadinos <koza-sparrow@hotmail.com>
Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
@edewit edewit linked a pull request Sep 17, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/enhancement Categorizes a PR related to an enhancement team/core-iam
Projects
None yet
5 participants