Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ConfigGenerators/MsSqlCommands.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ update Book --config "dab-config.MsSql.json" --permissions "policy_tester_08:rea
update Review --config "dab-config.MsSql.json" --permissions "authenticated:create,read,update,delete"
update Review --config "dab-config.MsSql.json" --relationship books --target.entity Book --cardinality one
update BookWebsitePlacement --config "dab-config.MsSql.json" --permissions "authenticated:create,update" --rest true --graphql true
update BookWebsitePlacement --config "dab-config.MsSql.json" --permissions "authenticated:delete" --fields.include "*" --policy-database "@claims.id eq @item.id"
update BookWebsitePlacement --config "dab-config.MsSql.json" --permissions "authenticated:delete" --fields.include "*" --policy-database "@claims.userId eq @item.id"
update Author --config "dab-config.MsSql.json" --permissions "authenticated:create,read,update,delete" --rest true --graphql true
update WebsiteUser --config "dab-config.MsSql.json" --permissions "authenticated:create,read,delete,update" --rest false --graphql "websiteUser:websiteUsers"
update stocks_price --config "dab-config.MsSql.json" --permissions "authenticated:create,read,delete,update" --rest false
Expand Down
2 changes: 1 addition & 1 deletion ConfigGenerators/MySqlCommands.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ update Review --config "dab-config.MySql.json" --permissions "authenticated:crea
update Review --config "dab-config.MySql.json" --relationship books --target.entity Book --cardinality one
update Empty --config "dab-config.MySql.json" --permissions "anonymous:read"
update BookWebsitePlacement --config "dab-config.MySql.json" --permissions "authenticated:create,update" --rest true --graphql true
update BookWebsitePlacement --config "dab-config.MySql.json" --permissions "authenticated:delete" --fields.include "*" --policy-database "@claims.id eq @item.id"
update BookWebsitePlacement --config "dab-config.MySql.json" --permissions "authenticated:delete" --fields.include "*" --policy-database "@claims.userId eq @item.id"
update Author --config "dab-config.MySql.json" --permissions "authenticated:create,read,update,delete" --rest true --graphql true
update WebsiteUser --config "dab-config.MySql.json" --permissions "authenticated:create,read,delete,update" --rest false --graphql "websiteUser:websiteUsers"
update stocks_price --config "dab-config.MySql.json" --permissions "authenticated:create,read,delete,update" --rest false
Expand Down
2 changes: 1 addition & 1 deletion ConfigGenerators/PostgreSqlCommands.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ update Review --config "dab-config.PostgreSql.json" --permissions "authenticated
update Review --config "dab-config.PostgreSql.json" --relationship books --target.entity Book --cardinality one
update Empty --config "dab-config.PostgreSql.json" --permissions "anonymous:read"
update BookWebsitePlacement --config "dab-config.PostgreSql.json" --permissions "authenticated:create,update" --rest true --graphql true
update BookWebsitePlacement --config "dab-config.PostgreSql.json" --permissions "authenticated:delete" --fields.include "*" --policy-database "@claims.id eq @item.id"
update BookWebsitePlacement --config "dab-config.PostgreSql.json" --permissions "authenticated:delete" --fields.include "*" --policy-database "@claims.userId eq @item.id"
update Author --config "dab-config.PostgreSql.json" --permissions "authenticated:create,read,update,delete" --rest true --graphql true
update WebsiteUser --config "dab-config.PostgreSql.json" --permissions "authenticated:create,read,delete,update" --rest false --graphql "websiteUser:websiteUsers"
update stocks_price --config "dab-config.PostgreSql.json" --permissions "authenticated:create,read,delete,update" --rest false
Expand Down
20 changes: 16 additions & 4 deletions src/Service.Tests/Authorization/AuthorizationHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ public static RuntimeConfig InitRuntimeConfig(
HashSet<string>? includedCols = null,
HashSet<string>? excludedCols = null,
string? databasePolicy = null,
string? requestPolicy = null
string? requestPolicy = null,
string authProvider = "AppService"
)
{
Field? fieldsForRole = null;
Expand Down Expand Up @@ -102,16 +103,27 @@ public static RuntimeConfig InitRuntimeConfig(
Mappings: null
);

Dictionary<string, Entity> entityMap = new();
entityMap.Add(entityName, sampleEntity);
Dictionary<string, Entity> entityMap = new()
{
{ entityName, sampleEntity }
};

// Create runtime settings for the config.
Dictionary<GlobalSettingsType, object> runtimeSettings = new();
AuthenticationConfig authenticationConfig = new(Provider: authProvider);
HostGlobalSettings hostGlobal = new(Authentication: authenticationConfig);
JsonElement hostGlobalJson = JsonSerializer.SerializeToElement(hostGlobal);
runtimeSettings.Add(GlobalSettingsType.Host, hostGlobalJson);

RuntimeConfig runtimeConfig = new(
Schema: "UnitTestSchema",
DataSource: new DataSource(DatabaseType: DatabaseType.mssql),
RuntimeSettings: new Dictionary<GlobalSettingsType, object>(),
RuntimeSettings: runtimeSettings,
Entities: entityMap
);

runtimeConfig.DetermineGlobalSettings();

return runtimeConfig;
}

