How to create a user with CrowdService?

Gary Weaver
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
June 13, 2011

Have the following:

import com.atlassian.confluence.user.UserAccessor;
import com.atlassian.crowd.embedded.api.CrowdDirectoryService;
import com.atlassian.crowd.embedded.api.CrowdService;
import com.atlassian.crowd.embedded.api.Directory;
import com.atlassian.crowd.embedded.api.OperationType;
import com.atlassian.crowd.embedded.impl.ImmutableUser;
import com.atlassian.user.User;
...
private Long findFirstWritableDirectoryId() {
List<Directory> directories = crowdDirectoryService.findAllDirectories();
for (int i=0; i<directories.size(); i++) {
Directory directory = directories.get(i);
if (directory!=null) {
boolean writable = false;
Set allowedOperations = directory.getAllowedOperations();
Iterator iter = allowedOperations.iterator();
while(iter.hasNext()) {
OperationType operationType = (OperationType)iter.next();
if (operationType == OperationType.CREATE_USER) {
writable = true;
return directory.getId();
}
}
}
}
return null;
}

public User addUser(String userName, String email, String fullName) {
User user = null;
try {
ImmutableUser.Builder userBuilder = new ImmutableUser.Builder();
userBuilder.active(true);
userBuilder.directoryId(findFirstWritableDirectoryId());
userBuilder.displayName(fullName);
userBuilder.emailAddress(email);
userBuilder.name(userName);
com.atlassian.crowd.embedded.api.User cUser = userBuilder.toUser();
String credential = null;
cUser = crowdService.addUser(cUser, credential);
user = userAccessor.getUser(cUser.getName());
} catch (Throwable t) {
log.error("Problem creating user '" + userName + "'", t);
}
return user;
}

But, during upload of the Confluence plugin using that in Confluence 3.5.5, it fails with the following:

ClassNotFoundException: com.atlassian.crowd.embedded.impl.ImmutableUser$Builder

The reason that I'm using userAccessor at the end is because most of my code and GroupManager, etc. requires com.atlassian.user.User.

Any idea how to create a user using the Confluence API or embedded Crowd API in Confluence 3.5.5? If interested, the latest version of plugin code is here.

2 answers

1 accepted

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

2 votes
Answer accepted
Stefan Kohler
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
June 16, 2011

Need some more work, but bassicaly it should come to this. Not sure if the permission check is ignored now though ;-)

Also added a check if the current confluence instance is licensed to add more user, seems right!

public User addUser(String username, String email, String fullname) {
if (userAccessor.isLicensedToAddMoreUsers()) {
DefaultUser user = new DefaultUser(username, fullname, email);
User user = createUser(user, createRandomCredential());

personalInformationManager.createPersonalInformation(user);
userChecker.incrementRegisteredUserCount();
eventManager.publishEvent(new UserCreateEvent(this, user));
return user;
} else {
throw new LicensingException("You are not licensed to add any more users to this installation of Confluence. Please contact sales@atlassian.com");
}
}

private User createUser(User userTemplate, Credential credential) {
// add check to prevent duplicated UserNames
try {
crowdService.addUser(toUserTemplate(userTemplate), credential.getValue());
} catch (.....) {

}
return Conversions.TO_ATLASSIAN_USER.apply(crowdUser);
}

private Credential createRandomCredential() {
String randomPassword = SecureRandomStringUtils.getInstance().randomAlphanumericString(22);
return Credential.unencrypted(randomPassword);
}


private UserTemplate toUserTemplate(User atlassianUser) {
UserTemplate template = new UserTemplate(atlassianUser.getName());
template.setDisplayName(atlassianUser.getFullName());
template.setEmailAddress(atlassianUser.getEmail());
template.setActive(true);
return template;
}
Gary Weaver
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
June 19, 2011
Thanks, Stefan!
1 vote
Stefan Kohler
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
June 14, 2011

Honestly, I think the 'UserAccessor' takes care of this all (or I misunderstood your problem :-))

I added this to a simple macro and it seemed to work!

public User addUser(String username, String email, String fullname) {
DefaultUser user = new DefaultUser(username, fullname, email);
try {
User user = userAccessor.createUser(user, Credential.NONE);
userAccessor.addMembership(UserAccessor.GROUP_CONFLUENCE_USERS, username);
return user;
}
catch (LicensingException e) {
....
}
catch (InfrastructureException e) {
....
}
}
Stefan Kohler
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
June 14, 2011
I took a deep dive into the source code starting at the 'CreateUserAction' from Confluence all the way down to 'ApplicationServiceGeneric' and there it seemed that all the work of finding a writable directory is done for you :)
Gary Weaver
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
June 14, 2011
Stefan, Thanks! Could you post how to do this with CrowdService though, since you have access, if you can do so without violating terms of use of Confluence/other Atlassian source? UserAccessor checks permissions and the user does not actually have rights to do some actions as a space admin instead of confluence admin, which is why the service and manager classes, which don't check permissions, must be used in some cases. UserManager was used for this before 3.5, but it can no longer be used afaik.
TAGS
AUG Leaders

Atlassian Community Events