Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

User account mapping #140

Merged
merged 5 commits into from
Dec 8, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions tfs/src/main/java/hudson/plugins/tfs/TeamPluginGlobalConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import hudson.Extension;
import hudson.ExtensionList;
import hudson.plugins.tfs.model.DomainUserAccountMapper;
import hudson.plugins.tfs.model.UserAccountMapper;
import hudson.plugins.tfs.model.UserAccountMapperDescriptor;
import jenkins.model.GlobalConfiguration;
import jenkins.model.Jenkins;
import net.sf.json.JSONObject;
Expand All @@ -27,6 +30,7 @@ public class TeamPluginGlobalConfig extends GlobalConfiguration {
private boolean configFolderPerNode;
private boolean enableTeamPushTriggerForAllJobs;
private boolean enableTeamStatusForAllJobs;
private UserAccountMapper userAccountMapper;

public TeamPluginGlobalConfig() {
this(true);
Expand Down Expand Up @@ -84,6 +88,21 @@ public void setEnableTeamStatusForAllJobs(final boolean enableTeamStatusForAllJo
this.enableTeamStatusForAllJobs = enableTeamStatusForAllJobs;
}

public UserAccountMapper getUserAccountMapper() {
if (userAccountMapper == null) {
userAccountMapper = new DomainUserAccountMapper();
}
return userAccountMapper;
}

public void setUserAccountMapper(UserAccountMapper userAccountMapper) {
this.userAccountMapper = userAccountMapper;
}

public List<UserAccountMapperDescriptor> getUserAccountMapperDescriptors() {
return UserAccountMapper.all();
}

@Override
public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package hudson.plugins.tfs.model;

import hudson.Extension;
import org.kohsuke.stapler.DataBoundConstructor;

public class AliasOnlyUserAccountMapper extends UserAccountMapper {
private static final long serialVersionUID = 1L;

@DataBoundConstructor
public AliasOnlyUserAccountMapper() {

}

@Override
public String mapUserAccount(final String input) {
final String[] split = input.split("\\\\");
final String result;
if (split.length == 2) {
result = split[1];
} else {
result = input;
}
return result;
}

@Extension
public static final class DescriptorImpl extends UserAccountMapperDescriptor {
@Override
public String getDisplayName() {
return "Resolve user using 'alias' only, removing 'DOMAIN\\'";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package hudson.plugins.tfs.model;

import hudson.Extension;
import org.kohsuke.stapler.DataBoundConstructor;

public class DomainUserAccountMapper extends UserAccountMapper {
private static final long serialVersionUID = 1L;

@DataBoundConstructor
public DomainUserAccountMapper() {

}

@Override
public String mapUserAccount(final String input) {
return input;
}

@Extension
public static final class DescriptorImpl extends UserAccountMapperDescriptor {
@Override
public String getDisplayName() {
return "Resolve user using 'DOMAIN\\alias'";
}
}
}
5 changes: 4 additions & 1 deletion tfs/src/main/java/hudson/plugins/tfs/model/Project.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.microsoft.tfs.core.clients.versioncontrol.specs.version.LatestVersionSpec;
import hudson.model.User;
import hudson.plugins.tfs.TeamPluginGlobalConfig;
import hudson.plugins.tfs.commands.GetFilesToWorkFolderCommand;
import hudson.plugins.tfs.commands.RemoteChangesetVersionCommand;
import hudson.plugins.tfs.model.ChangeSet.Item;
Expand Down Expand Up @@ -110,7 +111,9 @@ public UserLookup getOrCreateUserLookup() {
synchronized (this) {
if (userLookup == null) {
final IIdentityManagementService ims = server.createIdentityManagementService();
userLookup = new TfsUserLookup(ims);
final TeamPluginGlobalConfig teamPluginGlobalConfig = TeamPluginGlobalConfig.get();
final UserAccountMapper mapper = teamPluginGlobalConfig.getUserAccountMapper();
userLookup = new TfsUserLookup(ims, mapper);
}
}
}
Expand Down
12 changes: 8 additions & 4 deletions tfs/src/main/java/hudson/plugins/tfs/model/TfsUserLookup.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package hudson.plugins.tfs.model;

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.microsoft.tfs.core.clients.webservices.IIdentityManagementService;
Expand All @@ -17,17 +18,20 @@ public class TfsUserLookup implements UserLookup {
private static final Logger LOGGER = Logger.getLogger(TfsUserLookup.class.getName());

private final IIdentityManagementService ims;

public TfsUserLookup(IIdentityManagementService ims) {
private final UserAccountMapper userAccountMapper;

public TfsUserLookup(final IIdentityManagementService ims, final UserAccountMapper userAccountMapper) {
this.ims = ims;
this.userAccountMapper = userAccountMapper;
}

/**
* @param accountName Windows NT account name: domain\alias.
*/
public User find(String accountName) {
LOGGER.fine("Looking up Jenkins user for account '%s'.");
final User jenkinsUser = User.get(accountName);
final String mappedAccountName = userAccountMapper.mapUserAccount(accountName);
LOGGER.log(Level.FINE, "Looking up Jenkins user for account '%s'.", mappedAccountName);
final User jenkinsUser = User.get(mappedAccountName);
Mailer.UserProperty mailerProperty = jenkinsUser.getProperty(Mailer.UserProperty.class);
if (mailerProperty == null || mailerProperty.getAddress() == null || mailerProperty.getAddress().length() == 0) {
final TeamFoundationIdentity tfsUser = ims.readIdentity(
Expand Down
28 changes: 28 additions & 0 deletions tfs/src/main/java/hudson/plugins/tfs/model/UserAccountMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package hudson.plugins.tfs.model;

import hudson.DescriptorExtensionList;
import hudson.ExtensionPoint;
import hudson.model.Describable;
import jenkins.model.Jenkins;

import java.io.Serializable;

public abstract class UserAccountMapper implements ExtensionPoint, Describable<UserAccountMapper>, Serializable {
private static final long serialVersionUID = 1L;

public final String getDisplayName() {
return getDescriptor().getDisplayName();
}

public UserAccountMapperDescriptor getDescriptor() {
final Jenkins jenkins = Jenkins.getInstance();
return (UserAccountMapperDescriptor) jenkins.getDescriptorOrDie(getClass());
}

public abstract String mapUserAccount(final String input);

public static DescriptorExtensionList<UserAccountMapper, UserAccountMapperDescriptor> all() {
final Jenkins jenkins = Jenkins.getInstance();
return jenkins.getDescriptorList(UserAccountMapper.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package hudson.plugins.tfs.model;

import hudson.model.Descriptor;

public abstract class UserAccountMapperDescriptor extends Descriptor<UserAccountMapper> {
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ f.section(title: descriptor.displayName) {
description: "Turning this on is equivalent to adding the 'Set build pending status in TFS/Team Services' build step and the 'Set build completion status in TFS/Team Services' post-build action to all jobs.") {
f.checkbox (default: false)
}
f.entry() {
f.dropdownDescriptorSelector(
title: _("User account name mapping strategy"),
field: "userAccountMapper",
descriptors: descriptor.getUserAccountMapperDescriptors()
)
}
f.advanced() {
f.entry(title: _("Store TFVC configuration in computer-specific folders"),
field: "configFolderPerNode",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div>
<p>
When interpreting changesets from TFVC, the TFS plugin will attempt to map domain accounts (i.e. <code>DOMAIN\alias</code>) to Jenkins accounts.
</p>
<p>
The default mapping strategy (<b>Resolve user using 'DOMAIN\alias'</b>) is to provide the string (received from TFVC) as-is to Jenkins, which causes Jenkins to convert the username from <code>DOMAIN\alias</code> to <code>DOMAIN_alias</code>. If your Jenkins users are named with a different convention, try another user mapping strategy.
</p>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
package hudson.plugins.tfs.model.AliasOnlyUserAccountMapper

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
package hudson.plugins.tfs.model.DomainUserAccountMapper