public override void Disassociate(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities)
 {
     if (DisassociateAction != null)
     {
         DisassociateAction(Service, entityName, entityId, relationship, relatedEntities);
     }
     else if (DisassociateActions != null)
     {
         if (DisassociateCache == null)
         {
             DisassociateCache = Service;
             foreach (var disassociate in DisassociateActions)
             {
                 DisassociateCache = new FakeIOrganizationService(DisassociateCache)
                 {
                     DisassociateAction = disassociate
                 };
             }
         }
         DisassociateCache.Disassociate(entityName, entityId, relationship, relatedEntities);
     }
     else
     {
         if (ExecutionTracingEnabled)
         {
             Timer.Time(DisassociateInternal, new Tuple <string, Guid, Relationship, EntityReferenceCollection>(entityName, entityId, relationship, relatedEntities),
                        "Disassociate {0}:{1} using relationship {2} to releated Entities {3}: {4}",
                        entityName, entityId, relationship, relatedEntities.Select(e => e.GetNameId()).ToCsv());
         }
         else
         {
             Service.Disassociate(entityName, entityId, relationship, relatedEntities);
         }
     }
 }
Beispiel #2
0
        public void Associate(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities)
        {
            if (!relatedEntities.Any()) { throw new ArgumentException("Must contain at least one related entity!", nameof(relatedEntities)); }
            if (relatedEntities.Any(e => e.LogicalName != relatedEntities.First().LogicalName)) { throw new NotImplementedException("Don't currently Support different Entity Types for related Entities!"); }

            if (relationship.PrimaryEntityRole.GetValueOrDefault(EntityRole.Referenced) == EntityRole.Referencing)
            {
                throw new NotImplementedException("Referencing Not Currently Implemented");
            }

            var referencedIdName = EntityHelper.GetIdAttributeName(entityName);
            var referencingIdName = EntityHelper.GetIdAttributeName(relatedEntities.First().LogicalName);
            if (referencedIdName == referencingIdName)
            {
                referencedIdName += "one";
                referencingIdName += "two";
            }


            foreach (var relation in relatedEntities.Select(relatedEntity => new Entity(relationship.SchemaName)
            {
                [referencedIdName] = entityId,
                [referencingIdName] = relatedEntity.Id
            }))
            {
                Service.Create(relation);
            }
        }
        /// <summary>
        /// Creates the Association
        /// </summary>
        /// <param name="service">The service.</param>
        /// <param name="entityName">Type: String. The logical name of the entity that is specified in the <paramref name="entityId" /> parameter.</param>
        /// <param name="entityId">Type: Guid. The Id of the record to which the related records are associated.</param>
        /// <param name="relationship">Type: <see cref="T:Microsoft.Xrm.Sdk.Relationship" />. The name of the relationship to be used to create the link.</param>
        /// <param name="relatedEntities">Type: <see cref="T:Microsoft.Xrm.Sdk.EntityReferenceCollection" />. A collection of entity references (references to records) to be associated.</param>
        public Guid[] CreateAssociation(IOrganizationService service, string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities)
        {
            if (!DefinitionsByRelationshipName.TryGetValue(relationship.SchemaName, out var definition))
            {
                throw new KeyNotFoundException($"Schema name {relationship.SchemaName} was not found in the DefinitionsByRelationshipName dictionary.");
            }

            var primaryAttributeName = entityName == definition.PrimaryEntityType
                ? definition.PrimaryEntityIdName
                : definition.AssociatedEntityIdName;
            var associatedAttributeName = entityName == definition.PrimaryEntityType
                ? definition.AssociatedEntityIdName
                : definition.PrimaryEntityIdName;
            var ids = new List <Guid>();

            foreach (var relation in relatedEntities.Select(relatedEntity => new Entity(definition.AssociationLogicalName)
            {
                [primaryAttributeName] = entityId,
                [associatedAttributeName] = relatedEntity.Id
            }))
            {
                ids.Add(service.Create(relation));
            }

            return(ids.ToArray());
        }
