public bool SetProfileImage(string identity, string imagePath, out string message) { bool ret = true; message = string.Empty; byte[] image = new byte[0]; TeamFoundationIdentity i = ims2.ReadIdentity(IdentitySearchFactor.AccountName, identity, MembershipQuery.Direct, ReadIdentityOptions.None); if (i == null) { message = "User/Group [" + identity + "] not found"; ret = false; } if (!File.Exists(imagePath)) { message = "File [" + imagePath + "] not found"; ret = false; } if (ret) { try { byte[] rawImage = File.ReadAllBytes(imagePath); image = ConvertAndResizeImage(rawImage); } catch (Exception ex) { message = "Could not read the profile image: " + ex.Message; ret = false; } } if (ret) { i.SetProperty("Microsoft.TeamFoundation.Identity.Image.Data", image); i.SetProperty("Microsoft.TeamFoundation.Identity.Image.Type", "image/png"); i.SetProperty("Microsoft.TeamFoundation.Identity.Image.Id", Guid.NewGuid().ToByteArray()); i.SetProperty("Microsoft.TeamFoundation.Identity.CandidateImage.Data", null); i.SetProperty("Microsoft.TeamFoundation.Identity.CandidateImage.UploadDate", null); try { ims2.UpdateExtendedProperties(i); } catch (PropertyServiceException) { // swallow; this exception happens each and every time, but the changes are applied :S. } message = "Profile image set"; } return(ret); }
public bool ClearProfileImage(string identity, out string message) { bool ret = true; message = string.Empty; TeamFoundationIdentity i = ims2.ReadIdentity(IdentitySearchFactor.AccountName, identity, MembershipQuery.Direct, ReadIdentityOptions.None); if (i == null) { message = "User/Group [" + identity + "] not found"; ret = false; } if (ret) { i.SetProperty("Microsoft.TeamFoundation.Identity.Image.Data", null); i.SetProperty("Microsoft.TeamFoundation.Identity.Image.Type", null); i.SetProperty("Microsoft.TeamFoundation.Identity.Image.Id", null); i.SetProperty("Microsoft.TeamFoundation.Identity.CandidateImage.Data", null); i.SetProperty("Microsoft.TeamFoundation.Identity.CandidateImage.UploadDate", null); try { ims2.UpdateExtendedProperties(i); } catch (PropertyServiceException) { // swallow; this exception happens each and every time, but the changes are applied :S. } message = "Profile image cleared"; } return(ret); }
public ITeamFoundationIdentity ReadIdentity( IdentitySearchFactor searchFactor, string searchFactorValue, MembershipQuery queryMembership) { if (string.IsNullOrEmpty(searchFactorValue)) { throw new ArgumentException("Value cannot be null or empty.", nameof(searchFactorValue)); } // TODO: Use configuration options from IWorkItemStore to control proxy creation return(_identityManagementService2.ReadIdentity( (Microsoft.TeamFoundation.Framework.Common.IdentitySearchFactor)searchFactor, searchFactorValue, (Microsoft.TeamFoundation.Framework.Common.MembershipQuery)queryMembership, ReadIdentityOptions.IncludeReadFromSource) .AsProxy()); }
private static readonly string SpecialGroupName = "Service Hooks Administrators"; // assumed to be a collection-level group containing people that will have management permissions for SH in each project public void Run(Uri collectionUri) { Console.WriteLine("Utility to remove Service Hooks management permissions from the Project Administrators groups."); Console.WriteLine(""); Console.WriteLine(" All projects in account/collection: " + collectionUri); Console.WriteLine(""); Console.WriteLine("WARNING! This operation will remove the permissions.\n\n Are you sure you want to continue (Y/N)?"); int confirmChar = Console.In.Read(); if (confirmChar != 'y' || confirmChar != 'Y') { return; } if (collectionUri != null) { TfsTeamProjectCollection connection = new TfsTeamProjectCollection(collectionUri); // Get Core, security, and identity services ISecurityService securityService = connection.GetService <ISecurityService>(); SecurityNamespace hooksSecurity = securityService.GetSecurityNamespace(ServiceHooksSecurityNamespaceId); IIdentityManagementService2 identityService = connection.GetService <IIdentityManagementService2>(); ProjectHttpClient projectClient = connection.GetClient <ProjectHttpClient>(); IEnumerable <TeamProjectReference> projects = projectClient.GetProjects(stateFilter: Microsoft.TeamFoundation.Common.ProjectState.WellFormed).Result; // Iterate over each project, check SH permissions, and remove if the project administrators group has access foreach (var project in projects) { // Remove manage permissions from the project's administrators group (but leave it "view" access) Console.WriteLine(String.Format("Project {0} ({1})", project.Name, project.Id)); var groups = identityService.ListApplicationGroups(project.Id.ToString(), ReadIdentityOptions.None, null, Microsoft.TeamFoundation.Framework.Common.IdentityPropertyScope.Both); String adminGroupName = String.Format("vstfs:///Classification/TeamProject/{0}\\Project Administrators", project.Id); try { TeamFoundationIdentity adminGroup = groups.First(g => String.Equals(g.UniqueName, adminGroupName, StringComparison.InvariantCultureIgnoreCase)); Console.WriteLine(" - Checking Project Administrators group permissions"); String securityToken = "PublisherSecurity/" + project.Id; bool hasPermission = hooksSecurity.HasPermission(securityToken, adminGroup.Descriptor, ManagePermissions, false); // Project admin group has "manage" permissions for SH in the project if (hasPermission) { // Remove manage permissions from the project's administrators group (but leave it "view" access) Console.WriteLine(" - Has permissions. Removing..."); // Give the admin group only view permissions hooksSecurity.SetPermissions(securityToken, adminGroup.Descriptor, ViewPermissions, 0, false); // check permission again after granting hasPermission = hooksSecurity.HasPermission(securityToken, adminGroup.Descriptor, ManagePermissions, false); if (!hasPermission) { Console.WriteLine(" - Verified permissions correctly removed."); } else { Console.WriteLine(" - Project Administrators Group still has manage permissions."); } } else { Console.WriteLine(" - Does not have permissions to manage service hook subscriptions."); } } catch (Exception ex) { Console.WriteLine(String.Format("Admin group: Not found! ({0})", ex.Message)); } Console.WriteLine(""); } // Grant the group manage permissions across the entire collection TeamFoundationIdentity specialGroup = identityService.ReadIdentity(IdentitySearchFactor.DisplayName, SpecialGroupName, MembershipQuery.None, ReadIdentityOptions.None); if (specialGroup != null) { Console.WriteLine("Granting full manage permissions to: {0}", specialGroup.UniqueName); String rootSecurityToken = "PublisherSecurity/"; hooksSecurity.SetPermissions(rootSecurityToken, specialGroup.Descriptor, ManagePermissions, 0, false); } else { Console.WriteLine("Could not find this group."); } } }
public static object Run(ExportADGroupsOptions opts, string logPath) { Telemetry.Current.TrackEvent("Run-ExportADGroupsCommand"); string exportPath = CreateExportPath(logPath, "ExportADGroups"); Trace.Listeners.Add(new TextWriterTraceListener(Path.Combine(exportPath, "ExportADGroups.log"), "ExportADGroupsCommand")); Stopwatch stopwatch = Stopwatch.StartNew(); ////////////////////////////////////////////////// StreamWriter sw = File.CreateText(Path.Combine(exportPath, "AzureADGroups.csv")); sw.AutoFlush = true; using (var csv = new CsvWriter(sw)) { csv.WriteHeader <AzureAdGroupItem>(); TfsTeamProjectCollection sourceCollection = new TfsTeamProjectCollection(opts.CollectionURL); sourceCollection.EnsureAuthenticated(); IIdentityManagementService2 sourceIMS2 = (IIdentityManagementService2)sourceCollection.GetService(typeof(IIdentityManagementService2)); List <CatalogNode> sourceTeamProjects = sourceCollection.CatalogNode.QueryChildren(new[] { CatalogResourceTypes.TeamProject }, false, CatalogQueryOptions.None).ToList(); if (opts.TeamProject != null) { sourceTeamProjects = sourceTeamProjects.Where(x => x.Resource.DisplayName == opts.TeamProject).ToList(); } int current = sourceTeamProjects.Count(); foreach (CatalogNode sourceTeamProject in sourceTeamProjects) { Trace.WriteLine(string.Format("---------------{0}\\{1}", current, sourceTeamProjects.Count())); Trace.WriteLine(string.Format("{0}, {1}", sourceTeamProject.Resource.DisplayName, sourceTeamProject.Resource.Identifier)); string projectUri = sourceTeamProject.Resource.Properties["ProjectUri"]; TeamFoundationIdentity[] appGroups = sourceIMS2.ListApplicationGroups(projectUri, ReadIdentityOptions.None); foreach (TeamFoundationIdentity appGroup in appGroups.Where(x => !x.DisplayName.EndsWith("\\Project Valid Users"))) { Trace.WriteLine(string.Format(" {0}", appGroup.DisplayName)); TeamFoundationIdentity sourceAppGroup = sourceIMS2.ReadIdentity(appGroup.Descriptor, MembershipQuery.Expanded, ReadIdentityOptions.None); foreach (IdentityDescriptor child in sourceAppGroup.Members.Where(x => x.IdentityType == "Microsoft.TeamFoundation.Identity")) { TeamFoundationIdentity sourceChildIdentity = sourceIMS2.ReadIdentity(IdentitySearchFactor.Identifier, child.Identifier, MembershipQuery.None, ReadIdentityOptions.ExtendedProperties); if ((string)sourceChildIdentity.GetProperty("SpecialType") == "AzureActiveDirectoryApplicationGroup") { Trace.WriteLine(string.Format(" Suspected AD Group {0}", sourceChildIdentity.DisplayName)); csv.WriteRecord <AzureAdGroupItem>(new AzureAdGroupItem { TeamProject = sourceTeamProject.Resource.DisplayName, ApplciationGroup = sourceTeamProject.Resource.DisplayName, Account = (string)sourceChildIdentity.GetProperty("Account"), Mail = (string)sourceChildIdentity.GetProperty("Mail"), DirectoryAlias = (string)sourceChildIdentity.GetProperty("DirectoryAlias") }); } } } current--; sw.Flush(); } } sw.Close(); // current--; //} ////////////////////////////////////////////////// stopwatch.Stop(); Trace.WriteLine(string.Format(@"DONE in {0:%h} hours {0:%m} minutes {0:s\:fff} seconds", stopwatch.Elapsed)); Trace.Listeners.Remove("ExportADGroupsCommand"); return(0); }
//private readonly TfsTeamService teamService; //private readonly ProjectInfo projectInfo; public override int RunInternal(ExportPicturesOptions opts) { if (!Directory.Exists(opts.OutPath)) { Directory.CreateDirectory(opts.OutPath); } TfsTeamProjectCollection collection = new TfsTeamProjectCollection(opts.CollectionURL); collection.EnsureAuthenticated(); IIdentityManagementService2 ims2 = (IIdentityManagementService2)collection.GetService(typeof(IIdentityManagementService2)); TeamFoundationIdentity SIDS = ims2.ReadIdentity(IdentitySearchFactor.AccountName, "Project Collection Valid Users", MembershipQuery.Expanded, ReadIdentityOptions.None); Trace.WriteLine(string.Format("Found {0}", SIDS.Members.Count())); var itypes = (from IdentityDescriptor id in SIDS.Members select id.IdentityType).Distinct(); foreach (string item in itypes) { var infolks = (from IdentityDescriptor id in SIDS.Members where id.IdentityType == item select id); Trace.WriteLine(string.Format("Found {0} of {1}", infolks.Count(), item)); } var folks = (from IdentityDescriptor id in SIDS.Members where id.IdentityType == "System.Security.Principal.WindowsIdentity" || id.IdentityType == "Microsoft.IdentityModel.Claims.ClaimsIdentity" select id); DirectoryContext objContext = new DirectoryContext(DirectoryContextType.Domain, opts.Domain, opts.Username, opts.Password); Domain objDomain = Domain.GetDomain(objContext); string ldapName = string.Format("LDAP://{0}", objDomain.Name); int current = folks.Count(); foreach (IdentityDescriptor id in folks) { try { TeamFoundationIdentity i = ims2.ReadIdentity(IdentitySearchFactor.Identifier, id.Identifier, MembershipQuery.Direct, ReadIdentityOptions.None); Trace.WriteLine(i.DisplayName); if (!(i == null) && (i.IsContainer == false)) { if ((!i.DisplayName.StartsWith("Microsoft.") && (!i.DisplayName.StartsWith("OssManagement")))) { DirectoryEntry d = new DirectoryEntry(ldapName, opts.Username, opts.Password); DirectorySearcher dssearch = new DirectorySearcher(d); if (i.UniqueName.Contains("@")) { dssearch.Filter = string.Format("(sAMAccountName={0})", i.UniqueName.Split(char.Parse(@"@"))[0]); } else { dssearch.Filter = string.Format("(sAMAccountName={0})", i.UniqueName.Split(char.Parse(@"\"))[1]); } SearchResult sresult = dssearch.FindOne(); WebClient webClient = new WebClient(); webClient.Credentials = CredentialCache.DefaultNetworkCredentials; if (sresult != null) { string newImage = Path.Combine(opts.OutPath, string.Format("{0}.jpg", i.UniqueName.Replace(@"\", "-"))); if (!File.Exists(newImage)) { DirectoryEntry deUser = new DirectoryEntry(sresult.Path, opts.Username, opts.Password); Trace.WriteLine(string.Format("{0} [PROCESS] {1}: {2}", current, deUser.Name, newImage)); string empPic = string.Format(opts.CorporatePictureMask, deUser.Properties[opts.ADPropertyName].Value); try { webClient.DownloadFile(empPic, newImage); } catch (Exception ex) { Trace.WriteLine(string.Format(" [ERROR] {0}", ex.ToString())); } } else { Trace.WriteLine(string.Format("{0} [SKIP] Exists {1}", current, newImage)); } } } } } catch (Exception ex) { Trace.WriteLine(string.Format(" [ERROR] {0}", ex.ToString())); } current--; } return(0); }
internal override void InternalExecute() { Stopwatch stopwatch = Stopwatch.StartNew(); ////////////////////////////////////////////////// string exportPath; string assPath = System.Reflection.Assembly.GetExecutingAssembly().Location; exportPath = Path.Combine(Path.GetDirectoryName(assPath), "export-pic"); if (!Directory.Exists(exportPath)) { Directory.CreateDirectory(exportPath); } TeamFoundationIdentity SIDS = ims2.ReadIdentity(IdentitySearchFactor.AccountName, "Team Foundation Valid Users", MembershipQuery.Expanded, ReadIdentityOptions.None); Trace.WriteLine(string.Format("Found {0}", SIDS.Members.Count())); var itypes = (from IdentityDescriptor id in SIDS.Members select id.IdentityType).Distinct(); foreach (string item in itypes) { var infolks = (from IdentityDescriptor id in SIDS.Members where id.IdentityType == item select id); Trace.WriteLine(string.Format("Found {0} of {1}", infolks.Count(), item)); } var folks = (from IdentityDescriptor id in SIDS.Members where id.IdentityType == "System.Security.Principal.WindowsIdentity" select id); DirectoryContext objContext = new DirectoryContext(DirectoryContextType.Domain, config.Domain, config.Username, config.Password); Domain objDomain = Domain.GetDomain(objContext); string ldapName = string.Format("LDAP://{0}", objDomain.Name); int current = folks.Count(); foreach (IdentityDescriptor id in folks) { try { TeamFoundationIdentity i = ims2.ReadIdentity(IdentitySearchFactor.Identifier, id.Identifier, MembershipQuery.Direct, ReadIdentityOptions.None); if (!(i == null) && i.IsContainer == false) { DirectoryEntry d = new DirectoryEntry(ldapName, config.Username, config.Password); DirectorySearcher dssearch = new DirectorySearcher(d); dssearch.Filter = string.Format("(sAMAccountName={0})", i.UniqueName.Split(char.Parse(@"\"))[1]); SearchResult sresult = dssearch.FindOne(); WebClient webClient = new WebClient(); webClient.Credentials = CredentialCache.DefaultNetworkCredentials; if (sresult != null) { string newImage = Path.Combine(exportPath, string.Format("{0}.jpg", i.UniqueName.Replace(@"\", "-"))); if (!File.Exists(newImage)) { DirectoryEntry deUser = new DirectoryEntry(sresult.Path, config.Username, config.Password); Trace.WriteLine(string.Format("{0} [PROCESS] {1}: {2}", current, deUser.Name, newImage)); string empPic = string.Format(config.PictureEmpIDFormat, deUser.Properties["employeeNumber"].Value); try { webClient.DownloadFile(empPic, newImage); } catch (Exception ex) { Trace.WriteLine(string.Format(" [ERROR] {0}", ex.ToString())); } } else { Trace.WriteLine(string.Format("{0} [SKIP] Exists {1}", current, newImage)); } } webClient.Dispose(); } } catch (Exception ex) { Trace.WriteLine(string.Format(" [ERROR] {0}", ex.ToString())); } current--; } ////////////////////////////////////////////////// stopwatch.Stop(); Trace.WriteLine(string.Format(@"DONE in {0:%h} hours {0:%m} minutes {0:s\:fff} seconds", stopwatch.Elapsed)); }
public override int RunInternal(ExportAzureADOptions opts) { opts.OutPath = opts.OutPath ?? this.LogPathRoot; StreamWriter sw = File.CreateText(Path.Combine(opts.OutPath, "IdentityList.csv")); sw.AutoFlush = true; using (var csv = new CsvWriter(sw)) { csv.WriteHeader <AzureAdGroupItem>(); TfsTeamProjectCollection sourceCollection = new TfsTeamProjectCollection(opts.CollectionURL); sourceCollection.EnsureAuthenticated(); IIdentityManagementService2 sourceIMS2 = (IIdentityManagementService2)sourceCollection.GetService(typeof(IIdentityManagementService2)); List <CatalogNode> sourceTeamProjects = sourceCollection.CatalogNode.QueryChildren(new[] { CatalogResourceTypes.TeamProject }, false, CatalogQueryOptions.None).ToList(); if (opts.TeamProject != null) { sourceTeamProjects = sourceTeamProjects.Where(x => x.Resource.DisplayName == opts.TeamProject).ToList(); } int current = sourceTeamProjects.Count(); foreach (CatalogNode sourceTeamProject in sourceTeamProjects) { Trace.WriteLine(string.Format("---------------{0}\\{1}", current, sourceTeamProjects.Count())); Trace.WriteLine(string.Format("{0}, {1}", sourceTeamProject.Resource.DisplayName, sourceTeamProject.Resource.Identifier)); string projectUri = sourceTeamProject.Resource.Properties["ProjectUri"]; TeamFoundationIdentity[] appGroups = sourceIMS2.ListApplicationGroups(projectUri, ReadIdentityOptions.None); foreach (TeamFoundationIdentity appGroup in appGroups.Where(x => !x.DisplayName.EndsWith("\\Project Valid Users"))) { Trace.WriteLine(string.Format(" {0}", appGroup.DisplayName)); TeamFoundationIdentity sourceAppGroup = sourceIMS2.ReadIdentity(appGroup.Descriptor, MembershipQuery.Expanded, ReadIdentityOptions.None); foreach (IdentityDescriptor child in sourceAppGroup.Members.Where(x => x.IdentityType == "Microsoft.TeamFoundation.Identity" || x.IdentityType == "Microsoft.IdentityModel.Claims.ClaimsIdentity")) { TeamFoundationIdentity sourceChildIdentity = sourceIMS2.ReadIdentity(IdentitySearchFactor.Identifier, child.Identifier, MembershipQuery.None, ReadIdentityOptions.ExtendedProperties); var SpecialType = (string)sourceChildIdentity.GetProperty("SpecialType"); var Account = (string)sourceChildIdentity.GetProperty("Account"); object DirectoryAlias; object Mail; sourceChildIdentity.TryGetProperty("DirectoryAlias", out DirectoryAlias); sourceChildIdentity.TryGetProperty("Mail", out Mail); switch (SpecialType) { case "AzureActiveDirectoryApplicationGroup": Trace.WriteLine(string.Format(" Found AD Group {0}", sourceChildIdentity.DisplayName)); csv.WriteRecord <AzureAdGroupItem>(new AzureAdGroupItem { TeamProject = sourceTeamProject.Resource.DisplayName, ApplciationGroup = appGroup.DisplayName, Account = Account, Mail = (string)Mail, DirectoryAlias = (string)DirectoryAlias }); break; case "Generic": if (sourceChildIdentity.IsContainer) { Trace.WriteLine(string.Format("Skipping {0} | {1} - TF GROUP", SpecialType, Account)); } else { Trace.WriteLine(string.Format(" Found AD User {0}", sourceChildIdentity.DisplayName)); csv.WriteRecord <AzureAdGroupItem>(new AzureAdGroupItem { TeamProject = sourceTeamProject.Resource.DisplayName, ApplciationGroup = appGroup.DisplayName, Account = Account, Mail = (string)Mail, DirectoryAlias = (string)DirectoryAlias }); } break; default: Trace.WriteLine(string.Format("Skipping {0} | {1} - UNKNOWN", SpecialType, Account)); break; } } } current--; sw.Flush(); } } sw.Close(); return(0); }