Exemplo n.º 1
0
        protected override bool TryAssert(OrganizationServiceContext serviceContext, Entity entity, CrmEntityRight right, CrmEntityCacheDependencyTrace dependencies, ContentMap map)
        {
            entity.ThrowOnNull("entity");
            dependencies.AddEntityDependency(entity);
            ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format(@"Testing right {0} on {1} ""{2}"" ({3}).", right, entity.LogicalName, entity.GetAttributeValue <string>("adx_name"), entity.Id));

            switch (entity.LogicalName)
            {
            case "adx_ideaforum":
                dependencies.AddEntitySetDependency("adx_webrole");
                return(this.TryAssertIdeaForum(entity, right, dependencies, map));

            case "adx_idea":
                return(this.TryAssertIdea(serviceContext, entity, right, dependencies, map));

            case "adx_ideacomment":
                return(this.TryAssertIdeaComment(serviceContext, entity, right, dependencies, map));

            case "adx_ideavote":
                return(this.TryAssertIdeaVote(serviceContext, entity, right, dependencies, map));

            default:
                throw new NotSupportedException("Entities of type {0} are not supported by this provider.".FormatWith(entity.LogicalName));
            }
        }
Exemplo n.º 2
0
        public override bool TryAssert(OrganizationServiceContext context, Entity currentEvent, CrmEntityRight right, CrmEntityCacheDependencyTrace dependencies)
        {
            currentEvent.AssertEntityName("adx_event");

            ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("Testing right {0} on event ({1}).", right, currentEvent.Id));

            dependencies.AddEntityDependency(currentEvent);
            dependencies.AddEntitySetDependency("adx_webrole");
            dependencies.AddEntitySetDependency("adx_eventaccesspermission");

            if (!Roles.Enabled)
            {
                ADXTrace.Instance.TraceInfo(TraceCategory.Application, "Roles are not enabled for this application. Allowing Read, but not Change.");

                // If roles are not enabled on the site, grant Read, deny Change.
                return(right == CrmEntityRight.Read);
            }

            // Windows Live ID Server decided to return null for an unauthenticated user's name
            // A null username, however, breaks the Roles.GetRolesForUser() because it expects an empty string.
            var currentUsername = (HttpContext.Current.User != null && HttpContext.Current.User.Identity != null)
                                ? HttpContext.Current.User.Identity.Name ?? string.Empty
                                : string.Empty;


            var userRoles = Roles.GetRolesForUser(currentUsername);

            // Get all rules applicable to the event, grouping equivalent rules. (Rules that
            // target the same event and confer the same right are equivalent.)
            var ruleGroupings = from rule in GetRulesApplicableToEvent(context, currentEvent, dependencies)
                                let eventReference = rule.GetAttributeValue <EntityReference>("adx_eventid")
                                                     let rightOption = rule.GetAttributeValue <OptionSetValue>("adx_right")
                                                                       where eventReference != null && rightOption != null
                                                                       group rule by new { EventID = eventReference.Id, Right = rightOption.Value } into ruleGrouping
            select ruleGrouping;

            var websiteReference = currentEvent.GetAttributeValue <EntityReference>("adx_websiteid");

            foreach (var ruleGrouping in ruleGroupings)
            {
                // Collect the names of all the roles that apply to this rule grouping
                var ruleGroupingRoles = ruleGrouping.SelectMany(rule => rule.GetRelatedEntities(context, "adx_eventaccesspermission_webrole").ToList()
                                                                .Where(role => BelongsToWebsite(websiteReference, role))
                                                                .Select(role => role.GetAttributeValue <string>("adx_name")));

                // Determine if the user belongs to any of the roles that apply to this rule grouping
                var userIsInAnyRoleForThisRule = ruleGroupingRoles.Any(role => userRoles.Any(userRole => userRole == role));

                // If the user belongs to one of the roles...
                if (userIsInAnyRoleForThisRule)
                {
                    if (ruleGrouping.Key.Right != RestrictRead)
                    {
                        ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("User has right Change on forum ({0}). Permission granted.", ruleGrouping.Key.EventID));

                        // ...the user has all rights.
                        return(true);
                    }
                }
                // If the user does not belong to any of the roles, the rule restricts read, and the desired right
                // is read...
                else if (ruleGrouping.Key.Right == RestrictRead && right == CrmEntityRight.Read)
                {
                    ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("User does not have right Read due to read restriction on event ({0}). Permission denied.", ruleGrouping.Key.EventID));

                    // ...the user has no right.
                    return(false);
                }
            }

            //Get all membership type applicable to the event
            var membershipTypes = currentEvent.GetRelatedEntities(context, "adx_event_membershiptype");

            //If the event has membership types, specific user has right to access it. If there is no membership type, every user has right.
            if (membershipTypes.Any())
            {
                var contact = PortalContext.Current.User;

                //Anonymouse user has no right.
                if (contact == null)
                {
                    return(false);
                }

                foreach (var membershipType in membershipTypes)
                {
                    if (contact.GetRelatedEntities(context, "adx_membership_contact").Any(m => m.GetAttributeValue <EntityReference>("adx_membershiptypeid") == membershipType.ToEntityReference()))
                    {
                        return(true);
                    }
                }

                return(false);
            }

            // If none of the above rules apply, assert on parent webpage.
            var parentWebPage = currentEvent.GetRelatedEntity(context, "adx_webpage_event");

            // If there is no parent web page, grant Read by default, and deny Change.
            if (parentWebPage == null)
            {
                ADXTrace.Instance.TraceInfo(TraceCategory.Application, "No access control rules apply to the current user and event. Allowing Read, but not Change.");

                return(right == CrmEntityRight.Read);
            }

            ADXTrace.Instance.TraceInfo(TraceCategory.Application, "No access control rules apply to the current user and event. Asserting right on parent web page.");

            return(_webPageAccessControlProvider.TryAssert(context, parentWebPage, right, dependencies));
        }