Beispiel #4
0
 public override void Associate(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities)
 {
     if (AssociateAction != null)
     {
         AssociateAction(Service, entityName, entityId, relationship, relatedEntities);
     }
     else if (AssociateActions != null)
     {
         if (AssociateCache == null)
         {
             AssociateCache = Service;
             foreach (var action in AssociateActions)
             {
                 AssociateCache = new FakeIOrganizationService(AssociateCache)
                 {
                     AssociateAction = action
                 };
             }
         }
         AssociateCache.Associate(entityName, entityId, relationship, relatedEntities);
     }
     else
     {
         if (ExecutionTracingEnabled)
         {
             Timer.Time(AssociateInternal, new Tuple <string, Guid, Relationship, EntityReferenceCollection>(entityName, entityId, relationship, relatedEntities),
                        "Associate {0}:{1} using relationship {2} to releated Entities {3}: {4}",
                        entityName, entityId, relationship, String.Join(", ", relatedEntities.Select(e => e.GetNameId())));
         }
         else
         {
             Service.Associate(entityName, entityId, relationship, relatedEntities);
         }
     }
 }
Beispiel #5
0
        public void Disassociate(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities)
        {
            if (!relatedEntities.Any())
            {
                throw new ArgumentException("Must contain at least one related entity!", "relatedEntities");
            }
            if (relatedEntities.Any(e => e.LogicalName != relatedEntities.First().LogicalName))
            {
                throw new NotImplementedException("Don't currently Support different Entity Types for related Entities!");
            }

            if (relationship.PrimaryEntityRole.GetValueOrDefault(EntityRole.Referenced) == EntityRole.Referencing)
            {
                throw new NotImplementedException("Referencing Not Currently Implemented");
            }

            var referencedIdName  = EntityHelper.GetIdAttributeName(entityName);
            var referencingIdName = EntityHelper.GetIdAttributeName(relatedEntities.First().LogicalName);

            if (referencedIdName == referencingIdName)
            {
                referencedIdName  += "one";
                referencingIdName += "two";
            }


            foreach (var entity in relatedEntities.
                     Select(e => QueryExpressionFactory.Create(relationship.SchemaName, referencedIdName, entityId, referencingIdName, e.Id)).
                     Select(qe => Service.RetrieveMultiple(qe).ToEntityList <Entity>().FirstOrDefault()).
                     Where(entity => entity != null))
            {
                Service.Delete(entity);
            }
        }
Beispiel #6
0
        /// <summary>
        /// Iterates and displays the entity references in the entity reference collection.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <param name="info">Optional arguments.</param>
        public static string ToStringDebug(this EntityReferenceCollection collection, StringDebugInfo info = null)
        {
            if (collection == null)
            {
                return("null");
            }

            return(Wrap("[",
                        collection.Select(r => r.ToStringDebug()),
                        "]",
                        info));
        }
 private void Associate1ToN(Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities,
                            string referencedIdName, string referencingIdName)
 {
     foreach (var relation in relatedEntities.Select(relatedEntity => new Entity(relationship.SchemaName)
     {
         [referencedIdName] = entityId,
         [referencingIdName] = relatedEntity.Id
     }))
     {
         Service.Create(relation);
     }
 }
 private void Disassociate1ToN(Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities,
                               string referencedIdName, string referencingIdName)
 {
     foreach (var entity in relatedEntities
              .Select(e => QueryExpressionFactory.Create(relationship.SchemaName, referencedIdName, entityId,
                                                         referencingIdName, e.Id))
              .Select(qe => Service.RetrieveMultiple(qe).ToEntityList <Entity>().FirstOrDefault())
              .Where(entity => entity != null))
     {
         Service.Delete(entity);
     }
 }
        public void Disassociate(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities)
        {
            bag.trace($"Disassociate({entityName}, {entityId}, {relationship.SchemaName}, {relatedEntities.Count})");
            if (bag.TracingService.Verbose)
            {
                bag.trace("Disassociated record(s):{0}", relatedEntities.Select(r => $"\n  {r.LogicalName} {r.Id} {r.Name}"));
            }
            var watch = Stopwatch.StartNew();

            service.Disassociate(entityName, entityId, relationship, relatedEntities);
            watch.Stop();
            bag.trace($"Disassociated in: {watch.ElapsedMilliseconds} ms");
        }
