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

Add support for parametrized @Query #453

Open
chess-levin opened this issue Nov 22, 2023 · 4 comments · May be fixed by #505
Open

Add support for parametrized @Query #453

chess-levin opened this issue Nov 22, 2023 · 4 comments · May be fixed by #505
Assignees
Labels
type: enhancement A general enhancement

Comments

@chess-levin
Copy link

chess-levin commented Nov 22, 2023

I'm trying to build a filter using @Query in my LdapRepository class that uses a parameter and the parameter most likely contains '*'.

The queries are successful when using a parameter cn without wildcard '*'. I'm expecting one entry and I' getting one result. Log output:

finalFilter=(&(&(objectclass=top)(objectclass=group))(cn=us_dbl_ci_user_grp))

When trying to add '*' to query-parameter cn the result is always empty. Log output:

finalFilter=(&(&(objectclass=top)(objectclass=group))(cn=us_ci_\2a))

@Repository
public interface GroupRepository extends LdapRepository<LdapGroup> {

    @Query( base = "OU=jenkins,OU=gruppen,OU=MYORG", searchScope = SearchScope.SUBTREE, value = "(cn={0})")
    List<LdapGroup> suchDistinguishedNameJenkins(String cn);

    @Query( base = "OU=itsqs,OU=gruppen,OU=MYORG", searchScope = SearchScope.SUBTREE, value = "(cn={0})")
    List<LdapGroup> suchDistinguishedNameItsqs(String cn);
}
@Entry(base="OU=gruppen,OU=MYORG", objectClasses = {"top", "group"})
final public class LdapGroup {

    @JsonIgnore
    @Id
    private Name id;

    @Attribute(name = "distinguishedName")
    private String distinguishedName;

    @Attribute(name = "cn")
    private String cn;

    @Attribute(name = "name")
    private String name;

    @Attribute(name="member")
    private List<String> members;

    public LdapGroup() {}
}

Is this behavior intended, is it a bug or am I doing something wrong?

Just in case I'm trying to explain what I try to achieve with my code:

My main goal is to narrow down the ldap base for this to different queries.

I set the ldap base in my entry class to the upper 'folder' in the ldap hierarchy.

@Entry(base="OU=gruppen,OU=MYORG", objectClasses = {"top", "group"})

Because this path contains >1000 subfolders and because I know exactly which subfolder I want to query, I narrow it down when I define the @Query (btw: it would be great to use params like {1} for base as well)

@Query( base = "OU=jenkins,OU=gruppen,OU=MYORG", searchScope = SearchScope.SUBTREE, value = "(cn={0})")

@Query( base = "OU=itsqs,OU=gruppen,OU=MYORG", searchScope = SearchScope.SUBTREE, value = "(cn={0})")

If I'm on the wrong path, please give me some advise, how to do this query the correct way. THX

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Nov 22, 2023
@mp911de mp911de added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged labels Nov 23, 2023
@mp911de mp911de changed the title Wildcards in @Query not working Add support for parametrized @Query Nov 23, 2023
@mp911de
Copy link
Member

mp911de commented Nov 23, 2023

Parameters from the method call aren't incorporated in @Query. Typically, we support named (:myParam) or indexed (?0, ?1, …) parameters and we should extend annotated query methods to pick up parameters.

Also, adding SpEL support would make sense as well.

@mp911de mp911de self-assigned this Nov 23, 2023
@chess-levin
Copy link
Author

chess-levin commented Nov 24, 2023

I wrote my own repository class to be able to individually change the base on each query. Is there a way to write the objectClass check in a shorter way? e.g. where("objectClass").in("top,group")

@Repository
public class MyGroupRepo {

    @Autowired
    private LdapTemplate ldapTemplate;

    public List<LdapGroup> findByCnInGroup(String cnFilter, Name groupName) {
        LdapQuery query = query().searchScope(SearchScope.SUBTREE)
                .base(groupName)
                .where("objectclass").is("top")
                .and("objectclass").is("group")
                .and("cn").like(cnFilter);

        return ldapTemplate.find(query, LdapGroup.class);
    }
}

@mp911de As I wrote in my 1st post. It is possible pass a numbered parameter into value argument with {0}, but there are no wildcards allowed.

@mp911de
Copy link
Member

mp911de commented Nov 27, 2023

It is possible pass a numbered parameter into value argument with {0}, but there are no wildcards allowed.

It's not supported reliably. Parameter evaluation happens in Spring LDAP's org.springframework.ldap.query.LdapQueryBuilder and only for the filter part. It's not supported for base.

Parameters are encoded using LdapEncoder.filterEncode.

System.out.println(LdapEncoder.filterEncode("*"));

produces:

\2a

@mp911de
Copy link
Member

mp911de commented Oct 14, 2024

We want to extend parametrization capabilities by allowing:

  • Binding of named parameters (and indexed parameters) (@Query(value = "(cn=?0)", @Query( value = "(cn=:lastname)")
  • Binding of SpEL expressions and property placeholders (@Query(value = "(cn=:#{…})"), @Query( value = "(cn=:${…})"))
  • Support parameter binding in value and base

The previous form of {some-number} remains active while we would consider it outdated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants