jose azevedo
jose azevedo

Reputation: 245

Return ldap entries on paginated form in springboot

I have a ldap method that returns all users that are in it (almost 1300 users) and I want to return them by page, similar to what PagingAndSortingRepository does in Springboot:

If I have this endpoint ( users/?page=0&size=1 )and I wnat to return on page 0 just 1 entry.

Is there any way to do that?

Currently I have this but it doesn´t work:

SearchRequest searchRequest = new SearchRequest(ldapConfig.getBaseDn(), SearchScope.SUB,
                Filter.createEqualityFilter("objectClass", "person"));
        ASN1OctetString resumeCookie = null;
        while (true) {
            searchRequest.setControls(new SimplePagedResultsControl(pageable.getPageSize(), resumeCookie));
            SearchResult searchResult = ldapConnection.search(searchRequest);
            numSearches++;
            totalEntriesReturned += searchResult.getEntryCount();
            for (SearchResultEntry e : searchResult.getSearchEntries()) {

                 String[] completeDN = UaaUtils.searchCnInDn(e.getDN());
                 String[] username = completeDN[0].split("=");
                 UserEntity u = new UserEntity(username[1]);
                 list.add(u);

                System.out.println("TESTE");
            }

            SimplePagedResultsControl responseControl = SimplePagedResultsControl.get(searchResult);
            if (responseControl.moreResultsToReturn()) {
                // The resume cookie can be included in the simple paged results
                // control included in the next search to get the next page of results.
                System.out.println("Antes "+resumeCookie);
                resumeCookie = responseControl.getCookie();
                System.out.println("Depois "+resumeCookie);
            } else {
                break;
            }

            Page<UserEntity> newPage = new PageImpl<>(list, pageable, totalEntriesReturned);

            System.out.println("content " + newPage.getContent());
            System.out.println("total elements " + newPage.getTotalElements());

            System.out.println(totalEntriesReturned);
        }

Upvotes: 1

Views: 2011

Answers (1)

Jeremy Jenkins
Jeremy Jenkins

Reputation: 11

I'm unsure if this is the proper way, but here's how I went about it:

public PaginatedLookup getAll(String page, String perPage) {
  PagedResultsCookie cookie = null;
  List<LdapUser> results;

  try {
      if ( page != null ) {
          cookie = new PagedResultsCookie(Hex.decode(page));
      } // end if

      Integer pageSize = perPage != null ? Integer.parseInt(perPage) : PROCESSOR_PAGE_SIZE;

      PagedResultsDirContextProcessor processor = new PagedResultsDirContextProcessor(pageSize, cookie);
      LdapName base = LdapUtils.emptyLdapName();

      SearchControls sc = new SearchControls();
      sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
      sc.setTimeLimit(THREE_SECONDS);
      sc.setCountLimit(pageSize);
      sc.setReturningAttributes(new String[]{"cn", "title"});

      results = ldapTemplate.search(base, filter.encode(), sc, new PersonAttributesMapper(), processor);

      cookie = processor.getCookie();
  } catch ( Exception e ) {
      log.error(e.getMessage());
      return null;
  } // end try-catch

  String nextPage = null;

  if ( cookie != null && cookie.getCookie() != null ) {
      nextPage = new String(Hex.encode(cookie.getCookie()));
  } // end if
  return new PaginatedLookup(nextPage, results);
}

The main issue I kept on hitting was trying to get the cookie as something that could be sent to the client, which is where my Hex.decode and Hex.encode came in handy. PersonAttributesMapper is a private mapper that I have to make the fields more human readable, and PaginatedLookup is a custom class I use for API responses.

Upvotes: 1

Related Questions