Esempio n. 1
0
        public void Words_are_inflected_using_overridden_singular_and_plural_forms_based_on_supplied_count_correctly()
        {
            "".ShouldSatisfyAllConditions(
                // No overrides, showing default Inflection behavior
                () => Inflector.Inflect("do", 0).ShouldBe("dos"),
                () => Inflector.Inflect("do", 1).ShouldBe("do"),
                () => Inflector.Inflect("do", 2).ShouldBe("dos"),

                // Overrides, showing Inflection using overrides
                () => Inflector.Inflect("do", 0, "does", "do").ShouldBe("do"),
                () => Inflector.Inflect("do", 1, "does", "do").ShouldBe("does"),
                () => Inflector.Inflect("do", 2, "does", "do").ShouldBe("do"),

                // Overrides, showing Inflection using overrides (ignoring the supplied word completely)
                () => Inflector.Inflect(null, 0, "does", "do").ShouldBe("do"),
                () => Inflector.Inflect(null, 1, "does", "do").ShouldBe("does"),
                () => Inflector.Inflect(null, 2, "does", "do").ShouldBe("do")
                );
        }
Esempio n. 2
0
        public void Words_are_inflected_to_singular_and_plural_forms_based_on_supplied_count_correctly()
        {
            "".ShouldSatisfyAllConditions(
                // Singular form supplied
                () => Inflector.Inflect("dog", 0).ShouldBe("dogs"),
                () => Inflector.Inflect("dog", 1).ShouldBe("dog"),
                () => Inflector.Inflect("dog", 2).ShouldBe("dogs"),

                // Plural form supplied
                () => Inflector.Inflect("dogs", 0).ShouldBe("dogs"),
                () => Inflector.Inflect("dogs", 1).ShouldBe("dog"),
                () => Inflector.Inflect("dogs", 2).ShouldBe("dogs"),

                // Singular form supplied
                () => Inflector.Inflect("doggy", 0).ShouldBe("doggies"),
                () => Inflector.Inflect("doggy", 1).ShouldBe("doggy"),
                () => Inflector.Inflect("doggy", 2).ShouldBe("doggies"),

                // Plural form supplied
                () => Inflector.Inflect("doggies", 0).ShouldBe("doggies"),
                () => Inflector.Inflect("doggies", 1).ShouldBe("doggy"),
                () => Inflector.Inflect("doggies", 2).ShouldBe("doggies")
                );
        }
        private async Task PerformViewBasedAuthorizationAsync(
            AuthorizationStrategyFilterResults[] resultsWithPendingExistenceChecks,
            EdFiAuthorizationContext authorizationContext,
            CancellationToken cancellationToken)
        {
            string sql = BuildExistenceCheckSql(resultsWithPendingExistenceChecks);

            // Execute the query
            using var sessionScope = new SessionScope(_sessionFactory);

            await using var cmd = sessionScope.Session.Connection.CreateCommand();

            // Assign the command text
            cmd.CommandText = sql;

            // Assign all parameters
            cmd.Parameters.AddRange(
                resultsWithPendingExistenceChecks.SelectMany(
                    x => x.FilterResults.Select(
                        f =>
            {
                var parameter           = cmd.CreateParameter();
                parameter.ParameterName = f.FilterContext.SubjectEndpointName;
                parameter.Value         = f.FilterContext.SubjectEndpointValue;

                return(parameter);
            }))
                .GroupBy(x => x.ParameterName)
                .Select(x => x.First())
                .ToArray());

            _viewBasedSingleItemAuthorizationQuerySupport.ApplyClaimsParametersToCommand(cmd, authorizationContext);

            // Process the pending AND SQL checks, ensure that they are all 1, or throw an exception
            var result = (int?)await cmd.ExecuteScalarAsync(cancellationToken);

            if (result == 0)
            {
                throw new EdFiSecurityException(GetAuthorizationFailureMessage());
            }

            string BuildExistenceCheckSql(AuthorizationStrategyFilterResults[] resultsWithPendingExistenceChecks)
            {
                // Build the existence check SQL
                StringBuilder sql = new();

                sql.Append("SELECT CASE WHEN ");

                resultsWithPendingExistenceChecks.ForEach(
                    (x, i) =>
                {
                    if (i > 0)
                    {
                        if (x.Operator == FilterOperator.And)
                        {
                            sql.Append(" AND ");
                        }
                        else
                        {
                            sql.Append(" OR ");
                        }
                    }

                    sql.Append('(');

                    x.FilterResults.ForEach(
                        (y, j) =>
                    {
                        var viewBasedFilterDefinition = y.FilterDefinition as ViewBasedAuthorizationFilterDefinition
                                                        ?? throw new InvalidOperationException(
                            "Expected a ViewBasedAuthorizationFilterDefinition instance for performing existence checks.");

                        var viewSqlSupport = viewBasedFilterDefinition.ViewBasedSingleItemAuthorizationQuerySupport;

                        if (j > 0)
                        {
                            // NOTE: Individual filters (segments) are always combined with AND
                            sql.Append(" AND ");
                        }

                        sql.Append("EXISTS (");
                        sql.Append(viewSqlSupport.GetItemExistenceCheckSql(viewBasedFilterDefinition, y.FilterContext));
                        sql.Append(')');
                    });

                    sql.Append(')');
                });

                sql.Append(" THEN 1 ELSE 0 END AS IsAuthorized");

                return(sql.ToString());
            }

            string GetAuthorizationFailureMessage()
            {
                // NOTE: Embedded convention - UniqueId is suffix used for external representation of USI values
                string[] subjectEndpointNames = resultsWithPendingExistenceChecks
                                                .SelectMany(asf => asf.FilterResults
                                                            .Select(f => f.FilterContext.SubjectEndpointName.ReplaceSuffix("USI", "UniqueId")))
                                                .Distinct()
                                                .OrderBy(n => n)
                                                .ToArray();

                string subjectEndpointNamesText = $"'{string.Join("', '", subjectEndpointNames)}'";

                object[] claimEndpointValues = resultsWithPendingExistenceChecks.SelectMany(x => x.FilterResults.Select(f => f.FilterContext))
                                               .FirstOrDefault()
                                               ?.ClaimEndpointValues.OrderBy(Convert.ToInt32).ToArray();

                string claimOrClaims = Inflector.Inflect("claim", claimEndpointValues?.Length ?? 0);

                const int MaximumEdOrgClaimValuesToDisplay = 5;

                var claimEndpointValuesAsString =
                    claimEndpointValues?.Select(v => v.ToString()).Take(MaximumEdOrgClaimValuesToDisplay + 1).ToArray()
                    ?? Array.Empty <string>();

                var claimEndpointValuesForDisplayText = claimEndpointValuesAsString?.Take(MaximumEdOrgClaimValuesToDisplay).ToList();

                if (claimEndpointValuesAsString.Length > MaximumEdOrgClaimValuesToDisplay)
                {
                    claimEndpointValuesForDisplayText.Add("...");
                }

                string claimEndpointValuesText = string.Join(", ", claimEndpointValuesForDisplayText);

                if (subjectEndpointNames.Length == 1)
                {
                    return($"Authorization denied. No relationships have been established between the caller's education organization id {claimOrClaims} ({claimEndpointValuesText}) and the resource item's {subjectEndpointNamesText} value.");
                }

                return($"Authorization denied. No relationships have been established between the caller's education organization id {claimOrClaims} ({claimEndpointValuesText}) and one or more of the following properties of the resource item: {subjectEndpointNamesText}.");
            }
        }