auth0 / auth0-java

Java client library for the Auth0 platform
https://auth0.com
MIT License
286 stars 131 forks source link

Allow exportUsers to select all users by omitting connection_id #530

Closed radhikalism closed 1 year ago

radhikalism commented 1 year ago

Describe the problem you'd like to have solved

JobsEntity.exportUsers(String connectionId, UsersExportFilter filter) requires a non-null connection ID argument, and can only create jobs to export subsets from a given connection.

But /api/v2/jobs/users-export in Auth0 treats connection_id as optional, such that omitting it exports all users.

So JobsEntity.exportUsers cannot create a job to export all users although the remote API supports it.

Also, the interaction between the mandatory connectionId parameter and the UsersExportFilter member for connection_id is somewhat confusing (i.e. that the filter's attribute overrides the mandatory argument, so there are two interfering ways to specify a connection ID).

Describe the ideal solution

A single-arity JobsEntity.exportUsers(UsersExportFilter filter) method could be added, which would skip the connection_id field in the request body, whenever it was omitted from the export filter.

So when no connection_id is given in the filter, the new exportUsers will export all users. When connection_id is given in the filter, it will select users by connection as usual (without any confusion with any other arguments).

Hypothetical example to select from all connections:

JobsEntity jobs = mgmt.jobs();
UsersExportFilter filter = new UsersExportFilter().withLimit(100);
Job job = jobs.exportUsers(filter).execute(),getBody(); // no connection ID, just select users from any connections

Hypothetical example to select from one connection:

JobsEntity jobs = mgmt.jobs();
UsersExportFilter filter = new UsersExportFilter().withLimit(100).withConnectionId("XXXXX"); // choose a connection in a single place
Job job = jobs.exportUsers(filter).execute(),getBody(); // connection ID given only in the filter

Alternatives and current work-arounds

  1. Workaround: one option is to instantiate a placeholder exportUsers request and manually generate a new request body to reset into the request with setBody. This is clumsy but proves the concept:
    JobsEntity jobs = mgmt.jobs();
    UsersExportFilter filter = new UsersExportFilter().withLimit(100);
    Map<String, Object> requestBody = new HashMap<>();
    requestBody.putAll(filter.getAsMap());
    Job job = jobs.exportUsers("", null) // make a placeholder request
    .setBody(requestBody) // replace its body with filter properties alone
    .execute(),getBody();
  2. Alternative implementation: the existing exportUsers(String connectionId, UsersExportsFilter f) method could be modified to start accepting a null connectionId, in which case it would skip adding that field to the request. Hypothetically:
    JobsEntity jobs = mgmt.jobs();
    UsersExportFilter filter = new UsersExportFilter().withLimit(100);
    Job job = jobs.exportUsers(null, filter).execute(),getBody(); // imply that connection_id should be skipped

Additional information, if any

None.

jimmyjames commented 1 year ago

Thanks for the info @radhikalism and suggested fix! I think your proposed solution makes sense, if the connection_id is not required by the API than it should not be required by the SDK. We could deprecate the existing method in favor of the new method, and just delegate to it. I'll put it in our backlog, but if you're interested in making a PR before we pick it up would be happy to review. Thanks again!

jimmyjames commented 1 year ago

Fixed with #538. Will get a release out with this fix this week. Thanks!