예제 #1
0
파일: Program.cs 프로젝트: rtwashburn/DG
        private static void BatchUpMembershipThatExceedsSizeLimit(TeamFoundationIdentity membershipGroup,
            int batchSizeLimit,
            IIdentityManagementService ims, List<TeamFoundationIdentity> membershipGroups,
            Dictionary<IdentityDescriptor, TeamFoundationIdentity> allIdentities)
        {
            var batchNum = 0;
            var remainder = membershipGroup.Members.Length;
            var descriptors = new IdentityDescriptor[batchSizeLimit];

            while (remainder > 0)
            {
                var startAt = batchNum*batchSizeLimit;
                var length = batchSizeLimit;
                if (length > remainder)
                {
                    length = remainder;
                    descriptors = new IdentityDescriptor[length];
                }

                Array.Copy(membershipGroup.Members, startAt, descriptors, 0, length);
                var memberIdentities = ims.ReadIdentities(descriptors, MembershipQuery.Direct, ReadIdentityOptions.None);
                AddCollectionUsersAndGroupsToLists(memberIdentities, membershipGroups, allIdentities);
                remainder -= length;
            }
        }
예제 #2
0
        private void FetchIdentities(IdentityDescriptor[] descriptors)
        {
            TeamFoundationIdentity[] identities;

            // If total membership exceeds batch size limit for Read, break it up
            int batchSizeLimit = 100000;

            if (descriptors.Length > batchSizeLimit)
            {
                int batchNum         = 0;
                int remainder        = descriptors.Length;
                var batchDescriptors = new IdentityDescriptor[batchSizeLimit];

                while (remainder > 0)
                {
                    int startAt = batchNum * batchSizeLimit;
                    int length  = batchSizeLimit;
                    if (length > remainder)
                    {
                        length           = remainder;
                        batchDescriptors = new IdentityDescriptor[length];
                    }

                    Array.Copy(descriptors, startAt, batchDescriptors, 0, length);
                    identities = tfsContext.IdentityManagementService.ReadIdentities(batchDescriptors, MembershipQuery.Direct, ReadIdentityOptions.None);
                    SortIdentities(identities);
                    remainder -= length;
                }
            }
            else
            {
                identities = tfsContext.IdentityManagementService.ReadIdentities(descriptors, MembershipQuery.Direct, ReadIdentityOptions.None);
                SortIdentities(identities);
            }
        }
예제 #3
0
 public PolicyViolationEvent(Type policyType, object originalEvent, IdentityDescriptor identity, string message)
 {
     PolicyType    = policyType;
     OriginalEvent = originalEvent;
     Identity      = identity;
     Message       = message;
 }
예제 #4
0
        private static void BatchUpMembershipThatExceedsSizeLimit(TeamFoundationIdentity membershipGroup,
                                                                  int batchSizeLimit,
                                                                  IIdentityManagementService ims, List <TeamFoundationIdentity> membershipGroups,
                                                                  Dictionary <IdentityDescriptor, TeamFoundationIdentity> allIdentities)
        {
            var batchNum    = 0;
            var remainder   = membershipGroup.Members.Length;
            var descriptors = new IdentityDescriptor[batchSizeLimit];

            while (remainder > 0)
            {
                var startAt = batchNum * batchSizeLimit;
                var length  = batchSizeLimit;
                if (length > remainder)
                {
                    length      = remainder;
                    descriptors = new IdentityDescriptor[length];
                }

                Array.Copy(membershipGroup.Members, startAt, descriptors, 0, length);
                var memberIdentities = ims.ReadIdentities(descriptors, MembershipQuery.Direct, ReadIdentityOptions.None);
                AddCollectionUsersAndGroupsToLists(memberIdentities, membershipGroups, allIdentities);
                remainder -= length;
            }
        }
예제 #5
0
        static void AddUserToAccount(string username)
        {
            //Reference taken from https://blogs.msdn.microsoft.com/buckh/2014/10/07/how-to-add-licensed-users-to-vs-online-via-the-api/
            try
            {
                string _personalAccessToken = ConfigurationSettings.AppSettings["appsetting.pat"].ToString();
                var    creds            = new VssBasicCredential("", _personalAccessToken);
                string _vstsaccountname = ConfigurationSettings.AppSettings["appsetting.vstsacountname"].ToString();
                var    vssConnection    = new VssConnection(new Uri("https://" + _vstsaccountname + ".vssps.visualstudio.com"), creds);
                string aadtenantid      = ConfigurationSettings.AppSettings["appsetting.aadtenantid"].ToString();

                var licensingClient = vssConnection.GetClient <LicensingHttpClient>();
                var identityClient  = vssConnection.GetClient <IdentityHttpClient>();


                var collectionScope = identityClient.GetScopeAsync(_vstsaccountname).Result;


                var licensedUsersGroupDescriptor = new IdentityDescriptor(IdentityConstants.TeamFoundationType,
                                                                          GroupWellKnownSidConstants.LicensedUsersGroupSid);


                var identifier = String.Concat(SidIdentityHelper.GetDomainSid(collectionScope.Id),
                                               SidIdentityHelper.WellKnownSidType,
                                               licensedUsersGroupDescriptor.Identifier.Substring(SidIdentityHelper.WellKnownSidPrefix.Length));


                var collectionLicensedUsersGroupDescriptor = new IdentityDescriptor(IdentityConstants.TeamFoundationType,
                                                                                    identifier);



                var upnIdentity = string.Format("upn:{0}\\{1}", aadtenantid, username);


                var newUserDesciptor = new IdentityDescriptor(IdentityConstants.BindPendingIdentityType,
                                                              upnIdentity);



                bool result = identityClient.AddMemberToGroupAsync(collectionLicensedUsersGroupDescriptor,
                                                                   newUserDesciptor).Result;
                var userIdentity = identityClient.ReadIdentitiesAsync(IdentitySearchFilter.AccountName,
                                                                      username).Result.FirstOrDefault();



                var entitlement = licensingClient.AssignEntitlementAsync(userIdentity.Id, AccountLicense.Auto).Result;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                if (e.InnerException != null)
                {
                    Console.WriteLine(e.InnerException.Message);
                }
            }
        }
 /// <summary>
 /// Constructs an AccessCheckException.
 /// </summary>
 /// <param name="descriptor">The identity descriptor which was checked.</param>
 /// <param name="identityDisplayName">The display name of the identity which was checked.</param>
 /// <param name="token">The token which was checked.</param>
 /// <param name="requestedPermissions">The requested permissions, which were not satisifed by the check.</param>
 /// <param name="namespaceId">The security namespace which was checked.</param>
 /// <param name="message">A descriptive message for the exception.</param>
 public AccessCheckException(
     IdentityDescriptor descriptor,
     String identityDisplayName,
     String token,
     int requestedPermissions,
     Guid namespaceId,
     String message)
     : this(descriptor, token, requestedPermissions, namespaceId, message)
 {
     this.IdentityDisplayName = identityDisplayName;
 }
