public void Test_CanCreateEntityTypes()
        {
            EntityAccessControlService         entityAccessControlService;
            Mock <IEntityAccessControlChecker> entityAccessControlChecker;
            EntityType entityType;

            entityType = Entity.Get <EntityType>("core:person");
            Assert.That(entityType, Is.Not.Null, "Person type not found");

            entityAccessControlChecker = new Mock <IEntityAccessControlChecker>(MockBehavior.Strict);
            entityAccessControlChecker.Setup(eacc => eacc.CheckTypeAccess(
                                                 It.Is <IList <EntityType> >(ets => ets.SequenceEqual(new [] { entityType }, new EntityEqualityComparer())),
                                                 It.Is <EntityRef>(perm => perm.Id == Permissions.Create.Id),
                                                 It.IsAny <EntityRef>()))
            .Returns <IList <EntityType>, EntityRef, EntityRef>(
                (ets, perm, user) => new Dictionary <long, bool> {
                { entityType.Id, true }
            });

            entityAccessControlService = new EntityAccessControlService(entityAccessControlChecker.Object);

            Assert.That(entityAccessControlService.CanCreate(new [] { entityType }),
                        Is.EquivalentTo(new [] { new KeyValuePair <long, bool>(entityType.Id, true) }));

            entityAccessControlChecker.VerifyAll();
        }
        public void Test_TraceCacheInvalidations_CanCreate(SecurityTraceLevel traceLevel)
        {
            EntityType entityType;
            EntityAccessControlService entityAccessControlService;
            UserAccount userAccount;
            int         expectedOccurrences;

            userAccount = new UserAccount
            {
                Name = "Test User " + Guid.NewGuid()
            };
            userAccount.Save();

            entityType = new EntityType();
            entityType.Save();

            entityAccessControlService = new EntityAccessControlService(
                new EntityAccessControlChecker(), () => (int)traceLevel);

            using (new SetUser(userAccount))
            {
                entityAccessControlService.CanCreate(entityType);
            }

            expectedOccurrences = -1;
            switch (traceLevel)
            {
            case SecurityTraceLevel.DenyVerbose:
            case SecurityTraceLevel.DenyBasic:
            case SecurityTraceLevel.AllVerbose:
            case SecurityTraceLevel.AllBasic:
                expectedOccurrences = 1;
                break;

            case SecurityTraceLevel.None:
                expectedOccurrences = 0;
                break;

            default:
                Assert.Fail("Unknown security trace level.");
                break;
            }

            IList <LogActivityLogEntry> activityLogEntries;

            activityLogEntries = Entity.GetInstancesOfType <LogActivityLogEntry>().ToList();
            Assert.That(activityLogEntries,
                        Has.Exactly(expectedOccurrences)
                        .Property("LogEntrySeverity_Enum").EqualTo(LogSeverityEnum_Enumeration.InformationSeverity).And
                        .Property("LogEventTime").EqualTo(DateTime.UtcNow).Within(TimeSpan.FromSeconds(10)).And
                        .Property("Description").StartsWith(
                            string.Format(
                                "Access control check: Does user '{0}' have '{1}' access to entity(ies) '{2}'",
                                userAccount.Name, Permissions.Create.Alias, entityType.Id)));
        }
        /// <summary>
        ///     Verify that the current user has permission to create instances of types mentioned in a data source.
        /// </summary>
        /// <remarks>
        ///     Loads all relationship instances and searches for 'isOfType' relationships.
        ///     Then performs a 'can create' check on those types, if they are present in the current tenant.
        /// </remarks>
        /// <param name="source">Data source to read relationships from.</param>
        /// <param name="context">Processing context for reading the source.</param>
        /// <exception cref="PlatformSecurityException">Thrown if permission is denied.</exception>
        public void CheckTypeCreatePermissions(IDataSource source, IProcessingContext context)
        {
            // Load types that would be imported
            IEnumerable <Guid> typeUpgradeIds =
                source.GetRelationships(context)
                .Where(rel => rel.TypeId == Helpers.IsOfTypeRelationshipUpgradeId)
                .Select(rel => rel.ToId).Distinct( );

            // Note: UpgradeIdProvider will drop any upgradeIds that don't exist in the tenant.
            IEnumerable <long> typeIds =
                UpgradeIdProvider.GetIdsFromUpgradeIds(typeUpgradeIds)
                .Select(pair => pair.Value);
            IDictionary <long, EntityType> types = EntityRepository.Get <EntityType>(typeIds).ToDictionary(e => e.Id);

            // Demand 'create' for types
            IDictionary <long, bool> canCreate = EntityAccessControlService.CanCreate(types.Values.ToList( ));
            IList <long>             denied    = canCreate.Where(pair => !pair.Value).Select(pair => pair.Key).ToList( );

            if (denied.Count > 0)
            {
                string message = "Permission denied to create records of type: " + string.Join(", ", denied.Select(id => types[id].Name));
                throw new PlatformSecurityException(message);
            }
        }