package jetbrains.buildServer.vcsUsersSync; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.text.StringUtil; import java.util.Collection; import jetbrains.buildServer.serverSide.SProject; import jetbrains.buildServer.serverSide.auth.Role; import jetbrains.buildServer.serverSide.auth.RoleScope; import jetbrains.buildServer.serverSide.auth.RolesManager; import jetbrains.buildServer.serverSide.impl.LogUtil; import jetbrains.buildServer.users.PropertyKey; import jetbrains.buildServer.users.SUser; import jetbrains.buildServer.users.SimplePropertyKey; import jetbrains.buildServer.users.UserModel; import jetbrains.buildServer.vcs.SVcsModification; import jetbrains.buildServer.vcs.VcsModification; import jetbrains.buildServer.vcs.VcsRoot; /** * @author Yegor.Yarko * Date: 25.09.12 */ public class UserSynchronizer { final static Logger LOG = Logger.getInstance(UserSynchronizer.class.getName()); private static final PropertyKey USERNAME_USER_PROPERTY = new SimplePropertyKey("vcsUsersSync.generatedUser"); private VcsUserSynchronizerOptions myOptions; private UserModel myUserModel; private RolesManager myRolesManager; public UserSynchronizer(VcsUserSynchronizerOptions options, final UserModel userModel, final RolesManager rolesManager) { myOptions = options; myUserModel = userModel; myRolesManager = rolesManager; } public void processChange(final VcsModification modification, final VcsRoot root) { LOG.debug("Processing change: " + modification.toString()); final String vcsUsername = modification.getUserName(); SUser teamCityUser = findTeamCityUser(vcsUsername); if (teamCityUser == null) { if (myOptions.isCreateUsers()) { try { teamCityUser = createUser(vcsUsername); LOG.info("Created TeamCity user " + LogUtil.describe(teamCityUser) + " based on VCS username '" + vcsUsername + "'"); } catch (Exception e) { LOG.error("Error creating user for VCS username '" + vcsUsername + "': " + e.toString()); LOG.debug("Error creating user for VCS username '" + vcsUsername + "': " + e.toString(), e); } } else { LOG.debug("No TeamCity user exists for VCS username '" + vcsUsername + "', but users creation is disabled, ignoring the change."); return; } } UserSynchronizerRolesMode rolesMode = myOptions.getAddRolesMode(); if (rolesMode == null || rolesMode.equals(UserSynchronizerRolesMode.DISABLED)) { LOG.debug("Found TeamCity user for VCS username " + vcsUsername + ", but user roles addition is disabled, adding no roles."); return; } if (rolesMode.equals(UserSynchronizerRolesMode.ONLY_FOR_CREATED_USERS)) { if (!isGeneratedUser(teamCityUser)) { LOG.debug( "TeamCity user found but it was not created by the plugin, skipping roles assignment as it is configured to affect only earlier created users."); return; } } else { if (!rolesMode.equals(UserSynchronizerRolesMode.ALL_USERS)) { LOG.error("Unknown role synchronization option."); return; } } addRoles(teamCityUser, getProjects(modification)); } private void addRoles(final SUser teamCityUser, final Collection projects) { for (SProject project : projects) { final String roleId = myOptions.getRoleId(); final Role role = myRolesManager.findRoleById(roleId); if (role == null) { LOG.warn("Cannot find role by configured role id '" + roleId + "'. Check the settings. Adding no roles to TeamCity user " + LogUtil.describe(teamCityUser)); return; } final RoleScope projectScope = RoleScope.projectScope(project.getProjectId()); final Collection existingRoles = teamCityUser.getRolesWithScope(projectScope); if (!existingRoles.contains(role)) { teamCityUser.addRole(projectScope, role); LOG.info( "Added role '" + role.getName() + "' for project " + LogUtil.describe(project) + " to user " + LogUtil.describe(teamCityUser)); } else { LOG.debug("Role '" + role.getName() + "' for project " + LogUtil.describe(project) + " already granted for user " + LogUtil.describe(teamCityUser)); } } } private Collection getProjects(final VcsModification modification) { return ((SVcsModification)modification).getRelatedProjects(); //todo: open API issues } private boolean isGeneratedUser(final SUser teamCityUser) { return StringUtil.isNotEmpty(teamCityUser.getPropertyValue(USERNAME_USER_PROPERTY)); } private void markUserAsGenerated(final SUser teamCityUser) { teamCityUser.setUserProperty(USERNAME_USER_PROPERTY, teamCityUser.getUsername()); } private SUser createUser(final String vcsUsername) { //todo: might need permissions checking final SUser user = myUserModel.createUserAccount(null, getTeamCityUsernameFromVcsUsername(vcsUsername)); markUserAsGenerated(user); // setVCSUsername(user, vcsUsername); //todo user.updateUserAccount(user.getUsername(), user.getName(), getEmail(vcsUsername)); return user; } private String getEmail(final String vcsUsername) { final String emailDomain = myOptions.getEmailDomain(); if (StringUtil.isEmpty(emailDomain)) { return null; } return vcsUsername + "@" + emailDomain; } private String getTeamCityUsernameFromVcsUsername(final String vcsUsername) { return vcsUsername; } private SUser findTeamCityUser(final String vcsUsername) { return myUserModel.findUserAccount(null, getTeamCityUsernameFromVcsUsername(vcsUsername)); } }