예제 #7
0
 public void WorkItemRepositoryBuilt(Uri uri, IdentityDescriptor toImpersonate)
 {
     if (toImpersonate != null)
     {
         this.logger.Log(LogLevel.Verbose, "Built a new Work Item Repository for {0} as {1}", uri, toImpersonate);
     }
     else
     {
         this.logger.Log(LogLevel.Diagnostic, "Built a new Work Item Repository for {0}", uri);
     }
 }
        /// <summary>
        /// Retrieve the target identity for a given source descriptor
        /// </summary>
        /// <param name="sourceIdentityDescriptor">Source identity Descriptor</param>
        /// <returns>Target Identity</returns>
        private TeamFoundationIdentity GetTargetIdentity(IdentityDescriptor sourceIdentityDescriptor)
        {
            var sourceIdentity = sourceIdentityManagementService.ReadIdentity(
                sourceIdentityDescriptor,
                MembershipQuery.Direct,
                ReadIdentityOptions.ExtendedProperties);
            string sourceIdentityMail = sourceIdentity.GetProperty("Mail") as string;

            // Try refresh the Identity if we are missing the Mail property
            if (string.IsNullOrEmpty(sourceIdentityMail))
            {
                sourceIdentity = sourceIdentityManagementService.ReadIdentity(
                    sourceIdentityDescriptor,
                    MembershipQuery.Direct,
                    ReadIdentityOptions.ExtendedProperties);

                sourceIdentityMail = sourceIdentity.GetProperty("Mail") as string;
            }

            if (!string.IsNullOrEmpty(sourceIdentityMail))
            {
                // translate source assignedto name to target identity
                var targetIdentity = targetIdentityManagementService.ReadIdentity(
                    IdentitySearchFactor.MailAddress,
                    sourceIdentityMail,
                    MembershipQuery.Direct,
                    ReadIdentityOptions.None);

                if (targetIdentity == null)
                {
                    targetIdentity = targetIdentityManagementService.ReadIdentity(
                        IdentitySearchFactor.AccountName,
                        sourceIdentityMail,
                        MembershipQuery.Direct,
                        ReadIdentityOptions.None);
                }

                if (targetIdentity == null)
                {
                    Trace.Write($"Cannot find tester with e-mail [{sourceIdentityMail}] in target system. Cannot assign.", "TestPlansAndSuites");
                    return(null);
                }

                return(targetIdentity);
            }
            else
            {
                Trace.Write($"No e-mail address known in source system for [{sourceIdentity.DisplayName}]. Cannot translate to target.",
                            "TestPlansAndSuites");
                return(null);
            }
        }
예제 #9
0
        internal static IdentityDescriptorWrapper GetInstance()
        {
            IdentityDescriptor real = default(IdentityDescriptor);

            RealInstanceFactory(ref real);
            var instance = (IdentityDescriptorWrapper)IdentityDescriptorWrapper.GetWrapper(real);

            InstanceFactory(ref instance);
            if (instance == null)
            {
                Assert.Inconclusive("Could not Create Test Instance");
            }
            return(instance);
        }
예제 #10
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="groupID"></param>
 /// <param name="userID"></param>
 /// <returns></returns>
 private bool RemoveMemberFromGroup(IdentityDescriptor groupID, IdentityDescriptor userID)
 {
     try
     {
         if (groupID != null && userID != null && idMgmtSvc.IsMember(groupID, userID))
         {
             idMgmtSvc.RemoveMemberFromApplicationGroup(groupID, userID);
         }
     }
     catch (Exception ex)
     {
         FileHelper.Log(ex.Message);
         return(false);
     }
     return(true);
 }
 private IEnumerable <PermissionAssignment> GetResourcePermissions(
     IdentityDescriptor identity, IReadOnlyList <Resource> resources, string namespaceName)
 {
     try
     {
         var @namespace  = _facade.GetNamespace(namespaceName);
         var tfsIdentity = _facade.GetIdentity(identity);
         var permissions = GetResourcePermissions(resources, @namespace, tfsIdentity);
         return(permissions);
     }
     catch (Exception e)
     {
         Log.Warning($"{e.Message}");
         return(Enumerable.Empty <PermissionAssignment>());
     }
 }
        /// <summary>
        /// Constructs an AccessCheckException.
        /// </summary>
        /// <param name="descriptor">The identity descriptor which was checked.</param>
        /// <param name="token">The token which was checked.</param>
        /// <param name="requestedPermissions">The requested permissions, which were not satisifed by the check.</param>
        /// <param name="namespaceId">The security namespace which was checked.</param>
        /// <param name="message">A descriptive message for the exception.</param>
        public AccessCheckException(
            IdentityDescriptor descriptor,
            String token,
            int requestedPermissions,
            Guid namespaceId,
            String message)
            : base(message)
        {
            ArgumentUtility.CheckForNull(descriptor, nameof(descriptor));
            ArgumentUtility.CheckForNull(token, nameof(token));
            ArgumentUtility.CheckForNull(message, nameof(message));

            this.Descriptor           = descriptor;
            this.Token                = token;
            this.RequestedPermissions = requestedPermissions;
            this.NamespaceId          = namespaceId;
        }