Beispiel #10
0
        protected void HandleOwnerTeamMembership(LocalPluginContext localContext, EntityReference target, EntityReferenceCollection refs)
        {
            localContext.Trace($"Handling TeamMembership '{localContext.PluginExecutionContext.MessageName}' operation via 'opc_teams_teams_owneraadassociation'.");

            // Isolate teamIds and queueIds
            Guid[] affectedAADTeamIds, ownerTeamId, unaffectedTeamIds = null;
            affectedAADTeamIds = refs.Select(t => t.Id).ToArray();
            ownerTeamId        = new[] { target.Id };

            localContext.Trace($"There is {affectedAADTeamIds.Count()} affected AAD teams ({string.Join(",", affectedAADTeamIds)})");
            localContext.Trace($"There is {ownerTeamId.Count()} affected owner teams: {string.Join(",", ownerTeamId)}");

            // If it's a disassociate operation we will need all the AAD teams associated to the owner team to ensure
            // the user does not have access through another team
            if (localContext.PluginExecutionContext.MessageName == PluginMessage.Disassociate)
            {
                // Build and execute query to get all AAD teams associated to the owner team that should not be affected by this change
                unaffectedTeamIds = FetchUnaffectedAADTeamsByOwnerTeams(localContext, ownerTeamId, affectedAADTeamIds);
                localContext.Trace($"There is {unaffectedTeamIds.Count()} unaffected AAD teams ({string.Join(",", unaffectedTeamIds)})");
            }

            // Build and execute fetch query to get all users associated to AAD teams but only keep the ones which are not associated to unaffected AAD teams
            var usersInTeams = FetchUsersByTeams(localContext, unaffectedTeamIds, affectedAADTeamIds, ownerTeamId);

            localContext.Trace($"There is {usersInTeams.Count()} users affected ({string.Join(",", usersInTeams)})");

            // Add owner teams to users who don't have the owner team already.
            if (localContext.PluginExecutionContext.MessageName == PluginMessage.Associate)
            {
                // Build and execute query to get all users associated to the owner teams
                var usersInOwnerTeams = FetchOwnerTeamMembershipByOwnerTeams(localContext, ownerTeamId);
                localContext.Trace($"There is {usersInOwnerTeams.Count()} users associated to affected owner teams: ({string.Join(",", usersInOwnerTeams)})");

                // Add owner teams to users who don't have the owner team already.
                var toAdd = usersInTeams.Except(usersInOwnerTeams).Select(u => new EntityReference("systemuser", u)).ToList();
                foreach (var teamId in ownerTeamId)
                {
                    localContext.Trace($"Adding {toAdd.Count()} users to owner team '{teamId}'");
                    localContext.OrganizationService.Associate("team", teamId, new Relationship("teammembership_association"), new EntityReferenceCollection(toAdd));
                }
            }
            else if (localContext.PluginExecutionContext.MessageName == PluginMessage.Disassociate)
            {
                var toRemove = usersInTeams.Select(u => new EntityReference("systemuser", u)).ToList();
                foreach (var teamId in ownerTeamId)
                {
                    localContext.Trace($"Removing {toRemove.Count()} users from owner team '{teamId}'");
                    localContext.OrganizationService.Disassociate("team", teamId, new Relationship("teammembership_association"), new EntityReferenceCollection(toRemove));
                }
            }
        }
