Esempio n. 1
0
        public async static Task CheckBypassRulesPermission(WorkItemClientConnection client, string project)
        {
            try
            {
                var securityHttpClient = client.Connection.GetClient <SecurityHttpClient>();
                var namespaces         = await securityHttpClient.QuerySecurityNamespacesAsync(ProjectSecurityNamespace);

                if (namespaces.SelectMany(n => n.Actions).Any(a => a.Bit == BypassRulesPermission))
                {
                    await CheckPermission(client, project, ProjectSecurityNamespace, BypassRulesPermission);
                    await CheckPermission(client, project, ProjectSecurityNamespace, SuppressNotificationsPermission);

                    Logger.LogSuccess(LogDestination.All, $"Verified {client.Connection.AuthorizedIdentity.DisplayName} has bypass rules permission in {project}");
                    return;
                }
            }
            catch (ValidationException)
            {
                // no op, fallback to the legacy check
            }
            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 validating project permissions", e);
            }

            // granular permissions not available, or the check failed.  falling back to legacy PCA check
            await CheckLegacyBypassRulesPermission(client, project);
        }
        private async static Task CheckProjectPermission(WorkItemClientConnection client, string project, int requestedPermission)
        {
            Logger.LogInformation($"Checking project security permissions for {client.Connection.AuthorizedIdentity.DisplayName} in {project}");

            SecurityHttpClient securityHttpClient = null;
            ProjectHttpClient  projectHttpClient  = null;
            TeamProject        teamProject        = null;

            try
            {
                securityHttpClient = client.Connection.GetClient <SecurityHttpClient>();
                projectHttpClient  = client.Connection.GetClient <ProjectHttpClient>();
                teamProject        = await projectHttpClient.GetProject(project);
            }
            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 reading the classification nodes to validate project permissions", e);
            }

            await HasPermission(securityHttpClient, project, $"$PROJECT:vstfs:///Classification/TeamProject/{teamProject.Id}", ProjectSecurityNamespace, requestedPermission);
        }
Esempio n. 3
0
        public async static Task CheckConnection(WorkItemClientConnection client, string project, int requestedPermission)
        {
            Logger.LogInformation($"Checking security permissions for {client.Connection.AuthorizedIdentity.DisplayName} in {project}");
            bool hasPermission = false;

            SecurityHttpClient         securityHttpClient = null;
            WorkItemClassificationNode result             = null;

            try
            {
                securityHttpClient = client.Connection.GetClient <SecurityHttpClient>();
                result             = await WorkItemTrackingHelpers.GetClassificationNode(client.WorkItemTrackingHttpClient, project, TreeStructureGroup.Areas);
            }
            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 reading the classification nodes to validate project permissions", e);
            }

            //construct the token by appending the id
            string token = $"vstfs:///Classification/Node/{result.Identifier}";

            //WORK_ITEM guid is hardcoded below
            //securityNameSpaceId for WORK_ITEM is 83e28ad4-2d72-4ceb-97b0-c7726d5502c3
            try
            {
                hasPermission = await securityHttpClient.HasPermissionAsync(
                    new Guid("83e28ad4-2d72-4ceb-97b0-c7726d5502c3"),
                    token,
                    requestedPermission,
                    false);
            }
            catch (Exception e)
            {
                throw new ValidationException($"An unexpected error occurred while trying to check permissions for project {project}", e);
            }

            if (hasPermission)
            {
                Logger.LogSuccess(LogDestination.All, $"Verified security permissions for {project} project");
            }
            else
            {
                throw new ValidationException($"You do not have the necessary security permissions for {project}, work item {(requestedPermission == WritePermission ? "write" : "read")} permissions are required.");
            }
        }
Esempio n. 4
0
        private async static Task CheckPermission(WorkItemClientConnection client, string project, Guid securityNamespace, int requestedPermission)
        {
            Logger.LogInformation($"Checking security permissions for {client.Connection.AuthorizedIdentity.DisplayName} in {project}");
            bool hasPermission = false;

            SecurityHttpClient         securityHttpClient = null;
            WorkItemClassificationNode result             = null;

            try
            {
                securityHttpClient = client.Connection.GetClient <SecurityHttpClient>();
                result             = await WorkItemTrackingHelpers.GetClassificationNode(client.WorkItemTrackingHttpClient, project, TreeStructureGroup.Areas);
            }
            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 reading the classification nodes to validate project permissions", e);
            }

            //construct the token by appending the id
            string token = $"vstfs:///Classification/Node/{result.Identifier}";

            try
            {
                hasPermission = await securityHttpClient.HasPermissionAsync(
                    securityNamespace,
                    token,
                    requestedPermission,
                    false);
            }
            catch (Exception e)
            {
                throw new ValidationException($"An unexpected error occurred while trying to check permissions for project {project} in namespace {securityNamespace}", e);
            }

            if (hasPermission)
            {
                Logger.LogSuccess(LogDestination.All, $"Verified security permissions for {project} project");
            }
            else
            {
                throw new ValidationException($"You do not have the necessary security permissions for {project}, work item permission: {requestedPermission} is required.");
            }
        }
Esempio n. 5
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");
            }
        }
        private async static Task CheckCssPermission(WorkItemClientConnection client, string project, int requestedPermission)
        {
            Logger.LogInformation($"Checking css security permissions for {client.Connection.AuthorizedIdentity.DisplayName} in {project}");

            SecurityHttpClient         securityHttpClient = null;
            WorkItemClassificationNode result             = null;

            try
            {
                securityHttpClient = client.Connection.GetClient <SecurityHttpClient>();
                result             = await WorkItemTrackingHelpers.GetClassificationNode(client.WorkItemTrackingHttpClient, project, TreeStructureGroup.Areas);
            }
            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 reading the classification nodes to validate project permissions", e);
            }

            await HasPermission(securityHttpClient, project, $"vstfs:///Classification/Node/{result.Identifier}", CssSecurityNamespace, requestedPermission);
        }
Esempio n. 7
0
 public async static Task CheckReadPermission(WorkItemClientConnection client, string project)
 {
     await CheckPermission(client, project, CssSecurityNamespace, ReadPermission);
 }
 public async static Task CheckReadPermission(WorkItemClientConnection client, string project)
 {
     await CheckCssPermission(client, project, ReadPermission);
 }