예제 #13
0
        public TeamFoundationIdentity[] GetUsers()
        {
            var ims = TfsTeamProjectCollection.GetService <IIdentityManagementService>();

            // Get expanded membership of the Valid Users group, which is all identities in this host
            var group            = ims.ReadIdentity(GroupWellKnownDescriptors.EveryoneGroup, MembershipQuery.Expanded, ReadIdentityOptions.None);
            var resultIdentities = new HashSet <TeamFoundationIdentity>();;

            // If total membership exceeds batch size limit for Read, break it up
            int batchSizeLimit = 100000;
            var descriptors    = group.Members;

            if (descriptors.Length > batchSizeLimit)
            {
                TeamFoundationIdentity[] identities;
                int batchNum  = 0;
                int remainder = descriptors.Length;
                IdentityDescriptor[] batchDescriptors = new IdentityDescriptor[batchSizeLimit];

                while (remainder > 0)
                {
                    int startAt = batchNum * batchSizeLimit;
                    int length  = batchSizeLimit;
                    if (length > remainder)
                    {
                        length           = remainder;
                        batchDescriptors = new IdentityDescriptor[length];
                    }

                    Array.Copy(descriptors, startAt, batchDescriptors, 0, length);
                    identities = ims.ReadIdentities(batchDescriptors, MembershipQuery.Direct, ReadIdentityOptions.None);
                    resultIdentities.UnionWith(identities);
                    remainder -= length;
                }
            }
            else
            {
                resultIdentities.UnionWith(ims.ReadIdentities(descriptors, MembershipQuery.Direct, ReadIdentityOptions.None));
            }
            var validWebUsers   = resultIdentities.Where(identity => identity.Descriptor.Identifier.EndsWith("@live.com", StringComparison.InvariantCultureIgnoreCase) && identity.IsActive == true && identity.IsContainer == false).ToArray();
            var validLocalUsers = resultIdentities.Where(identity => identity.Descriptor.IdentityType == "System.Security.Principal.WindowsIdentity" && identity.IsActive == true && identity.IsContainer == false).ToArray();
            var users           = validWebUsers.Concat(validLocalUsers).Where(identity => System.Globalization.CultureInfo.InvariantCulture.CompareInfo.IndexOf(identity.DisplayName, "build", System.Globalization.CompareOptions.IgnoreCase) < 0);

            return(users
                   .ToArray());
        }
        public TeamFoundationIdentity GetIdentity(IdentityDescriptor identity)
        {
            var tfsIdentity = _identityService.ReadIdentity(identity, MembershipQuery.Direct, ReadIdentityOptions.None);

            if (tfsIdentity != null)
            {
                return(tfsIdentity);
            }

            var adIdentity = _identityService.ReadIdentity(identity, MembershipQuery.Direct, ReadIdentityOptions.IncludeReadFromSource);

            if (adIdentity != null)
            {
                return(adIdentity);
            }

            throw new Exception($"Identity not found: {identity}");
        }