Expand Down
38 changes: 38 additions & 0 deletions src/Service.Tests/Unittests/ConfigValidationUnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,44 @@ public void ParseInvalidDbPolicyWithInvalidClaimTypeFormat(string policy)
Assert.AreEqual(DataApiBuilderException.SubStatusCodes.ConfigValidationError, ex.SubStatusCode);
}

/// <summary>
/// Test to validate that only and only for SWA, if claims other than "userId" and
/// "userDetails" are referenced in the database policy, we fail the validation.
/// </summary>
/// <param name="authProvider">Authentication provider like AppService, StaticWebApps.</param>
/// <param name="dbPolicy">Database policy defined for action.</param>
/// <param name="action">The action for which database policy is defined.</param>
/// <param name="errorExpected">Boolean value indicating whether an exception is expected or not.</param>
[DataTestMethod]
[DataRow("StaticWebApps", "@claims.userId eq @item.col2", Operation.Read, false, DisplayName = "SWA- Database Policy defined for Read passes")]
[DataRow("staticwebapps", "@claims.userDetails eq @item.col3", Operation.Update, false, DisplayName = "SWA- Database Policy defined for Update passes")]
[DataRow("StaticWebAPPs", "@claims.email eq @item.col3", Operation.Delete, true, DisplayName = "SWA- Database Policy defined for Delete fails")]
[DataRow("appService", "@claims.email eq @item.col3", Operation.Delete, false, DisplayName = "AppService- Database Policy defined for Delete passes")]
public void TestInvalidClaimsForStaticWebApps(string authProvider, string dbPolicy, Operation action, bool errorExpected)
{
RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig(
entityName: AuthorizationHelpers.TEST_ENTITY,
roleName: AuthorizationHelpers.TEST_ROLE,
operation: action,
includedCols: new HashSet<string> { "col1", "col2", "col3" },
databasePolicy: dbPolicy,
authProvider: authProvider.ToString()
);
RuntimeConfigValidator configValidator = AuthenticationConfigValidatorUnitTests.GetMockConfigValidator(ref runtimeConfig);
try
{
configValidator.ValidatePermissionsInConfig(runtimeConfig);
Assert.IsFalse(errorExpected);
}
catch (DataApiBuilderException ex)
{
Assert.IsTrue(errorExpected);
Assert.AreEqual(HttpStatusCode.ServiceUnavailable, ex.StatusCode);
Assert.AreEqual(DataApiBuilderException.SubStatusCodes.ConfigValidationError, ex.SubStatusCode);
Assert.AreEqual(RuntimeConfigValidator.INVALID_CLAIMS_IN_POLICY_ERR_MSG, ex.Message);
}
}

/// <summary>
/// Test to validate that wildcard action passes all stages of config validation.
/// </summary>
Expand Down
21 changes: 20 additions & 1 deletion src/Service/Configurations/RuntimeConfigValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Text.Json;
using System.Text.RegularExpressions;
using Azure.DataApiBuilder.Config;
using Azure.DataApiBuilder.Service.AuthenticationHelpers;
using Azure.DataApiBuilder.Service.Authorization;
using Azure.DataApiBuilder.Service.Exceptions;
using Azure.DataApiBuilder.Service.GraphQLBuilder;
Expand Down Expand Up @@ -41,6 +42,9 @@ public class RuntimeConfigValidator : IConfigValidator
// specify the action name.
private static readonly string _actionKey = "action";

// Error messages.
public const string INVALID_CLAIMS_IN_POLICY_ERR_MSG = "One or more claim types supplied in the database policy are not supported.";

public RuntimeConfigValidator(
RuntimeConfigProvider runtimeConfigProvider,
IFileSystem fileSystem,
Expand Down Expand Up @@ -676,10 +680,13 @@ private static string ProcessFieldsInPolicy(string policy)
/// <param name="policy">The policy to be validated and processed.</param>
/// <returns>Processed policy</returns>
/// <exception cref="DataApiBuilderException">Throws exception when one or the other validations fail.</exception>
private static void ValidateClaimsInPolicy(string policy)
private void ValidateClaimsInPolicy(string policy)
{
// Find all the claimTypes from the policy
MatchCollection claimTypes = GetClaimTypesInPolicy(policy);
RuntimeConfig runtimeConfig = _runtimeConfigProvider.GetRuntimeConfiguration();
bool isStaticWebAppsAuthConfigured = Enum.TryParse<EasyAuthType>(runtimeConfig.AuthNConfig!.Provider, ignoreCase: true, out EasyAuthType easyAuthMode) ?
easyAuthMode is EasyAuthType.StaticWebApps : false;

foreach (Match claimType in claimTypes)
{
Expand All @@ -705,6 +712,18 @@ private static void ValidateClaimsInPolicy(string policy)
subStatusCode: DataApiBuilderException.SubStatusCodes.ConfigValidationError
);
}

if (isStaticWebAppsAuthConfigured &&
!(typeOfClaim.Equals(StaticWebAppsAuthentication.USER_ID_CLAIM) ||
typeOfClaim.Equals(StaticWebAppsAuthentication.USER_DETAILS_CLAIM)))
{
// Not a valid claimType containing allowed characters
throw new DataApiBuilderException(
message: INVALID_CLAIMS_IN_POLICY_ERR_MSG,
statusCode: System.Net.HttpStatusCode.ServiceUnavailable,
subStatusCode: DataApiBuilderException.SubStatusCodes.ConfigValidationError
);
}
} // MatchType claimType
}

Expand Down