Beispiel #11
0
        private void AddMembersToTeam(Guid?TeamId, EntityReferenceCollection Users, IOrganizationService service)
        {
            Guid[] UserIds;
            //get user
            AddMembersTeamRequest addRequest = new AddMembersTeamRequest();

            if (TeamId.HasValue)
            {
                addRequest.TeamId    = TeamId.Value;
                UserIds              = Users.Select(x => x.Id).ToArray();
                addRequest.MemberIds = UserIds;
                tracingService.Trace("before updating ");
                service.Execute(addRequest);
                tracingService.Trace("after updating ");
            }
        }
        public override void Execute()
        {
            var record = _crmContext.RecordCache.Get(_alias);
            var md     = GlobalTestingContext.Metadata.GetEntityMetadata(record.LogicalName, EntityFilters.Relationships);

            var relationship = md.ManyToManyRelationships.FirstOrDefault(r => (r.Entity1LogicalName == record.LogicalName && r.Entity2LogicalName == _relatedEntityName) ||
                                                                         (r.Entity1LogicalName == _relatedEntityName && r.Entity2LogicalName == record.LogicalName));

            if (relationship == null)
            {
                throw new TestExecutionException(Constants.ErrorCodes.N_N_RELATIONSHIP_NOT_FOUND, record.LogicalName, _relatedEntityName);
            }

            Logger.WriteLine($"Using relationship {relationship.SchemaName}");

            EntityReferenceCollection records = new EntityReferenceCollection();

            foreach (var row in _expectedRecords.Rows)
            {
                var lookupValue = ObjectConverter.GetLookupValue(_crmContext, row[Constants.SpecFlow.TABLE_VALUE], _relatedEntityName);
                if (lookupValue == null)
                {
                    throw new TestExecutionException(Constants.ErrorCodes.RECORD_NOT_FOUND, row[Constants.SpecFlow.TABLE_VALUE], _relatedEntityName);
                }
                records.Add(lookupValue);
            }

            var currentRecordFieldName = relationship.Entity1LogicalName == record.LogicalName ? relationship.Entity1IntersectAttribute : relationship.Entity2IntersectAttribute;
            var relatedFieldName       = relationship.Entity1LogicalName == _relatedEntityName ? relationship.Entity1IntersectAttribute : relationship.Entity2IntersectAttribute;

            var query = new QueryExpression(relationship.IntersectEntityName);

            query.ColumnSet.AddColumn(relatedFieldName);
            query.Criteria.AddCondition(currentRecordFieldName, ConditionOperator.Equal, record.Id);
            query.Criteria.AddCondition(relatedFieldName, ConditionOperator.In, records.Select(r => (object)r.Id).ToArray());
            var result = GlobalTestingContext.ConnectionManager.CurrentConnection.RetrieveMultiple(query);

            Assert.AreEqual(records.Count, result.Entities.Count, $"Different records: {string.Join(", ", records.Where(r => !result.Entities.Select(e => e.GetAttributeValue<Guid>(relatedFieldName)).Contains(r.Id)).Select(r => r.Name))}");
        }
        public void ApplyRulesToUser(EntityReferenceCollection ec, Guid userId, bool isOutlookFilter)
        {
            var tempUserId = ((CrmServiceClient)service).CallerId;

            ((CrmServiceClient)service).CallerId = userId;

            try
            {
                // TODO ICI
                var existingQueries = service.RetrieveMultiple(new QueryExpression("userquery")
                {
                    Criteria = new FilterExpression
                    {
                        Conditions =
                        {
                            new ConditionExpression("parentqueryid", ConditionOperator.In, ec.Select(e => e.Id).ToArray())
                        }
                    }
                }).Entities;

                var transac = new ExecuteTransactionRequest
                {
                    Requests        = new OrganizationRequestCollection(),
                    ReturnResponses = false
                };

                foreach (var query in existingQueries)
                {
                    transac.Requests.Add(new DeleteRequest {
                        Target = query.ToEntityReference()
                    });
                }

                transac.Requests.Add(new InstantiateFiltersRequest
                {
                    UserId             = userId,
                    TemplateCollection = ec
                });

                service.Execute(transac);
            }
            finally
            {
                ((CrmServiceClient)service).CallerId = tempUserId;
            }
        }
        /// <inheritdoc />
        public void Disassociate(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities)
        {
            var message = Settings.LogDetailedRequests
                ? $"Disassociate Request for {entityName}, with Id {entityId}, Relationship {relationship.SchemaName}, and Related Entities {relatedEntities.Select(e => e.ToStringDebug()).ToCsv()}."
                : "Disassociate Request";

            if (Settings.TimeRequests)
            {
                var timer = new Stopwatch();
                try
                {
                    TraceStart(message);
                    timer.Start();
                    Service.Disassociate(entityName, entityId, relationship, relatedEntities);
                    return;
                }
                finally
                {
                    TraceEnd(timer);
                }
            }

            TraceExecute(message);
            Service.Disassociate(entityName, entityId, relationship, relatedEntities);
        }
 public override void Disassociate(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities)
 {
     if (DisassociateAction != null)
     {
         DisassociateAction(Service, entityName, entityId, relationship, relatedEntities);
     }
     else if (DisassociateActions != null)
     {
         if (DisassociateCache == null)
         {
             DisassociateCache = Service;
             foreach (var disassociate in DisassociateActions)
             {
                 DisassociateCache = new FakeIOrganizationService(DisassociateCache) {DisassociateAction = disassociate};
             }
         }
         DisassociateCache.Disassociate(entityName, entityId, relationship, relatedEntities);
     }
     else
     {
         if (ExecutionTracingEnabled)
         {
             Timer.Time(DisassociateInternal, new Tuple<string, Guid, Relationship, EntityReferenceCollection>(entityName, entityId, relationship, relatedEntities),
                 "Disassociate {0}:{1} using relationship {2} to releated Entities {3}: {4}",
                 entityName, entityId, relationship, String.Join(", ", relatedEntities.Select(e => e.GetNameId())));
         }
         else
         {
             Service.Disassociate(entityName, entityId, relationship, relatedEntities);
         }
     }
 }