예제 #15
0
        public async static Task CheckIdentity(WorkItemClientConnection client, string project)
        {
            IdentityHttpClient targetIdentityClient = null;
            var currentUserIdentity    = client.Connection.AuthorizedIdentity;
            IdentityDescriptor adminId = null;

            Logger.LogInformation($"Checking administrative permissions for {client.Connection.AuthorizedIdentity.DisplayName} in {project}");
            try
            {
                targetIdentityClient = client.Connection.GetClient <IdentityHttpClient>();

                var targetIdentity = (await targetIdentityClient.ReadIdentitiesAsync(IdentitySearchFilter.General, "Project Collection Administrators", queryMembership: QueryMembership.Expanded)).FirstOrDefault();
                if (targetIdentity != null)
                {
                    //Check if the current user account running the tool is a member of project collection administrators
                    #region HackRegion
                    adminId = targetIdentity.Members.Where(a => string.Equals(a.Identifier, currentUserIdentity.Descriptor.Identifier, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
                    //We can replace the above code with the following two statements when they work
                    //var me = targetIdentityClient.GetIdentitySelfAsync().Result;
                    //var isMember = targetIdentityClient.IsMember(targetIdentity.Descriptor, currentUserIdentity.Descriptor).Result;
                    #endregion
                }
            }
            catch (Exception e) when(e.InnerException is VssUnauthorizedException)
            {
                throw new ValidationException(client.Connection.Uri.ToString(), (VssUnauthorizedException)e.InnerException);
            }
            catch (Exception e)
            {
                throw new ValidationException("An unexpected error occurred while checking administrative permissions", e);
            }

            if (adminId != null)
            {
                Logger.LogSuccess(LogDestination.All, $"Verified {client.Connection.AuthorizedIdentity.DisplayName} is a Project Collection Administrator in {project}");
            }
            else
            {
                throw new ValidationException($"{currentUserIdentity.Descriptor.Identifier} is not a Project Collection Administrator in {project}. Please follow https://www.visualstudio.com/en-us/docs/setup-admin/add-administrator-tfs on how to add the account to the project collection administrators");
            }
        }
예제 #16
0
        internal static void FetchIdentities(IdentityDescriptor[] descriptors,
                                             List <TeamFoundationIdentity> globalGroups,
                                             Dictionary <IdentityDescriptor, TeamFoundationIdentity> globalIdentities)
        {
            Int64 startTicks = Log.APPLICATION("Enter", Common.LOG_CATEGORY);

            TeamFoundationIdentity[] identities;

            // If total membership exceeds batch size limit for Read, break it up
            int batchSizeLimit = 100000;

            if (descriptors.Length > batchSizeLimit)
            {
                int batchNum  = 0;
                int remainder = descriptors.Length;
                IdentityDescriptor[] batchDescriptors = new IdentityDescriptor[batchSizeLimit];

                while (remainder > 0)
                {
                    int startAt = batchNum * batchSizeLimit;
                    int length  = batchSizeLimit;
                    if (length > remainder)
                    {
                        length           = remainder;
                        batchDescriptors = new IdentityDescriptor[length];
                    }

                    Array.Copy(descriptors, startAt, batchDescriptors, 0, length);
                    identities = AzureDevOpsExplorer.Presentation.Views.Server.IdentityManagementService.ReadIdentities(batchDescriptors, MembershipQuery.Direct, ReadIdentityOptions.None);
                    SortIdentities(identities, globalGroups, globalIdentities);
                    remainder -= length;
                }
            }
            else
            {
                identities = AzureDevOpsExplorer.Presentation.Views.Server.IdentityManagementService.ReadIdentities(descriptors, MembershipQuery.Direct, ReadIdentityOptions.None);
                SortIdentities(identities, globalGroups, globalIdentities);
            }

            Log.APPLICATION("Exit", Common.LOG_CATEGORY, startTicks);
        }
예제 #17
0
        /// <summary>
        /// Checks if a group exists and returns the descriptor.
        /// If the group does not exist, it is created (if the createIfNew flag is set to true).
        /// </summary>
        /// <param name="scope">Scope Id to limit the search area - default (empty string) is collection level.</param>
        /// <param name="groupName">Name of the group. Also used as group description for create.</param>
        /// <param name="createIfNew">Set to true for create. Default is false.</param>
        /// <returns>The IdentityDescriptor of the group. Returns null in case of any errors.</returns>
        private IdentityDescriptor CheckIfGroupExists(string scope, string groupName, bool createIfNew)
        {
            TeamFoundationIdentity tfi = null;

            try
            {
                // Find the group using Account Name
                tfi = idMgmtSvc.ReadIdentity(IdentitySearchFactor.AccountName, groupName,
                                             MembershipQuery.Direct, ReadIdentityOptions.None);

                if (tfi == null && createIfNew)
                {
                    FileHelper.Log("Creating new group..." + groupName);

                    // SCOPE: If a Team Project is found, add the group in that TP.
                    // If not, add the group at collection level.
                    // string scopeId = (teamProjectIdentity == null) ? string.Empty : teamProjectIdentity.Descriptor.Identifier;

                    //string scopeId = tpCollection.Uri.ToString() + "/" + scope;

                    IdentityDescriptor idDesc = idMgmtSvc.CreateApplicationGroup(scope, groupName, groupName);
                    FileHelper.Log("Group creation successful..." + groupName);
                    return(idDesc);
                }
                else
                {
                    FileHelper.Log("Group identity found..." + groupName);
                    return(tfi.Descriptor);
                }
            }
            catch (Exception ex)
            {
                FileHelper.Log(ex.Message);
                FileHelper.Log(ex.StackTrace);
            }
            return(null);
        }
        static void Main(string[] args)
        {
            string project = "http://xxx.xxx.xxx.xxx:8080/tfs";
            TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri(project));
            var tps = tpc.GetService <VersionControlServer>();
            var ttt = tps.GetTeamProject("ProjectName");
            ISecurityService securityService = tpc.GetService <ISecurityService>();

            System.Collections.ObjectModel.ReadOnlyCollection <SecurityNamespace> securityNamespaces = securityService.GetSecurityNamespaces();
            IGroupSecurityService gss             = tpc.GetService <IGroupSecurityService>();
            Identity                 SIDS         = gss.ReadIdentity(SearchFactor.AccountName, "GroupName", QueryMembership.Expanded);//GourName format: [ProjectName]\\GourpName
            IdentityDescriptor       id           = new IdentityDescriptor("Microsoft.TeamFoundation.Identity", SIDS.Sid);
            List <SecurityNamespace> securityList = securityNamespaces.ToList <SecurityNamespace>();
            string securityToken;

            foreach (SecurityNamespace sn in securityList)
            {
                if (sn.Description.DisplayName == "Project")
                {
                    securityToken = "$PROJECT:" + ttt.ArtifactUri.AbsoluteUri;
                    sn.SetPermissions(securityToken, id, 115, 0, true);
                }
            }
        }
        public bool RemoveTeamAdministrator(string team, string user, out string message)
        {
            message = string.Empty;
            bool ret = true;
            TeamFoundationTeam     t = this.teamService.ReadTeam(this.projectInfo.Uri, team, null);
            TeamFoundationIdentity i = this.identityManagementService.ReadIdentity(IdentitySearchFactor.AccountName, user, MembershipQuery.Direct, ReadIdentityOptions.None);

            if (t == null)
            {
                message = "Team [" + team + "] not found";
                ret     = false;
            }

            if (i == null)
            {
                message = "User [" + user + "] not found";
                ret     = false;
            }

            if (ret)
            {
                this.identityManagementService.AddMemberToApplicationGroup(t.Identity.Descriptor, i.Descriptor);
                message = "User removed ";

                IdentityDescriptor descriptor = i.Descriptor;
                string             token      = GetTeamAdminstratorsToken(t);

                ISecurityService  securityService   = this.teamProjectCollection.GetService <ISecurityService>();
                SecurityNamespace securityNamespace =
                    securityService.GetSecurityNamespace(FrameworkSecurity.IdentitiesNamespaceId);

                securityNamespace.RemovePermissions(token, descriptor, 15);
            }

            return(ret);
        }
 private static void ApplySecurityNamespacePermissions(string token, IdentityDescriptor identity, SecurityNamespace securityNamespace, IEnumerable <PermissionChange> permissions)
 {
     if (permissions.Where(p => p.Action != PermissionChangeAction.None).Any())
     {
         var allows   = permissions.Where(p => p.Action == PermissionChangeAction.Allow).Aggregate(0, (sum, p) => sum += p.Permission.PermissionBit);
         var denies   = permissions.Where(p => p.Action == PermissionChangeAction.Deny).Aggregate(0, (sum, p) => sum += p.Permission.PermissionBit);
         var inherits = permissions.Where(p => p.Action == PermissionChangeAction.Inherit).Aggregate(0, (sum, p) => sum += p.Permission.PermissionBit);
         if (allows > 0 || denies > 0 || inherits > 0)
         {
             if (securityNamespace == null)
             {
                 throw new InvalidOperationException("Permissions are being modified but the security namespace is not available in the current Team Project Collection.");
             }
             if (inherits > 0)
             {
                 securityNamespace.RemovePermissions(token, identity, inherits);
             }
             if (allows > 0 || denies > 0)
             {
                 securityNamespace.SetPermissions(token, identity, allows, denies, true);
             }
         }
     }
 }
예제 #21
0
        /// <summary>
        /// Adds the specified user to the TFS security group
        /// </summary>
        /// <param name="groupID">The TFS Security Group identifier</param>
        /// <param name="userName">The User name</param>
        /// <returns>true, if successful.</returns>
        private bool AddMemberToGroup(IdentityDescriptor groupId, string userName)
        {
            try
            {
                TeamFoundationIdentity tfiUser =
                    idMgmtSvc.ReadIdentity(IdentitySearchFactor.AccountName, userName, MembershipQuery.Direct, ReadIdentityOptions.IncludeReadFromSource);

                if (idMgmtSvc.IsMember(groupId, tfiUser.Descriptor))
                {
                    FileHelper.Log("User {0} already part of group {1}", userName, groupId.Identifier);
                }
                else
                {
                    idMgmtSvc.AddMemberToApplicationGroup(groupId, tfiUser.Descriptor);
                    FileHelper.Log("User {0} added to group {1}", userName, groupId.Identifier);
                }
            }
            catch (Exception ex)
            {
                FileHelper.Log(ex.Message);
                return(false);
            }
            return(true);
        }
        private static void ApplyGroupMemberChanges(ApplicationTask task, SecurityGroupChange securityGroup, IdentityDescriptor groupDescriptor, IIdentityManagementService ims, IList <TeamFoundationIdentity> existingMembers)
        {
            var existingMemberAccountNames = existingMembers.Select(m => GetAccountName(m));

            // Remove requested members.
            if (securityGroup.RemoveAllUsers)
            {
                foreach (var member in existingMembers)
                {
                    ims.RemoveMemberFromApplicationGroup(groupDescriptor, member.Descriptor);
                }
            }
            else
            {
                if (!string.IsNullOrEmpty(securityGroup.UsersToRemove))
                {
                    foreach (var userToRemove in securityGroup.UsersToRemove.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(u => u.Trim()))
                    {
                        if (existingMemberAccountNames.Any(m => string.Equals(m, userToRemove, StringComparison.OrdinalIgnoreCase)))
                        {
                            PerformUserAction(task, ims, userToRemove, identityToRemove => ims.RemoveMemberFromApplicationGroup(groupDescriptor, identityToRemove.Descriptor));
                        }
                    }
                }
            }

            // Add requested members.
            if (!string.IsNullOrEmpty(securityGroup.UsersToAdd))
            {
                foreach (var userToAdd in securityGroup.UsersToAdd.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(u => u.Trim()))
                {
                    if (!existingMemberAccountNames.Any(m => string.Equals(m, userToAdd, StringComparison.OrdinalIgnoreCase)))
                    {
                        PerformUserAction(task, ims, userToAdd, identityToAdd => ims.AddMemberToApplicationGroup(groupDescriptor, identityToAdd.Descriptor));
                    }
                }
            }
        }
예제 #23
0
        public void AddMemberToTeam(string teamName, IdentityDescriptor descriptor)
        {
            var groupSid = GetGroupIdentityForTeamName(teamName);

            groupSecurityService.AddMemberToApplicationGroup(groupSid.Sid, descriptor.Identifier);
        }
예제 #24
0
        private TeamFoundationIdentity[] allTfsUsers(TfsConnection tfs)
        {
            try
            {
                IIdentityManagementService ims = tfs.GetService<IIdentityManagementService>();

                TeamFoundationIdentity[] projectGroups = ims.ListApplicationGroups(tfsProject.Project, ReadIdentityOptions.None);
                Dictionary<IdentityDescriptor, object> descSet = new Dictionary<IdentityDescriptor, object>(IdentityDescriptorComparer.Instance);
                foreach (TeamFoundationIdentity projectGroup in projectGroups)
                {
                    descSet[projectGroup.Descriptor] = projectGroup.Descriptor;
                }
                projectGroups = ims.ReadIdentities(descSet.Keys.ToArray(), MembershipQuery.Expanded, ReadIdentityOptions.None);

                foreach (TeamFoundationIdentity projectGroup in projectGroups)
                {
                    foreach (IdentityDescriptor mem in projectGroup.Members)
                    {
                        descSet[mem] = mem;
                    }
                }

                TeamFoundationIdentity[] identities = new TeamFoundationIdentity[0];
                int batchSizeLimit = 100000;
                var descriptors = descSet.Keys.ToArray();

                if (descriptors.Length > batchSizeLimit)
                {
                    int batchNum = 0;
                    int remainder = descriptors.Length;
                    IdentityDescriptor[] batchDescriptors = new IdentityDescriptor[batchSizeLimit];

                    while (remainder > 0)
                    {
                        int startAt = batchNum * batchSizeLimit;
                        int length = batchSizeLimit;
                        if (length > remainder)
                        {
                            length = remainder;
                            batchDescriptors = new IdentityDescriptor[length];
                        }

                        Array.Copy(descriptors, startAt, batchDescriptors, 0, length);
                        identities = ims.ReadIdentities(batchDescriptors, MembershipQuery.Direct, ReadIdentityOptions.None);
                        remainder -= length;
                    }
                }
                else
                {
                    identities = ims.ReadIdentities(descriptors, MembershipQuery.Direct, ReadIdentityOptions.None);
                }

                return identities.Where(_ => !_.IsContainer && _.Descriptor.IdentityType != "Microsoft.TeamFoundation.UnauthenticatedIdentity").ToArray();
            }
            catch
            {
                /* Do nothing */
            }

            return  (tfs != null? new TeamFoundationIdentity[] { tfs.AuthorizedIdentity } : new TeamFoundationIdentity[0]);
        }
예제 #25
0
        private static void AddUserToAccount(string VssAccountName, string VssUserToAddMailAddress, License VssLicense)
        {
            try
            {
                // The first call is to see if the user already exists in the account.
                // Since this is the first call to the service, this will trigger the sign-in window to pop up.
                Console.WriteLine("Sign in as the admin of account {0}. You will see a sign-in window on the desktop.",
                                  VssAccountName);
                var userIdentity = identityClient.ReadIdentitiesAsync(IdentitySearchFilter.AccountName,
                                                                      VssUserToAddMailAddress).Result.FirstOrDefault();
                if (userIdentity == null)
                {
                    var username = VssUserToAddMailAddress.Substring(0, VssUserToAddMailAddress.IndexOf("@"));
                    userIdentity = identityClient.ReadIdentitiesAsync(IdentitySearchFilter.MailAddress, VssUserToAddMailAddress).Result.FirstOrDefault();
                }
                // If the identity is null, this is a user that has not yet been added to the account.
                // We'll need to add the user as a "bind pending" - meaning that the email address of the identity is
                // recorded so that the user can log into the account, but the rest of the details of the identity
                // won't be filled in until first login.
                if (userIdentity == null)
                {
                    Console.WriteLine("Creating a new identity and adding it to the collection's licensed users group.");

                    // We are adding the user to a collection, and at the moment only one collection is supported per
                    // account in VSO.
                    var collectionScope = identityClient.GetScopeAsync(VssAccountName).Result;

                    // First get the descriptor for the licensed users group, which is a well known (built in) group.
                    var licensedUsersGroupDescriptor = new IdentityDescriptor(IdentityConstants.TeamFoundationType,
                                                                              GroupWellKnownSidConstants.LicensedUsersGroupSid);

                    // Now convert that into the licensed users group descriptor into a collection scope identifier.
                    var identifier = String.Concat(SidIdentityHelper.GetDomainSid(collectionScope.Id),
                                                   SidIdentityHelper.WellKnownSidType,
                                                   licensedUsersGroupDescriptor.Identifier.Substring(SidIdentityHelper.WellKnownSidPrefix.Length));

                    // Here we take the string representation and create the strongly-type descriptor
                    var collectionLicensedUsersGroupDescriptor = new IdentityDescriptor(IdentityConstants.TeamFoundationType,
                                                                                        identifier);


                    // Get the domain from the user that runs this code. This domain will then be used to construct
                    // the bind-pending identity. The domain is either going to be "Windows Live ID" or the Azure
                    // Active Directory (AAD) unique identifier, depending on whether the account is connected to
                    // an AAD tenant. Then we'll format this as a UPN string.
                    var currUserIdentity = vssConnection.AuthorizedIdentity.Descriptor;
                    var directory        = "Windows Live ID"; // default to an MSA (fka Live ID)
                    if (currUserIdentity.Identifier.Contains('\\'))
                    {
                        // The identifier is domain\userEmailAddress, which is used by AAD-backed accounts.
                        // We'll extract the domain from the admin user.
                        directory = currUserIdentity.Identifier.Split(new char[] { '\\' })[0];
                    }
                    var upnIdentity = string.Format("upn:{0}\\{1}", directory, VssUserToAddMailAddress);

                    // Next we'll create the identity descriptor for a new "bind pending" user identity.
                    var newUserDesciptor = new IdentityDescriptor(IdentityConstants.BindPendingIdentityType,
                                                                  upnIdentity);

                    // We are ready to actually create the "bind pending" identity entry. First we have to add the
                    // identity to the collection's licensed users group. Then we'll retrieve the Identity object
                    // for this newly-added user. Without being added to the licensed users group, the identity
                    // can't exist in the account.
                    bool result = identityClient.AddMemberToGroupAsync(collectionLicensedUsersGroupDescriptor,
                                                                       newUserDesciptor).Result;
                    userIdentity = identityClient.ReadIdentitiesAsync(IdentitySearchFilter.AccountName,
                                                                      VssUserToAddMailAddress).Result.FirstOrDefault();
                }

                Console.WriteLine("Assigning license to user.");
                var entitlement = licensingClient.AssignEntitlementAsync(userIdentity.Id, VssLicense).Result;

                Console.WriteLine("Success!");
            }
            catch (Exception e)
            {
                using (StreamWriter sw = File.AppendText("fubarAccounts.txt"))
                {
                    sw.WriteLine("{0}, failed, {1}", VssUserToAddMailAddress, e.InnerException.Message);
                }
                Console.WriteLine("\r\nSomething went wrong...");
                Console.WriteLine(e.Message);
                if (e.InnerException != null)
                {
                    Console.WriteLine(e.InnerException.Message);
                }
            }
        }
        /// <summary>
        /// This is the one where all the magic starts.  Main() so to speak.  I will load the settings, connect to TFS and apply the aggregation rules.
        /// </summary>
        public EventNotificationStatus ProcessEvent(
            TeamFoundationRequestContext requestContext,
            NotificationType notificationType,
            object notificationEventArgs,
            out int statusCode,
            out string statusMessage,
            out ExceptionPropertyCollection properties)
        {
            var runtime = RuntimeContext.GetContext(
                GetServerSettingsFullPath,
                new RequestContextWrapper(requestContext),
                new ServerEventLogger(LogLevel.Normal));

            if (runtime.HasErrors)
            {
                statusCode    = 99;
                statusMessage = string.Join(". ", runtime.Errors);
                properties    = null;
                return(EventNotificationStatus.ActionPermitted);
            }

            // HACK: remove cast for ProcessEventException
            var logger = (ServerEventLogger)runtime.Logger;

            var result = new ProcessingResult();

            try
            {
                // Check if we have a workitem changed event before proceeding
                if (notificationType == NotificationType.Notification && notificationEventArgs is WorkItemChangedEvent)
                {
                    var uri = this.GetCollectionUriFromContext(requestContext);

                    IdentityDescriptor toImpersonate = null;
                    if (runtime.Settings.AutoImpersonate)
                    {
                        toImpersonate = this.GetIdentityToImpersonate(requestContext, notificationEventArgs as WorkItemChangedEvent);
                    }

                    using (EventProcessor eventProcessor = new EventProcessor(uri.AbsoluteUri, toImpersonate, runtime))
                    {
                        var context      = runtime.RequestContext;
                        var notification = new NotificationWrapper(
                            notificationType,
                            notificationEventArgs as WorkItemChangedEvent);

                        logger.StartingProcessing(context, notification);
                        result = eventProcessor.ProcessEvent(context, notification);
                        logger.ProcessingCompleted(result);
                    }
                }
            }
            catch (Exception e)
            {
                logger.ProcessEventException(e);

                // notify failure
                result.StatusCode         = -1;
                result.StatusMessage      = "Unexpected error: " + e.Message;
                result.NotificationStatus = EventNotificationStatus.ActionPermitted;
            }

            statusCode    = result.StatusCode;
            statusMessage = result.StatusMessage;
            properties    = result.ExceptionProperties;
            return(result.NotificationStatus);
        }
예제 #27
0
        private async static Task <Guid> AddMemberToAccount(Project project, TraceWriter log)
        {
            string username    = ConfigurationManager.AppSettings.Get("VSTSUserName");
            string pattoken    = ConfigurationManager.AppSettings.Get("VSTSPat");
            string accountName = ConfigurationManager.AppSettings.Get("VSTSAccountName");

            if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(pattoken) || string.IsNullOrWhiteSpace(accountName))
            {
                log.Error("AppSettings missing for VSTSUserName, VSTSPat or VSTSAccountName");
                return(Guid.Empty);
            }

            try
            {
                VssBasicCredential credentials = new VssBasicCredential(username, pattoken);
                VssConnection      connection  = new VssConnection(new Uri($"https://{accountName}.vssps.visualstudio.com/"), credentials);

                var identityClient  = connection.GetClient <IdentityHttpClient>();
                var licensingClient = connection.GetClient <LicensingHttpClient>();
                var userIdentity    = identityClient.ReadIdentitiesAsync(IdentitySearchFilter.AccountName, project.Owner).Result.FirstOrDefault();

                // If the identity is null, this is a user that has not yet been added to the account.
                // We'll need to add the user as a "bind pending" - meaning that the email address of the identity is
                // recorded so that the user can log into the account, but the rest of the details of the identity
                // won't be filled in until first login.
                if (userIdentity != null)
                {
                    log.Info($"User:{project.Owner} already exists in VSTS account with name: {accountName}");
                    return(userIdentity.Id);
                }

                log.Info("Creating a new identity and adding it to the collection's licensed users group.");
                var collectionScope = identityClient.GetScopeAsync(accountName).Result;

                // First get the descriptor for the licensed users group, which is a well known (built in) group.
                var licensedUsersGroupDescriptor = new IdentityDescriptor(IdentityConstants.TeamFoundationType,
                                                                          GroupWellKnownSidConstants.LicensedUsersGroupSid);

                // Now convert that into the licensed users group descriptor into a collection scope identifier.
                var identifier = string.Concat(SidIdentityHelper.GetDomainSid(collectionScope.Id),
                                               SidIdentityHelper.WellKnownSidType,
                                               licensedUsersGroupDescriptor.Identifier.Substring(SidIdentityHelper.WellKnownSidPrefix.Length));

                // Here we take the string representation and create the strongly-type descriptor
                var collectionLicensedUsersGroupDescriptor = new IdentityDescriptor(IdentityConstants.TeamFoundationType,
                                                                                    identifier);

                // Get the domain from the user that runs this code. This domain will then be used to construct
                // the bind-pending identity. The domain is either going to be "Windows Live ID" or the Azure
                // Active Directory (AAD) unique identifier, depending on whether the account is connected to
                // an AAD tenant. Then we'll format this as a UPN string.
                var currUserIdentity = connection.AuthorizedIdentity.Descriptor;
                if (!currUserIdentity.Identifier.Contains('\\'))
                {
                    log.Error("Could not find directory for user");
                    return(Guid.Empty);
                }

                // The identifier is domain\userEmailAddress, which is used by AAD-backed accounts.
                // We'll extract the domain from the admin user.
                var directory   = currUserIdentity.Identifier.Split(new char[] { '\\' })[0];
                var upnIdentity = string.Format("upn:{0}\\{1}", directory, project.Owner);

                // Next we'll create the identity descriptor for a new "bind pending" user identity.
                var newUserDesciptor = new IdentityDescriptor(IdentityConstants.BindPendingIdentityType,
                                                              upnIdentity);

                // We are ready to actually create the "bind pending" identity entry. First we have to add the
                // identity to the collection's licensed users group. Then we'll retrieve the Identity object
                // for this newly-added user. Without being added to the licensed users group, the identity
                // can't exist in the account.
                bool result = identityClient.AddMemberToGroupAsync(collectionLicensedUsersGroupDescriptor,
                                                                   newUserDesciptor).Result;
                userIdentity = identityClient.ReadIdentitiesAsync(IdentitySearchFilter.AccountName,
                                                                  project.Owner).Result.FirstOrDefault();

                log.Info("Assigning license to user.");
                Microsoft.VisualStudio.Services.Licensing.License licence = GetLicense();
                var entitlement = licensingClient.AssignEntitlementAsync(userIdentity.Id, licence, false).Result;
                log.Info($"Added {project.Owner} as a user with license:{licence.ToString()} to account with name:{accountName}");
                return(userIdentity.Id);
            }
            catch (Exception e)
            {
                log.Error(e.Message);
                return(Guid.Empty);
            }
        }
