Skip to content

Conversation

ritankarsaha
Copy link
Contributor

@ritankarsaha ritankarsaha commented Jul 18, 2025

Summary

Added the API Endpoint for importing users via a .csv file.

Fixes #3190

Suggest Reviewer

@GMishx
@amritkv
@rudra-superrr

How To Test?

image The new API Endpoint. - you can check via swagger UI or by passing a sample .csv file from your local system. - you can use the curl command
ritankar@ritankar-Victus-by-HP-Gaming-Laptop-15-fa1xxx:~$ curl -X 'POST' \
  'http://127.0.0.1:8080/resource/api/importExport/uploadUsers' \
  -H 'accept: application/json' \
  -H 'Authorization: Basic YWRtaW5Ac3czNjAub3JnOjEyMzQ1' \
  -H 'Content-Type: multipart/form-data' \
  -F 'usersFile=@/home/ritankar/Desktop/test-users.csv'
{
  "requestStatus" : "SUCCESS",
  "totalAffectedElements" : 3,
  "totalElements" : 3,
  "message" : "Successfully imported 3 users",
  "setTotalAffectedElements" : true,
  "setTotalElements" : true,
  "setMessage" : true,
  "setRequestStatus" : true
}

Added the response from the curl command above.

image

New Users imported via the csv properly.

{
  "_id": "5343fe0506666c2c2f394c4d8a0011a6",
  "_rev": "1-fb5349824bcb6ec2848326b1b0b8aa11",
  "givenname": "Jane",
  "wantsMailNotification": false,
  "issetBitfield": "1",
  "fullname": "Jane Smith",
  "type": "user",
  "department": "QA",
  "userGroup": "ADMIN",
  "email": "[email protected]",
  "deactivated": false,
  "lastname": "Smith"
}

Example of one.

Fixes #3190

Checklist

Must:

  • All related issues are referenced in commit messages and in PR

P.S. - I didn't add the test file for this, should I do that as well ?

@GMishx GMishx added needs code review needs general test This is general testing, meaning that there is no org specific issue to check for labels Jul 20, 2025
Copy link
Member

@GMishx GMishx left a comment

Choose a reason for hiding this comment

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

I would request you to look into the old code how this request was handled by the Liferay portlet. We can copy most of the code in the service class here.

References:

  • public void updateUsers(ActionRequest request, ActionResponse response) throws IOException {
    List<UserCSV> users = getUsersFromRequest(request, "file");
    try {
    createOrganizations(request, users);
    } catch (SystemException | PortalException e) {
    log.error("Error creating organizations", e);
    }
    for (UserCSV user : users) {
    dealWithUser(request, user);
    }
    }
  • private User dealWithUser(PortletRequest request, UserCSV userRec) {
    User user = null;
    try {
    user = userRec.addLifeRayUser(request);
    if (user != null) {
    UserUtils.synchronizeUserWithDatabase(userRec, thriftClients, userRec::getEmail, userRec::getGid, UserUtils::fillThriftUserFromUserCSV);
    }
    } catch (SystemException | PortalException e) {
    log.error("Error creating a new user", e);
    }
    return user;
    }
  • public static <T> org.eclipse.sw360.datahandler.thrift.users.User synchronizeUserWithDatabase(
    T source, ThriftClients thriftClients, Supplier<String> emailSupplier,
    Supplier<String> extIdSupplier, BiConsumer<org.eclipse.sw360.datahandler.thrift.users.User, T> synchronizer) {
    UserService.Iface client = thriftClients.makeUserClient();
    org.eclipse.sw360.datahandler.thrift.users.User existingThriftUser = null;
    String email = emailSupplier.get();
    try {
    existingThriftUser = client.getByEmailOrExternalId(email, extIdSupplier.get());
    } catch (TException e) {
    //This occurs for every new user, so there is not necessarily something wrong
    log.trace("User not found by email or external ID");
    }
    org.eclipse.sw360.datahandler.thrift.users.User resultUser = null;
    try {
    if (existingThriftUser == null) {
    log.info("Creating new user.");
    resultUser = new org.eclipse.sw360.datahandler.thrift.users.User();
    synchronizer.accept(resultUser, source);
    client.addUser(resultUser);
    } else {
    resultUser = existingThriftUser;
    if (!existingThriftUser.getEmail().equals(email)) { // email has changed
    resultUser.setFormerEmailAddresses(prepareFormerEmailAddresses(existingThriftUser, email));
    }
    synchronizer.accept(resultUser, source);
    client.updateUser(resultUser);
    }
    } catch (TException e) {
    log.error("Thrift exception when saving the user", e);
    }
    return resultUser;
    }

}

RequestSummary requestSummary = new RequestSummary();
requestSummary.setRequestStatus(org.eclipse.sw360.datahandler.thrift.RequestStatus.SUCCESS);
Copy link
Member

Choose a reason for hiding this comment

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

Why not import the name and simplify the usage?

return requestSummary;
}

if (file.getSize() > 10 * 1024 * 1024) { // 10MB limit
Copy link
Member

Choose a reason for hiding this comment

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

Why an arbitrary value which is not defined anywhere else?

Comment on lines +492 to +503
if (givenName.length() > 100) {
throw new IllegalArgumentException("GivenName too long (max 100 characters): " + givenName);
}
if (lastName.length() > 100) {
throw new IllegalArgumentException("Lastname too long (max 100 characters): " + lastName);
}
if (email.length() > 255) {
throw new IllegalArgumentException("Email too long (max 255 characters): " + email);
}
if (department.length() > 255) {
throw new IllegalArgumentException("Department too long (max 255 characters): " + department);
}
Copy link
Member

Choose a reason for hiding this comment

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

Same here, the restrictions are not defined anywhere else but here.

@GMishx
Copy link
Member

GMishx commented Sep 12, 2025

Hello @ritankarsaha , do you have any update on the same?

@ritankarsaha
Copy link
Contributor Author

Hello @ritankarsaha , do you have any update on the same?

yes yes, doing this one after testing and pushing the 4th pr for fossology integration and deleting stuff from the 2nd pr.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs code review needs general test This is general testing, meaning that there is no org specific issue to check for

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Admin: Users: Import Users

2 participants