Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 3
0
        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.");
                }
            }
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
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));
        }
Ejemplo n.º 8
0
        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);
        }