예제 #28
0
 public void WorkItemRepositoryBuilt(Uri uri, IdentityDescriptor toImpersonate)
 {
     if (toImpersonate != null)
     {
         this.logger.Log(LogLevel.Verbose, "Built a new Work Item Repository for {0} as {1}", uri, toImpersonate);
     }
     else
     {
         this.logger.Log(LogLevel.Diagnostic, "Built a new Work Item Repository for {0}", uri);
     }
 }
 static partial void RealInstanceFactory(ref IdentityDescriptor real, string callerName)
 {
     real = (IdentityDescriptor)FormatterServices.GetUninitializedObject(typeof(IdentityDescriptor));
 }
예제 #30
0
 public ConnectionInfo(Uri uri, IdentityDescriptor toImpersonate)
 {
     this.ProjectCollectionUri = uri;
     this.Impersonate          = toImpersonate;
 }
예제 #31
0
        private TeamFoundationIdentity[] allTfsUsers(TfsConnection tfs)
        {
            try
            {
                IIdentityManagementService ims = tfs.GetService <IIdentityManagementService>();

                TeamFoundationIdentity[] projectGroups          = ims.ListApplicationGroups(tfsProject.Project, ReadIdentityOptions.None);
                Dictionary <IdentityDescriptor, object> descSet = new Dictionary <IdentityDescriptor, object>(IdentityDescriptorComparer.Instance);
                foreach (TeamFoundationIdentity projectGroup in projectGroups)
                {
                    descSet[projectGroup.Descriptor] = projectGroup.Descriptor;
                }
                projectGroups = ims.ReadIdentities(descSet.Keys.ToArray(), MembershipQuery.Expanded, ReadIdentityOptions.None);

                foreach (TeamFoundationIdentity projectGroup in projectGroups)
                {
                    foreach (IdentityDescriptor mem in projectGroup.Members)
                    {
                        descSet[mem] = mem;
                    }
                }

                TeamFoundationIdentity[] identities = new TeamFoundationIdentity[0];
                int batchSizeLimit = 100000;
                var descriptors    = descSet.Keys.ToArray();

                if (descriptors.Length > batchSizeLimit)
                {
                    int batchNum  = 0;
                    int remainder = descriptors.Length;
                    IdentityDescriptor[] batchDescriptors = new IdentityDescriptor[batchSizeLimit];

                    while (remainder > 0)
                    {
                        int startAt = batchNum * batchSizeLimit;
                        int length  = batchSizeLimit;
                        if (length > remainder)
                        {
                            length           = remainder;
                            batchDescriptors = new IdentityDescriptor[length];
                        }

                        Array.Copy(descriptors, startAt, batchDescriptors, 0, length);
                        identities = ims.ReadIdentities(batchDescriptors, MembershipQuery.Direct, ReadIdentityOptions.None);
                        remainder -= length;
                    }
                }
                else
                {
                    identities = ims.ReadIdentities(descriptors, MembershipQuery.Direct, ReadIdentityOptions.None);
                }

                return(identities.Where(_ => !_.IsContainer && _.Descriptor.IdentityType != "Microsoft.TeamFoundation.UnauthenticatedIdentity").ToArray());
            }
            catch
            {
                /* Do nothing */
            }

            return(tfs != null? new TeamFoundationIdentity[] { tfs.AuthorizedIdentity } : new TeamFoundationIdentity[0]);
        }
