Team Foundation RSS Feed Generator for Source Control

Some time ago, I switched to a much more efficient way of keeping up with news and other events. Instead of visiting several web sites to keep up with what's happening, I started using a web-based blog aggregator. There are many out there, the one what worked the best for me and my situation is http://www.bloglines.com. This way, I could keep track of what's going on by visiting one web site and viewing the news articles that I wanted to see. Of course, if one of the sites doesn't have an RSS feed, than I was faced with either ditching that site or visiting the site. Usually, I ended up ditching the site in favor of viewing articles using the RSS reader.

In that spirit, I started to look into creating an RSS feed for Team Foundation. I work on the Source Control part of Team Foundation, so naturally, I started there. Before I get into what I actually did to create the RSS feed, let me explain a little about Team Foundation Alerts. An alert is an out-of-band notification that some condition that you expressed interest in has occurred. When the condition occurs, Team Foundation will send an email with the details. We have alerts that notify you when

  1. A work item is assigned to you (or a work item that is assigned to you changes)
  2. A checkin to has occurred.
  3. A build has started
  4. A build has completed

Alerts are created by subscribing  to one of these events and are scoped to a Team Project. When you subscribe to an alert (or more commonly, the Team Project administrator has created a subscription for you), you'll only receive alerts that related to that Team Project. You have to use Visual Studio to subscribe to an alert. Select a Team Project, then use Team -> Alerts. Select the event(s) and supply an email address.

Back to RSS feeds. I receive a lot of e-mail each day and decided that I'd rather find out about checkins that have occurred differently. Thus, the RSS feed generator for Team Project Source Control was born.

The RSS feed is implemented in a .ASPX file and makes use of public interfaces the Team Foundation source control assemblies to retrieve information about the most recent checkins. I'm not going to explain the details of what constitutes an RSS feed; there are many websites that do this. Instead, I'll focus on on this feed works.

Features

  • Returns information about the most recent checkins to Team Foundation
  • If a pathname is supplied, checkins relating to that path or below are returned
  • Only services 1 request per pester-interval for mal-behaved RSS aggregators
  • Only uses public interfaces in the Team Foundation assemblies

Overview

At a high level, this is what the RSS feed generator I wrote does:

  • Decide whether to process the request. If the sender was serviced within the pester interval, the request is ignored.
  • Check whether the request contains a filename. When a filename is specified, checkins to that filename (or, if it's a directory, files in the directory tree) is returned. When a filename is not specified, information about all recent checkins is returned.
  • Gather information about the checkins and prepare the RSS XML stream.

Sounds pretty simple, right? There are a few details buried in the .aspx file and you might be wondering about security. Team Foundation Source Control has a security model that provides authorization and information protection and has safeguards against to prevent information disclosure.

Security

A checkin represents a set of file changes. In order for a user to "see" the checkin, the user must have access to at least one element of the checkin. When a user doesn't have access any elements of the checkin, the checkin cannot be viewed by that user.

Therefore, the RSS aggregator used to obtain the feeds, must have read access to the Source Control repository. The repository provides a hierarchical view of the files that it contains rooted at $/. Team Projects are created as the top most elements, e.g., a repository with Team Projects Project1 and Project2 are represented this way:

   $/Project1/

         Subdirectory1

         Subdirectory2

   $/Project2/

         OtherSubdirectory1

         OtherSubdirectory2

Access to the files and directories is governed by a set of inheritable Access Control List (ACL) entries. Each ACL specifies which identities (users and/or groups) are granted or denied access to elements. You can view the permission settings of an item from the command line using the Source Control command line tool h.exe (to be renamed when we ship) as follows

   h perm $/Project1

   ===============================================================================
   Server item: $/Project1 (Inherit: Yes)
     Identity: Namespace Administrators
       Allow:
       Deny:
       Allow (Inherited): Read, PendChange, Checkin, Label, Lock, ReviseOther,
                          UnlockOther, UndoOther, LabelOther, AdminProjectRights, CheckinOther
       Deny (Inherited):

     Identity: Service Accounts
       Allow:
       Deny:
       Allow (Inherited): Read, PendChange, Checkin, Label, Lock, ReviseOther,
                          UnlockOther, UndoOther, LabelOther, AdminProjectRights, CheckinOther
       Deny (Inherited):

This shows that there are no explicit permissions assigned to $/Project1 since the Allow: and Deny: entries are empty. There are inherited permissions, however. This example also shows the default permissions that exist when Team Project is installed.

NOTE: Back to the RSS feed aggregator: the RSS aggregator must have read permission to the (sub)-tree of the repository that it gathers information from. You can use either the Permissions dialog within Visual Studio or, if you're a gear-head like me, use the h perm command to view and change the permission settings.

What do I really mean? The identity of the process that requests the feed must have read access.

You're probably wondering about the huge security hole that exists here, right? You get extra points for thinking about this but I've already taken care of it. The potential security hole is this:

  1. An RSS aggregator gathers checkin information for a site.
  2. Users connect to the RSS aggregator to get checkin information
  3. At least one of the users in step 2 can now see checkin information that, had they requested it directly using h changeset someNumber would be denied.

The RSS feed returns hyperlinks that, when followed, are processed according to the security associated with the identity opening the link. The RSS feed returns meta information about the checkin and the user uses the meta information (i.e., the hyperlink), to actually see the details of the changeset.

Whew! That's all for now, I'll write more about the details of the RSS feed in an upcoming blog.

jeff