Skip to content

Commit

Permalink
Add table alias on namespace-based authorization criteria to prevent …
Browse files Browse the repository at this point in the history
…ambiguous column name
  • Loading branch information
mjaksn committed Oct 18, 2024
1 parent f8cc506 commit bce7cc9
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ bool TryApplyFilters(
filterDefinition.CriteriaApplicator(
queryBuilder,
conjunctionQueryBuilder,
authorizationPlan.RequestContext.Resource,
filterContext.SubjectEndpointNames,
parameterValues,
joinType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using EdFi.Ods.Common.Infrastructure.Filtering;
using EdFi.Ods.Common.Models;
using EdFi.Ods.Common.Models.Resource;
using EdFi.Ods.Common.Providers.Queries;
using EdFi.Ods.Common.Security.Authorization;
using EdFi.Ods.Common.Security.Claims;

Expand Down Expand Up @@ -65,6 +66,7 @@ public IReadOnlyList<AuthorizationFilterDefinition> CreatePredefinedAuthorizatio
private static void ApplyAuthorizationCriteria(
QueryBuilder queryBuilder,
QueryBuilder whereBuilder,
Resource resource,
string[] subjectEndpointNames,
IDictionary<string, object> parameters,
JoinType joinType,
Expand All @@ -87,14 +89,16 @@ private static void ApplyAuthorizationCriteria(
// Ensure the Namespace parameter is represented as an object array
var namespacePrefixes = parameterValue as object[] ?? [parameterValue];

var alias = resource.Entity.RootTableAlias();

// Add the final namespaces criteria to the supplied WHERE clause (junction)
whereBuilder.WhereNotNull(subjectEndpointName)
whereBuilder.WhereNotNull($"{alias}.{subjectEndpointName}")
.Where(
qb =>
{
foreach (var namespacePrefix in namespacePrefixes)
{
qb.OrWhereLike(subjectEndpointName, namespacePrefix, MatchMode.Start);
qb.OrWhereLike($"{alias}.{subjectEndpointName}", namespacePrefix, MatchMode.Start);
}
return qb;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public IReadOnlyList<AuthorizationFilterDefinition> CreatePredefinedAuthorizatio
private static void ApplyAuthorizationCriteria(
QueryBuilder queryBuilder,
QueryBuilder whereQueryBuilder,
Resource resource,
string[] subjectEndpointNames,
IDictionary<string, object> parameters,
JoinType joinType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public ViewBasedAuthorizationFilterDefinition(
SELECT {{newAlias1}}.{viewTargetEndpointName}
FROM {GetFullNameForView($"auth_{viewName}")} {{newAlias1}}
WHERE {{newAlias1}}.{viewSourceEndpointName} IN (:{RelationshipAuthorizationConventions.ClaimsParameterName}))",
(queryBuilder, @where, subjectEndpointNames, parameters, joinType, authorizationStrategy) =>
(queryBuilder, @where, resource, subjectEndpointNames, parameters, joinType, authorizationStrategy) =>
{
if (subjectEndpointNames?.Length != 1)
{
Expand Down Expand Up @@ -89,7 +89,7 @@ public ViewBasedAuthorizationFilterDefinition(
: base(
filterName,
null, // HQL condition (not supported by view-based authorization)
(criteria, @where, subjectEndpointNames, parameters, joinType, authorizationStrategy)
(criteria, @where, resource, subjectEndpointNames, parameters, joinType, authorizationStrategy)
=> criteria.ApplyCustomViewJoinFilter(
viewName,
subjectEndpointNames,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class AuthorizationFilterDefinition
public AuthorizationFilterDefinition(
string filterName,
string friendlyHqlConditionFormat,
Action<QueryBuilder, QueryBuilder, string[], IDictionary<string, object>, JoinType, IAuthorizationStrategy> criteriaApplicator,
Action<QueryBuilder, QueryBuilder, Resource, string[], IDictionary<string, object>, JoinType, IAuthorizationStrategy> criteriaApplicator,
Action<AuthorizationFilterDefinition, AuthorizationFilterContext, Resource, int, QueryBuilder, bool> trackedChangesCriteriaApplicator,
Func<DataManagementRequestContext, AuthorizationFilterContext, string, InstanceAuthorizationResult> authorizeInstance)
{
Expand All @@ -58,7 +58,7 @@ public AuthorizationFilterDefinition(
/// <summary>
/// Gets the function for applying the filter using NHibernate's <see cref="NHibernate.ICriteria"/> API.
/// </summary>
public Action<QueryBuilder, QueryBuilder, string[], IDictionary<string, object>, JoinType, IAuthorizationStrategy> CriteriaApplicator { get; protected set; }
public Action<QueryBuilder, QueryBuilder, Resource, string[], IDictionary<string, object>, JoinType, IAuthorizationStrategy> CriteriaApplicator { get; protected set; }

/// <summary>
/// Gets the function for applying the filter to the <see cref="QueryBuilder" /> for tracked changes queries.
Expand Down
19 changes: 19 additions & 0 deletions Application/EdFi.Ods.Common/Providers/Queries/EntityExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: Apache-2.0
// Licensed to the Ed-Fi Alliance under one or more agreements.
// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0.
// See the LICENSE and NOTICES files in the project root for more information.

using EdFi.Ods.Common.Models.Domain;

namespace EdFi.Ods.Common.Providers.Queries;

public static class EntityExtensions
{
private const string _baseAlias = "b";
private const string _standardAlias = "r";

public static string RootTableAlias(this Entity aggregateRootEntity)
{
return aggregateRootEntity.IsDerived ? _baseAlias : _standardAlias;
}
}

0 comments on commit bce7cc9

Please sign in to comment.