예제 #32
0
        /// <summary>
        /// Adds a domain user to a TFS Security group, at a collection level. If the group does not exist, it will be created.
        /// The method will assume the context of the executing user.
        /// i.e.: To add a domain user, execute in the context of a domain user.
        /// Usage Scenarios:
        /// 1. Use this method to add a given user to multiple groups
        /// 2. Use this method to add multiple users to multiple groups
        /// </summary>
        /// <param name="user2Groups">A list of user to groups mapping</param>
        /// <returns></returns>
        public ReturnCode AddUsersToGroups(List <User2GroupsMap> user2Groups)
        {
            if (tpCollection == null)
            {
                FileHelper.Log("Collection not initialized.");
                return(ReturnCode.Failure);
            }

            int errorCount = 0;
            int iteration  = 0;

            try
            {
                if (user2Groups == null || user2Groups.Capacity <= 0)
                {
                    FileHelper.Log("Users 2 Groups mapping is not available.");
                    return(ReturnCode.Failure);
                }

                // For each User to Groups mapping
                foreach (User2GroupsMap u2gmap in user2Groups)
                {
                    string userName = u2gmap.UserName;
                    // For each team project listed
                    // Note that the tool assumes that if there are more than one team project specified,
                    // the user wants to add all groups listed to all team projects
                    foreach (string teamProjName in u2gmap.TeamProjectNames)
                    {
                        ProjectInfo objTeamProj = GetProject(teamProjName);
                        iteration++;
                        if (objTeamProj != null)
                        {
                            FileHelper.Log("Team Project: {0} found", objTeamProj.Name);
                            // For each group name specified
                            foreach (string grpName in u2gmap.GroupNames)
                            {
                                iteration++;
                                string searchableGroupName = string.Format(GROUP_NAME_FORMAT, teamProjName, grpName);
#if TFS10
                                bool success = CheckIfGroupExists_TFS10(objTeamProj.Uri, searchableGroupName, grpName, true);
                                if (success)
                                {
                                    iteration++;
                                    if (!AddMemberToGroup_TFS10(objTeamProj.Name, searchableGroupName, userName))
                                    {
                                        FileHelper.Log("Failed to add user {0} to group {1}", userName, grpName);
                                        errorCount++;
                                    }
                                }
                                else
                                {
                                    errorCount++;
                                }
#else
                                IdentityDescriptor groupId = CheckIfGroupExists(objTeamProj.Uri, searchableGroupName, true);

                                if (groupId != null)
                                {
                                    if (AddMemberToGroup(groupId, userName))
                                    {
                                        FileHelper.Log("User {0} added to group {1}", userName, searchableGroupName);
                                    }
                                    else
                                    {
                                        FileHelper.Log("Failed to add user {0} to group {1}", userName, searchableGroupName);
                                        errorCount++;
                                    }
                                }
                                else
                                {
                                    errorCount++;
                                }
#endif
                            }
                        }
                        else
                        {
                            errorCount++;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                FileHelper.Log(ex.Message);
                return(ReturnCode.Failure);
            }
            return(GetReturnCode(iteration, errorCount));
        }
예제 #33
0
 static partial void RealInstanceFactory(ref IdentityDescriptor real, [CallerMemberName] string callerName        = "");
예제 #34
0
 /// <summary>
 /// Remove a particular user from all groups at a collection level
 /// </summary>
 /// <param name="tfiPCValidUsers">The identity of ProjectCollectionValidUsers group</param>
 /// <param name="userIdentity">The identity of the user to be removed</param>
 /// <returns>True, if successful</returns>
 private bool RemoveUserFromAllGroupsInCollection(TeamFoundationIdentity tfiPCValidUsers, IdentityDescriptor userIdentity)
 {
     foreach (IdentityDescriptor groupDesc in tfiPCValidUsers.Members)
     {
         if (idMgmtSvc.IsMember(groupDesc, userIdentity))
         {
             try
             {
                 idMgmtSvc.RemoveMemberFromApplicationGroup(groupDesc, userIdentity);
             }
             catch (Exception ex)
             {
                 FileHelper.Log(ex.Message);
                 FileHelper.Log(ex.StackTrace);
             }
         }
     }
     return(true);
 }