In the past I’ve showed some examples on how to work with TFS IGroupSecurityService for getting users list, but you can do much more, Create new Group, Add or Remove users from group etc…

Download Demo Project
Step 1: Connect To TFS and Get All Users and Projects
As always we need to start with connecting to TFS, but here we’ll also obtain 2 important services for our demo IGroupSecurityService and ICommonStructureService.
Using ICommonStructureService we’ll be able to extract all Team Projects under the collection you choose, this is not the only way to do that.
Using IGroupSecurityService will allow us to get all users under the “Project Collection Valid Users” category.
private void BtnConnectClick(object sender, RoutedEventArgs e)
{
var tpp = new TeamProjectPicker(TeamProjectPickerMode.NoProject, false);
tpp.ShowDialog();
if (tpp.SelectedTeamProjectCollection == null) return;
_tfs= tpp.SelectedTeamProjectCollection;
_css= (ICommonStructureService)_tfs.GetService<ICommonStructureService>();
_gss= (IGroupSecurityService)_tfs.GetService<IGroupSecurityService>();
var allSids = _gss.ReadIdentity(SearchFactor.AccountName,
"Project Collection Valid Users", QueryMembership.Expanded);
listAllUsers.ItemsSource = _gss.ReadIdentities(SearchFactor.Sid,
allSids.Members, QueryMembership.None).Where(a=>a.Type ==
IdentityType.WindowsUser || a.Type == IdentityType.WindowsGroup);
listProjects.ItemsSource = _css.ListAllProjects();
}
Step 2: Get All Application Groups Under a Team Project
Once you choose a project we’ll use Project Uri and ListApplicationGroups method under IGroupSecurityService to get all Groups under that project.
private void ListProjectsSelectionChanged(object sender,
SelectionChangedEventArgs e)
{
if (listProjects.SelectedItem == null) return;
var project = listProjects.SelectedItem as ProjectInfo;
listGroups.ItemsSource = _gss.ListApplicationGroups(project.Uri);
}
Step 3: Get Users From Specific Group
When you select a specific group we’ll use the group SID to get all members under that group.
Make sure to change the SearchFactor to SID instead on AccountName, this will prevent getting users from another Project where the Group Name is not unique.
private void ListGroupsSelectionChanged(object sender,
SelectionChangedEventArgs e)
{
if (listGroups.SelectedItem == null) return;
var group = listGroups.SelectedItem as Identity;
var sids = _gss.ReadIdentity(SearchFactor.Sid, group.Sid,
QueryMembership.Expanded);
if (sids == null || sids.Members.Length == 0)
{
listUsers.ItemsSource = null;
return;
}
listUsers.ItemsSource = _gss.ReadIdentities(SearchFactor.Sid,
sids.Members, QueryMembership.None);
}
Step 4: Add New Application Group
This part is very simple, you just need to obtain the Project Uri and call CreateApplicationGroup under IGroupSecurityService with the Project Uri and the new Group Name.
private void BtnAddGroupClick(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(txtGroupName.Text) ||
listProjects.SelectedItem == null) return;
var project = listProjects.SelectedItem as ProjectInfo;
var groupname = txtGroupName.Text;
try
{
var result = _gss.CreateApplicationGroup(project.Uri, groupname,
"Your Group Description");
ListProjectsSelectionChanged(sender, null);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Step 5: Remove Application Group
This part is also very simple, you need to call DeleteApplicationGroup method under IGroupSecurityService with the Group sid you want to delete.
private void BtnRemoveGroupClick(object sender, RoutedEventArgs e)
{
if (listGroups.SelectedItem == null) return;
var result = MessageBox.Show("You are about to remove application
group from TFS, press yes to continue",
"Remove Group", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (result == MessageBoxResult.No) return;
var group = listGroups.SelectedItem as Identity;
_gss.DeleteApplicationGroup(group.Sid);
ListProjectsSelectionChanged(sender, null);
}
Step 6: Add User To Application Group
For this you need to obtain the User sid and Group sid and again using the IGroupSecurityService add call AddMemberToApplicationGroup method passing those values.
If the User already exists in that Group you will receive a soap exception.
private void BtnAddUserToGroupClick(object sender, RoutedEventArgs e)
{
if (listAllUsers.SelectedItem == null
|| listGroups.SelectedItem == null) return;
var group = listGroups.SelectedItem as Identity;
var user = listAllUsers.SelectedItem as Identity;
try
{
_gss.AddMemberToApplicationGroup(group.Sid, user.Sid);
ListGroupsSelectionChanged(sender, null);
}
catch (Exception ex)
{//TF50235: The group Test Group already has a member Administrators.
MessageBox.Show(ex.Message);
}
}
Step 7: Remove User From Application Group
It’s the same as Adding a user to a group, just call RemoveMemberFromApplicationGroup method.
private void BtnRemoveUserFromGroupClick(object sender, RoutedEventArgs e)
{
if (listUsers.SelectedItem == null ||
listGroups.SelectedItem == null) return;
var group = listGroups.SelectedItem as Identity;
var user = listUsers.SelectedItem as Identity;
_gss.RemoveMemberFromApplicationGroup(group.Sid,user.Sid);
ListGroupsSelectionChanged(sender, null);
}
Download Demo Project
Enjoy.
In my previous post on ASP MVC I showed How To Add Captcha to ASP MVC Web Application, but even if you use captcha you still want to make sure the user email is real and not just a fake one.
In order to make sure the user has gave you his real email you need to use Email Confirmation mechanism to your site.
ASP MVC is doing some of the work for us, when a user is register to your site is assign with a unique ID (Guid) property called - ProviderUserKey
I’ll use this value to verify the account.
Step 1: Create new ASP MVC 3 Web Site

Step 2: Modify Web.Config with SMTP Settings
Before we get started with the Email Confirmation implementation we need to define our email settings, to do so I’ve used my Gmail account (just for this test) and add those values in the web.config just below the configuration tag.
<configuration>
<system.net>
<mailSettings>
<smtp deliveryMethod="Network">
<network host="smtp.gmail.com" port="587"
userName="[YourName@Gmail.com]"
password="[Your Password]" />
</smtp>
</mailSettings>
</system.net>
Step 3: Add Confirmation View
After the user has register we want to redirect him to a confirmation page and tell him to check his email for the confirmation link, so
Add new View called – Confirmation
@{
ViewBag.Title = "Email Confirmation";
}
<h2>
Confirmation</h2>
<p>
Thank you for registering. Please check your email for a confirmation
request with a link that will confirm your account. Once you click the
link, your registration will be complete.</p>
In the AccountController add result for Confirmation
public ActionResult Confirmation()
{
return View();
}
Step 4: Send Mail
Before changing the registration we need to create the email functionality, this confirmation
email will contain the ProviderUserKey and a direct link to our site.
The SendConfirmationEmail method will receive the UserName, using Membership.GetUser
we’ll be able to get all the information on that user and of course the ProviderUserKey.
I’ve built the confirmation url using HttpContext and combine the User Guid ID and the site url.
var verifyUrl =
HttpContext.Current.Request.Url.GetLeftPart
(
UriPartial.Authority) +
"/Account/Verify/" + confirmationGuid;
public class EmailManager
{
private const string EmailFrom = "noreplay@gmail.com";
public static void SendConfirmationEmail(string userName)
{
var user = Membership.GetUser(userName.ToString());
var confirmationGuid = user.ProviderUserKey.ToString();
var verifyUrl = HttpContext.Current.Request.Url.GetLeftPart
(UriPartial.Authority) + "/Account/Verify/" + confirmationGuid;
using (var client = new SmtpClient())
{
using (var message = new MailMessage(EmailFrom, user.Email))
{
message.Subject = "Please Verify your Account";
message.Body = "<html><head><meta content=\"text/html;
charset=utf-8\" /></head><body><p>Dear " + user.UserName +
", </p><p>To verify your account, please click the following link:</p>"
+ "<p><a href=\"" + verifyUrl + "\" target=\"_blank\">" + verifyUrl + "
+"</a></p><div>Best regards,</div><div>Someone</div><p>Do not forward "
+"this email. The verify link is private.</p></body></html>";
message.IsBodyHtml = true;
client.EnableSsl = true;
client.Send(message);
};
};
}
}
Step 5: Change Registration
Now, we need to change Registration functionality, the main thing is when creating a new user we need to change the user state to Not Approve and instead of performing login we need to send him an email using our EmailManager and show him the confirmation page.
[HttpPost]
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
MembershipCreateStatus createStatus;
//Make sure the user is not approve at this point!!!
Membership.CreateUser(model.UserName, model.Password, model.Email,
null, null, false, null, out createStatus);
if (createStatus == MembershipCreateStatus.Success)
{
EmailManager.SendConfirmationEmail(model.UserName);
return RedirectToAction("Confirmation", "Account");
}
else
{
ModelState.AddModelError("", ErrorCodeToString(createStatus));
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Step 6: Add Verify
In the AccountController I’ve add a Verify ActionResult, the Verify will receive User ID, then we’ll check for some bad Ids, if the user is already approved SignOut the user a redirect to the LogOn page, if the user is not approve we need to change the IsApprove to true and call UpdateUser to update the database with the new change, also we will do the login for the user and redirect him to the home page.
public ActionResult Verify(string id)
{
if (string.IsNullOrEmpty(id) || (!Regex.IsMatch(id, @"[0-9a-f]{8}\-
([0-9a-f]{4}\-){3}[0-9a-f]{12}")))
{
ViewBag.Msg = "Not Good!!!";
return View();
}
else
{
var user = Membership.GetUser(new Guid(id));
if (!user.IsApproved)
{
user.IsApproved = true;
Membership.UpdateUser(user);
FormsAuthentication.SetAuthCookie(user.UserName, false);
return RedirectToAction("Index", "Home");
}
else
{
FormsAuthentication.SignOut();
ViewBag.Msg = "Account Already Approved";
return RedirectToAction("LogOn");
}
}
}
Enjoy