TFS 2010 - Build Security API
I had a request recently on how to “Secure” a build from code. While I am still not sure there is a great way to do that. What I found is that there is next to no information on the TFS Security API. So, I thought I would post this code here as an example of using the Security API. Note that this example is specific to Build, but the security API is for TFS in general.
So, in this example we want to “deny” contributors from being able to Edit builds for a particular definition. In the UI, you would simply right click the definition, choose Security, select the Contributors group, and click the checkbox in the Deny column for the “Edit build quality” permission.
In code this looks like this:
using System;
using Microsoft.TeamFoundation;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Build.Common;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.Framework.Common;
using Microsoft.TeamFoundation.Server;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// Remove the ability for a user to modify a build
TfsTeamProjectCollection collection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(
new Uri("https://jpricket-test:8080/tfs/defaultcollection"));
IBuildServer buildServer = collection.GetService<IBuildServer>();
ISecurityService securityService = collection.GetService<ISecurityService>();
ICommonStructureService cssService = collection.GetService<ICommonStructureService>();
IIdentityManagementService imService = collection.GetService<IIdentityManagementService>();
String teamProject = "jpricket-071410";
String definitionName = "New Build Definition 1";
String buildNumber = "New Build Definition 1_20100714.3";
String groupName = @"[jpricket-071410]\Contributors";
IBuildDetail build = buildServer.GetBuild(
buildServer.CreateBuildDefinitionSpec(teamProject, definitionName),
buildNumber, null, QueryOptions.Definitions);
// Read the group represnting the root node
TeamFoundationIdentity groupIdentity = imService.ReadIdentity(
IdentitySearchFactor.AccountName, groupName,
MembershipQuery.Direct, ReadIdentityOptions.None);
SecureBuild(build, groupIdentity, securityService, cssService);
Console.WriteLine("Build {0} secured.", build.BuildNumber);
}
static void SecureBuild(IBuildDetail build, TeamFoundationIdentity groupIdentity,
ISecurityService securityService, ICommonStructureService cssService)
{
SecurityNamespace buildSecurity = securityService.GetSecurityNamespace(
BuildSecurity.BuildNamespaceId);
// Check for null
// (build security would only be null if we are talking to an older server)
if (buildSecurity != null)
{
// Team project level permissions use this token
// (these permissions are found on the Security menu off the Builds node in Team Explorer)
String tokenTeamProject = LinkingUtilities.DecodeUri(
cssService.GetProjectFromName(build.TeamProject).Uri).ToolSpecificId;
// Definition level permissions use this token (Security menu on a BuildDefinition in Team Explorer)
String tokenDefinition =
tokenTeamProject +
BuildSecurity.NamespaceSeparator +
LinkingUtilities.DecodeUri(build.BuildDefinition.Uri.AbsoluteUri).ToolSpecificId;
buildSecurity.SetPermissions(
tokenDefinition, groupIdentity.Descriptor, 0,
BuildPermissions.EditBuildQuality, true);
}
}
}
}
I hope this sample leads to more samples – Code On!
Comments
Anonymous
July 07, 2011
I notice how you build the token definitions for both the team project level and definition level permissions. Is there more references you could point me to that would show me how to build tokens for other levels of permissions?Anonymous
August 14, 2012
Thanks - very helpful :)Anonymous
November 06, 2013
This was very helpful, got the ball rolling for me to be able to create powershell script to re-point all Build Definitions and their Builds to a new Drop Location as we had to move our Drop Location store to a new NAS drive.