0

I'm trying to programmatically retrieve a Team's Administrator Users.

For example in a setup like in the picture how can I get 'Billy' as being the Administrator of Team 'QC Manager'?

I already have the code that gets all users in a Team via IIdentityManagementService's ListApplicationGroups, getting the group using FirstOrDefault ... and then getting its users via ReadIdentities.

TFS Team Administrator setup

riQQ
  • 9,878
  • 7
  • 49
  • 66
siliond
  • 83
  • 9
  • I suspect it is an extended property on the Team's TeamFoundationIdentity, similar to how a Team Image is stored: http://blog.jessehouwing.nl/2013/01/set-your-tfs-profile-or-team-image-from.html – jessehouwing Feb 25 '14 at 16:41
  • Thank you, Jesse. I'm afraid it's going to require some other approach, I queried [Tfs_Configuration].[dbo].[tbl_PropertyDefinition] and while I've found the properties you've accessed to get to the Team's image I could not find anything related to Team's Admins. – siliond Feb 25 '14 at 19:27

2 Answers2

1

I've done some poking around in the Team Web Access assemblies, and this seems to be only available on the server side at the moment (no Rest or Client Object Model option available). The code looks like this:

TeamFoundationIdentity identity;
string token = service.GetSecurableToken(requestContext, teamIdentity.Descriptor, out identity);
AccessControlList list = requestContext.GetService<SecurityService>().QueryAccessControlLists(requestContext, FrameworkSecurity.IdentitiesNamespaceId, token, null, false, false).FirstOrDefault<AccessControlList>();
List<IdentityDescriptor> list2 = new List<IdentityDescriptor>();
if (list != null)
{
    foreach (AccessControlEntry entry in list.AccessControlEntries)
    {
        if ((entry.Allow & 8) == 8)
        {
            list2.Add(entry.Descriptor);
        }
    }
}
return service.ReadIdentities(requestContext, list2.ToArray());

Where GetSecurableToken looks like:

internal static string CreateSecurityToken(TeamFoundationIdentity group)
{
    return (group.GetAttribute(IdentityAttributeTags.LocalScopeId, string.Empty) + FrameworkSecurity.IdentitySecurityPathSeparator + group.TeamFoundationId.ToString());
}

From here you should be able to piece together the code to read and writes these lists. To go poking around yourself, look for the Microsoft.TeamFoundation.Server.Core.dll, Class Microsoft.TeamFoundation.Server.Core.TeamFoundationTeamService to be specific.

If you're able to rewrite it into something useful I'd be grateful and might stick it into the TfsTeamTools, at the moment I don't have much time on my hands to pick this up.

jessehouwing
  • 106,458
  • 22
  • 256
  • 341
  • Jesse, why not simply checking for [PROJECT]\Project Administrators membership? – Giulio Vian Feb 26 '14 at 05:47
  • @GiulioVian Because a Team Administrator is not the same thing as a Project Administrator. – jessehouwing Feb 26 '14 at 09:09
  • Thank you very much, Jesse. I will try to incorporate it and let you know how it went. I'm working on a automatic bug/issue assignment routine that looks at the Area field, matches it to a Team and assigns the bug to the Team's admin în case Assigned To field is not populated. – siliond Feb 26 '14 at 10:12
1

Found this post TFS11 API: Managing Team Administrators; I duplicate code for easy reference, see original post for complete info.

static void Main(string[] args)
{
    // Connect to the TFS server and get the team project URI.
    var collection = GetServer("server_uri");
    var projectUri = GetProjectUri(collection, "project_name");

    // Retrieve the default team.
    TfsTeamService teamService = collection.GetService<TfsTeamService>();
    TeamFoundationTeam defaultTeam = teamService.GetDefaultTeam(projectUri, null);

    // Get security namespace for the project collection.
    ISecurityService securityService = collection.GetService<ISecurityService>();
    SecurityNamespace securityNamespace = securityService.GetSecurityNamespace(FrameworkSecurity.IdentitiesNamespaceId);

    // Use reflection to retrieve a security token for the team.
    MethodInfo mi = typeof(IdentityHelper).GetMethod("CreateSecurityToken", BindingFlags.Static | BindingFlags.NonPublic);           
    string token = mi.Invoke(null, new object[] { defaultTeam.Identity }) as string;

    // Retrieve an ACL object for all the team members.
    var allMembers = defaultTeam.GetMembers(collection, MembershipQuery.Expanded).Where(m => !m.IsContainer);
    AccessControlList acl = securityNamespace.QueryAccessControlList(token, allMembers.Select(m => m.Descriptor), true);

    // Retrieve the team administrator SIDs by querying the ACL entries.
    var entries = acl.AccessControlEntries;
    var admins = entries.Where(e => (e.Allow & 15) == 15).Select(e => e.Descriptor.Identifier);

    // Finally, retrieve the actual TeamFoundationIdentity objects from the SIDs.
    var adminIdentities = allMembers.Where(m => admins.Contains(m.Descriptor.Identifier));       
}
Giulio Vian
  • 8,248
  • 2
  • 33
  • 41