Beispiel #16
0
        protected void HandleAADTeamMembership(LocalPluginContext localContext, EntityReference target, EntityReferenceCollection refs)
        {
            localContext.Trace($"Handling TeamMembership '{localContext.PluginExecutionContext.MessageName}' operation via 'teammembership_association'.");

            // Regardless of which side the relation was triggered; isolate teamIds and userIds
            Guid[] systemuserIds, affectedTeamIds, unaffectedTeamIds = null;
            systemuserIds   = target.LogicalName == "systemuser" ? new[] { target.Id } : refs.Select(u => u.Id).ToArray();
            affectedTeamIds = target.LogicalName == "team" ? new[] { target.Id } : refs.Select(t => t.Id).ToArray();

            localContext.Trace($"There is {affectedTeamIds.Count()} affected teams ({string.Join(",", affectedTeamIds)})");
            localContext.Trace($"There is {systemuserIds.Count()} affected users ({string.Join(",", systemuserIds)})");

            if (!systemuserIds.Any() || !affectedTeamIds.Any())
            {
                return;
            }

            // If it's a disassociate operation we will need all the AAD teams associated to the user to ensure
            // the user does not have access through another team
            if (localContext.PluginExecutionContext.MessageName == PluginMessage.Disassociate)
            {
                // Build and execute fetch query to get all AAD teams of the users which should not be affected by this change
                unaffectedTeamIds = FetchUnaffectedTeamsByUsers(localContext, systemuserIds, affectedTeamIds);
                localContext.Trace($"There is {unaffectedTeamIds.Count()} unaffected teams: {string.Join(",", unaffectedTeamIds)}");
            }

            // Build and execute fetch query to fetch all owner teams associated to AAD teams but only keep the ones which are not referenced in unaffected teams
            var ownerTeams = FetchAffectedOwnerTeams(localContext, unaffectedTeamIds, affectedTeamIds);

            localContext.Trace($"There are {ownerTeams.Count()} owner teams affected: ({string.Join(",", ownerTeams)})");

            // Build and execute fetch query to fetch all teams with their team types.
            var teams = FetchAllTeamsWithType(localContext);

            if (localContext.PluginExecutionContext.MessageName == PluginMessage.Associate)
            {
                // Build and execute query to fetch owner teams associated to users
                var userOwnerTeams = FetchOwnerTeamMembershipByUsers(localContext, systemuserIds);
                userOwnerTeams = userOwnerTeams.Except(teams.Where(t => t.TeamType == TeamTeamType.AADSecurityGroup).Select(t => t.Id).ToArray()).ToArray();

                localContext.Trace($"There are {userOwnerTeams.Count()} user associated to affected owner teams: ({string.Join(",", userOwnerTeams)})");

                // Only get the delta of owner teams to be added based on the owner teams the user is already affected to.
                var toAdd = ownerTeams.Except(userOwnerTeams)
                            .Select(t => new EntityReference("team", t))
                            .ToList();

                foreach (var userid in systemuserIds)
                {
                    localContext.Trace($"Adding {toAdd.Count()} owner teams to user '{userid}'");
                    localContext.OrganizationService.Associate("systemuser", userid, new Relationship("teammembership_association"), new EntityReferenceCollection(toAdd));
                }
            }
            else if (localContext.PluginExecutionContext.MessageName == PluginMessage.Disassociate)
            {
                var toRemove = ownerTeams.Select(t => new EntityReference("team", t)).ToList();
                foreach (var userid in systemuserIds)
                {
                    localContext.Trace($"Removing {toRemove.Count()} owner teams from user '{userid}'");
                    localContext.OrganizationService.Disassociate("systemuser", userid, new Relationship("teammembership_association"), new EntityReferenceCollection(toRemove));
                }
            }
        }
Beispiel #17
0
 public static List <PluginMessageEntityReference> ToPluginMessageEntityReferenceCollection(this EntityReferenceCollection entities)
 {
     return(new List <PluginMessageEntityReference>(entities.Select(reference => reference.ToPluginMessageEntityReference())));
 }