Friday, October 4, 2013

TFS API 2013 - check access rights of the user

I've got a task which suppose to be really simple - check if user has an access to delete a build in  a Team project.

Seems to be easy, but no, it showed to be really poorly documented!
Therefore I put my code here, so people can find it and reuse it.

So, at first, we create a collection object, same good old way:

var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("YourCollectionAddress"));

Getting a team project object, good old way:

var versionServer = tfs.GetService<VersionControlServer>();
var teamProject = versionServer.GetAllTeamProjects(false).ToList().First(tp => tp.Name == tpName);

Getting user identity - here comes new - using IIdentityManagementService:

var identityService = tfs.GetService<IIdentityManagementService>();
var userIdentity = identityService.ReadIdentity(IdentitySearchFactor.AccountName, username, MembershipQuery.Expanded, ReadIdentityOptions.None);

Getting SecurityNamespace object for team project - in this object we can see which permissions generally are appliable for the target (in our case - team project). Also new - using ISecurityService (IGroupSecurity is obsolete now):

var ss = (ISecurityService)tfs.GetService(typeof(ISecurityService));
var sn = ss.GetSecurityNamespaces().First(ssn => ssn.Description.Name == "Project");

With a good usage og LINQPad I can check the following access rights for SecurityNamespace for a Team Project:
Ok, so I will check for  UPDATE_BUILD then.

Next step - getting actually access rights list for the user in the Team project:

var securityToken = "$PROJECT:" + teamProject.ArtifactUri;
var access = sn.QueryAccessControlList(securityToken, new List<IdentityDescriptor> {userIdentity.Descriptor}, true);

Almost there!

Now we just need to check if the following access list contains UPDATE_BUILD, either as inhereted or granted directly:

if (access.AccessControlEntries.Any(
      acl => ((acl.ExtendedInfo.EffectiveAllow & 128) == 128 || 
      (acl.ExtendedInfo.InheritedAllow & 128) == 128)))
    return true;
return false;

Hope that helps :)

More information
Those pages helped me a lot, and actually were only info I found about using TFS API for permissions set\check: