Question

I'm attempting to use the TFS event subscription service to dynamically create subscriptions through the web interface. The subscriptions are going to an intermediate account. For our purposes, we'll call the two accounts "non-admin user" and "subscription storage".

An administrator can create an alert for the "subscription storage" account, and the subscription storage account can create alerts for itself, but a non-admin user cannot create subscriptions in the storage account. I receive the following error message:

Access Denied: {user account name} needs the following permission(s) on the resource $SUBSCRIPTION: to perform this action: Edit

The code I'm using is:

IEventService eventService = (IEventService)this.tfsCollection.GetService(typeof(IEventService));
eventService.SubscribeEvent(userAccountIdentity.Sid, Strings.WorkItemChangedEvent, string.Format(Strings.Condition0, workItem.ToString(CultureInfo.InvariantCulture)), deliveryPreference, string.Format(Strings.AlertTag0, workItem.ToString(CultureInfo.InvariantCulture)));

Please take it on faith that all of the parameters are correct and that their values are irrelevant for this discussion. :) tfsCollection is a TfsTeamProjectCollection object that comes from the page's Connection.TeamProjectCollection property.

My first thought was to break impersonation so that it uses the service account (in this case, NetworkService), so I made an extension method that takes an Action and performs it without impersonation, as follows:

    public static void WithoutImpersonation(this Action actionToPerform)
    {
        using (var ctx = WindowsIdentity.Impersonate(IntPtr.Zero))
        {
            try
            {
                actionToPerform();
            }
            finally
            {
                ctx.Undo();
            }
        }
    }

This correctly breaks impersonation for the duration of the Action (checking WindowsIdentity.GetCurrentUser() returns the NetworkService account instead of the user account), but it still fails to create the event subscription with the same error. The authenticated user of the TfsTeamProjectCollection is the NetworkService account, as well.

Was it helpful?

Solution

I solved it! It turns out I was approaching it the wrong way. From the page instantiating my class, I had to use EnterTfsImpersonationContext, then look up the identity of the storage account and create a new TfsTeamProjectCollection for the account. That solved the problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top