Exemplo n.º 3
0
        public override bool TryAssert(OrganizationServiceContext serviceContext, Entity entity, CrmEntityRight right, CrmEntityCacheDependencyTrace dependencies)
        {
            entity.ThrowOnNull("entity");

            if (entity.LogicalName == "adx_issueforum")
            {
                ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format(@"Testing right {0} on adx_issueforum ({1}).", right, entity.Id));

                dependencies.AddEntityDependency(entity);

                dependencies.AddEntitySetDependency("adx_webrole");

                return(right == CrmEntityRight.Change
                                        ? UserInRole("adx_webrole_issueforum_write", false, serviceContext, entity, dependencies)
                                        : UserInRole("adx_webrole_issueforum_read", true, serviceContext, entity, dependencies) ||
                       UserInRole("adx_webrole_issueforum_write", false, serviceContext, entity, dependencies));
            }

            if (entity.LogicalName == "adx_issue")
            {
                ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format(@"Testing right {0} on adx_issue ({1}).", right, entity.Id));

                dependencies.AddEntityDependency(entity);

                var issueForum = entity.GetRelatedEntity(serviceContext, new Relationship("adx_issueforum_issue"));

                if (issueForum == null)
                {
                    return(false);
                }

                var approved = entity.GetAttributeValue <bool?>("adx_approved").GetValueOrDefault(false);

                // If the right being asserted is Read, and the issue is approved, assert whether the issue forum is readable.
                if (right == CrmEntityRight.Read && approved)
                {
                    return(TryAssert(serviceContext, issueForum, right, dependencies));
                }

                return(TryAssert(serviceContext, issueForum, CrmEntityRight.Change, dependencies));
            }

            if (entity.LogicalName == "adx_issuecomment")
            {
                ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format(@"Testing right {0} on adx_issuecomment ({1}).", right, entity.Id));

                dependencies.AddEntityDependency(entity);

                var issue = entity.GetRelatedEntity(serviceContext, new Relationship("adx_issue_issuecomment"));

                if (issue == null)
                {
                    return(false);
                }

                var approved = entity.GetAttributeValue <bool?>("adx_approved").GetValueOrDefault(false);

                // If the right being asserted is Read, and the comment is approved, assert whether the issue is readable.
                if (right == CrmEntityRight.Read && approved)
                {
                    return(TryAssert(serviceContext, issue, right, dependencies));
                }

                return(TryAssert(serviceContext, issue, CrmEntityRight.Change, dependencies));
            }

            if (entity.LogicalName == "adx_issuevote")
            {
                ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format(@"Testing right {0} on adx_issuevote ({1}).", entity.Id));

                dependencies.AddEntityDependency(entity);

                var issue = entity.GetRelatedEntity(serviceContext, new Relationship("adx_issue_issuevote"));

                return(issue != null && TryAssert(serviceContext, issue, right, dependencies));
            }

            throw new NotSupportedException("Entities of type {0} are not supported by this provider.".FormatWith(entity.LogicalName));
        }
            public override bool TryAssert(OrganizationServiceContext context, Entity entity, CrmEntityRight right, CrmEntityCacheDependencyTrace dependencies)
            {
                if (entity == null || right == CrmEntityRight.Change)
                {
                    return(false);
                }

                dependencies.AddEntityDependency(entity);
                dependencies.AddEntitySetDependency("adx_webrole");
                dependencies.AddEntitySetDependency("adx_webrole_contact");
                dependencies.AddEntitySetDependency("adx_webrole_account");
                dependencies.AddEntitySetDependency("adx_websiteaccess");

                var entityName = entity.LogicalName;

                // Weblinks require some special handling.
                if (entityName == "adx_weblink")
                {
                    var weblinkPublishingState = context.RetrieveRelatedEntity(entity, "adx_publishingstate_weblink");

                    // If a weblink has a publishing state, and that state is not visible, state access is
                    // denied (unless the user can preview).
                    if (weblinkPublishingState != null && !weblinkPublishingState.GetAttributeValue <bool?>("adx_isvisible").GetValueOrDefault())
                    {
                        dependencies.AddEntityDependency(weblinkPublishingState);

                        return(UserCanPreview(context, entity));
                    }

                    var weblinkPage = context.RetrieveRelatedEntity(entity, "adx_webpage_weblink");

                    // If a weblink has an associated page, and page validation is not disabled, return the
                    // result of assertion on that page.
                    if (weblinkPage != null && !entity.GetAttributeValue <bool?>("adx_disablepagevalidation").GetValueOrDefault(false))
                    {
                        return(TryAssert(context, weblinkPage, right, dependencies));
                    }
                }

                if (entityName == "adx_idea")
                {
                    return(entity.GetAttributeValue <bool?>("adx_approved").GetValueOrDefault(false));
                }

                if (entityName == "adx_ideacomment")
                {
                    return(entity.GetAttributeValue <bool?>("adx_approved").GetValueOrDefault(false));
                }

                EntityReference publishingStateReference = null;
                Entity          entityPublishingState    = null;

                switch (entityName)
                {
                case "adx_webpage":
                    publishingStateReference = entity.GetAttributeValue <EntityReference>("adx_publishingstateid");
                    break;

                case "adx_weblinkset":
                    publishingStateReference = entity.GetAttributeValue <EntityReference>("adx_publishingstateid");
                    break;

                case "adx_webfile":
                    publishingStateReference = entity.GetAttributeValue <EntityReference>("adx_publishingstateid");
                    break;

                case "adx_communityforum":
                    publishingStateReference = entity.GetAttributeValue <EntityReference>("adx_publishingstateid");
                    break;

                case "adx_communityforumpost":
                    publishingStateReference = entity.GetAttributeValue <EntityReference>("adx_publishingstateid");
                    break;

                case "adx_ad":
                    publishingStateReference = entity.GetAttributeValue <EntityReference>("adx_publishingstateid");
                    break;

                // legacy entities
                case "adx_event":
                    entityPublishingState = context.RetrieveRelatedEntity(entity, "adx_publishingstate_event");
                    break;

                case "adx_eventschedule":
                    entityPublishingState = context.RetrieveRelatedEntity(entity, "adx_publishingstate_eventschedule");
                    break;

                case "adx_eventspeaker":
                    entityPublishingState = context.RetrieveRelatedEntity(entity, "adx_publishingstate_eventspeaker");
                    break;

                case "adx_eventsponsor":
                    entityPublishingState = context.RetrieveRelatedEntity(entity, "adx_publishingstate_eventsponsor");
                    break;

                case "adx_survey":
                    entityPublishingState = context.RetrieveRelatedEntity(entity, "adx_publishingstate_survey");
                    break;
                }

                if (publishingStateReference != null)
                {
                    entityPublishingState = context.RetrieveSingle(
                        "adx_publishingstate",
                        new[] { "adx_isvisible" },
                        new Condition("adx_publishingstateid", ConditionOperator.Equal, publishingStateReference.Id));
                }

                if (entityPublishingState == null)
                {
                    return(true);
                }

                dependencies.AddEntityDependency(entityPublishingState);

                if (entityPublishingState.GetAttributeValue <bool?>("adx_isvisible").GetValueOrDefault())
                {
                    return(true);
                }

                return(UserCanPreview(context, entityPublishingState));
            }
        public override bool TryAssert(OrganizationServiceContext context, Entity entity, CrmEntityRight right, CrmEntityCacheDependencyTrace dependencies)
        {
            if (entity == null || right == CrmEntityRight.Change)
            {
                return(false);
            }

            dependencies.AddEntityDependency(entity);
            dependencies.AddEntitySetDependency("adx_webrole");
            dependencies.AddEntitySetDependency("adx_webrole_contact");
            dependencies.AddEntitySetDependency("adx_webrole_account");
            dependencies.AddEntitySetDependency("adx_websiteaccess");

            var entityName = entity.LogicalName;

            if (entityName == "adx_idea")
            {
                return(entity.GetAttributeValue <bool?>("adx_approved").GetValueOrDefault(false));
            }

            if (entityName == "adx_ideacomment")
            {
                return(entity.GetAttributeValue <bool?>("adx_approved").GetValueOrDefault(false));
            }

            EntityReference publishingStateReference = null;
            Entity          entityPublishingState    = null;

            switch (entityName)
            {
            case "adx_communityforumpost":
                publishingStateReference = entity.GetAttributeValue <EntityReference>("adx_publishingstateid");
                break;

            case "adx_ad":
                publishingStateReference = entity.GetAttributeValue <EntityReference>("adx_publishingstateid");
                break;

            // legacy entities
            case "adx_event":
                entityPublishingState = context.RetrieveRelatedEntity(entity, "adx_publishingstate_event");
                break;

            case "adx_eventschedule":
                entityPublishingState = context.RetrieveRelatedEntity(entity, "adx_publishingstate_eventschedule");
                break;

            case "adx_eventspeaker":
                entityPublishingState = context.RetrieveRelatedEntity(entity, "adx_publishingstate_eventspeaker");
                break;

            case "adx_eventsponsor":
                entityPublishingState = context.RetrieveRelatedEntity(entity, "adx_publishingstate_eventsponsor");
                break;

            case "adx_survey":
                entityPublishingState = context.RetrieveRelatedEntity(entity, "adx_publishingstate_survey");
                break;
            }

            if (publishingStateReference != null)
            {
                entityPublishingState = context.RetrieveSingle(
                    "adx_publishingstate",
                    new[] { "adx_isvisible" },
                    new Condition("adx_publishingstateid", ConditionOperator.Equal, publishingStateReference.Id));
            }

            if (entityPublishingState == null)
            {
                return(true);
            }

            dependencies.AddEntityDependency(entityPublishingState);

            if (entityPublishingState.GetAttributeValue <bool?>("adx_isvisible").GetValueOrDefault())
            {
                return(true);
            }

            return(UserCanPreview(context, entityPublishingState));
        }
        /// <summary>
        /// Test whether or not an Entity's published dates are visible in the current context.
        /// </summary>
        /// <param name="context">OrganizationServiceContext</param>
        /// <param name="entity">CRM Entity</param>
        /// <param name="right">Entity Right</param>
        /// <param name="dependencies">Cache Dependency Trace</param>
        /// <param name="map">Content Map</param>
        /// <returns></returns>
        protected override bool TryAssert(OrganizationServiceContext context, Entity entity, CrmEntityRight right, CrmEntityCacheDependencyTrace dependencies, ContentMap map)
        {
            if (entity == null || right == CrmEntityRight.Change)
            {
                return(false);
            }

            dependencies.AddEntityDependency(entity);
            dependencies.AddEntitySetDependency("adx_webrole");
            dependencies.AddEntitySetDependency("adx_websiteaccess");

            var entityName = entity.LogicalName;

            var releaseDate = DateTime.MinValue;
            var expiryDate  = DateTime.MaxValue;

            if (entityName == "adx_webpage" ||
                entityName == "adx_webfile" ||
                entityName == "adx_event" ||
                entityName == "adx_survey" ||
                entityName == "adx_ad")
            {
                releaseDate = entity.GetAttributeValue <DateTime?>("adx_releasedate").GetValueOrDefault(DateTime.MinValue);
                expiryDate  = entity.GetAttributeValue <DateTime?>("adx_expirationdate").GetValueOrDefault(DateTime.MaxValue);
            }
            else if (entityName == "adx_weblink")
            {
                if (!entity.GetAttributeValue <bool?>("adx_disablepagevalidation").GetValueOrDefault(false))
                {
                    var pageReference = entity.GetAttributeValue <EntityReference>("adx_pageid");

                    if (pageReference != null)
                    {
                        WebPageNode rootPage;
                        if (map.TryGetValue(pageReference, out rootPage))
                        {
                            var weblinkWebPage = HttpContext.Current.GetContextLanguageInfo().FindLanguageSpecificWebPageNode(rootPage, false);

                            if (weblinkWebPage != null)
                            {
                                return(TryAssert(context, weblinkWebPage.ToEntity(), right, dependencies));
                            }
                        }
                    }
                }

                return(true);
            }
            else if (entityName == "adx_shortcut")
            {
                if (!entity.GetAttributeValue <bool?>("adx_disabletargetvalidation").GetValueOrDefault(false))
                {
                    var pageReference    = entity.GetAttributeValue <EntityReference>("adx_webpageid");
                    var webFileReference = entity.GetAttributeValue <EntityReference>("adx_webfileid");

                    if (pageReference != null)
                    {
                        WebPageNode rootPage;
                        if (map.TryGetValue(pageReference, out rootPage))
                        {
                            var shortcutWebPage = HttpContext.Current.GetContextLanguageInfo().FindLanguageSpecificWebPageNode(rootPage, false);

                            if (shortcutWebPage != null)
                            {
                                return(TryAssert(context, shortcutWebPage.ToEntity(), right, dependencies));
                            }
                        }
                    }
                    else if (webFileReference != null)
                    {
                        WebFileNode webFile;
                        if (map.TryGetValue(webFileReference, out webFile))
                        {
                            return(TryAssert(context, webFile.ToEntity(), right, dependencies));
                        }
                    }
                }

                var parentPageReference = entity.GetAttributeValue <EntityReference>("adx_parentpage_webpageid");

                if (parentPageReference != null)
                {
                    WebPageNode rootPage;
                    if (map.TryGetValue(parentPageReference, out rootPage))
                    {
                        var parentPage = HttpContext.Current.GetContextLanguageInfo().FindLanguageSpecificWebPageNode(rootPage, false);

                        return(TryAssert(context, parentPage.ToEntity(), right, dependencies));
                    }
                }

                return(true);
            }

            return(UserCanPreview(context, entity) || InnerTryAssert(releaseDate, expiryDate));
        }
        public bool TryAssertRightProperty(OrganizationServiceContext context, string rightPropertyName, CrmEntityCacheDependencyTrace dependencies)
        {
            // If Roles are not enabled on the site, deny permission.
            if (!Roles.Enabled)
            {
                ADXTrace.Instance.TraceError(TraceCategory.Application, "Roles are not enabled for this application. Permission denied.");

                return(false);
            }

            dependencies.AddEntitySetDependency("adx_webrole");
            dependencies.AddEntitySetDependency("adx_webrole_contact");
            dependencies.AddEntitySetDependency("adx_webrole_account");

            dependencies.AddEntityDependency(_website);

            var userRoles = this.GetUserRoles();

            if (!userRoles.Any())
            {
                ADXTrace.Instance.TraceInfo(TraceCategory.Application, "No roles were found for the current user. Permission denied.");

                return(false);
            }

            var websiteaccessFetch =
                new Fetch
            {
                Entity = new FetchEntity("adx_websiteaccess", new [] { "adx_manageweblinksets", "adx_previewunpublishedentities" })
                {
                    Filters = new[]
                    {
                        new Filter
                        {
                            Conditions = new[]
                            {
                                new Condition(
                                    "adx_websiteid",
                                    ConditionOperator.Equal,
                                    this._website.Id),
                            }
                        }
                    }
                }
            };

            var rules = context.RetrieveMultiple(websiteaccessFetch).Entities;

            // If no access permissions are defined for this site, deny permission.
            if (!rules.Any())
            {
                ADXTrace.Instance.TraceInfo(TraceCategory.Application, "No website access permission rules were found for the current website. Permission denied.");

                return(false);
            }

            dependencies.AddEntityDependencies(rules);

            foreach (var rule in rules)
            {
                var ruleRoles = context.RetrieveRelatedEntities(rule, "adx_websiteaccess_webrole", new [] { "adx_name" }).Entities;

                if (ruleRoles == null)
                {
                    continue;
                }

                var ruleRoleNames = ruleRoles.Select(role => role.GetAttributeValue <string>("adx_name"));

                var roleIntersection = ruleRoleNames.Intersect(userRoles, StringComparer.InvariantCulture);

                // If the user is in any of the roles associated with the permission rule, and
                // the rightsPredicate evaluates to true for the given rule, grant permission.
                if (roleIntersection.Any() && rule.GetAttributeValue <bool?>(rightPropertyName).GetValueOrDefault(false))
                {
                    return(true);
                }
            }

            // If no permission rules meet the necessary conditions, deny permission.
            return(false);
        }