Skip to content

Commit

Permalink
[ODS-5942] Optimize StudentContactAssociation resource authorization …
Browse files Browse the repository at this point in the history
…for read/update/delete actions (#838)

* Modified security metadata for preventing unnecessary joins during authorization of the StudentParentAssociation/StudentContactAssociation resource.

* Revert "[ODS-5942] Optimize StudentContactAssociation resource authorization for read/update/delete actions (#826)"

This reverts commit fd851c1.
  • Loading branch information
gmcelhanon authored Oct 3, 2023
1 parent eda2f09 commit 54bfc56
Show file tree
Hide file tree
Showing 10 changed files with 1,192 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,9 @@ bool ApplyAuthorizationStrategiesCombinedWithOrLogic()

foreach (var orStrategy in orStrategies)
{
var filters = orStrategy.Filters.Where(a=> a.FilterName != "ClaimEducationOrganizationIdsToStudentUSI"
|| !orStrategy.Filters.Any(b=>b.FilterName.Contains("ClaimEducationOrganizationIdsToContactUSI"))).ToList();

var filtersConjunction = new Conjunction(); // Combine filters with 'AND'

if (TryApplyFilters(filtersConjunction, filters))
if (TryApplyFilters(filtersConjunction, orStrategy.Filters))
{
mainDisjunction.Add(filtersConjunction);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,45 +323,29 @@ string BuildExistenceCheckSql(AuthorizationStrategyFilterResults[] resultsWithPe
resultsWithPendingExistenceChecks.ForEach(
(x, i, s) =>
{
if (i > 0)
{
if (x.Operator == FilterOperator.And)
{
s.Append(" AND ");
}
else
if (i > 0)
{
s.Append(" OR ");
if (x.Operator == FilterOperator.And)
{
s.Append(" AND ");
}
else
{
s.Append(" OR ");
}
}
}

s.Append('(');

var filterNamesToCheck = new List<string>
{
"ClaimEducationOrganizationIdsToStudentUSI",
"ClaimEducationOrganizationIdsToContactUSI"
};
s.Append('(');

bool areAllFilterNamesPresent = filterNamesToCheck.All(name => x.FilterResults.Any(a => a.FilterDefinition.FilterName == name));

if(areAllFilterNamesPresent)
{
x.FilterResults = x.FilterResults
.Where(a => a.FilterDefinition.FilterName != "ClaimEducationOrganizationIdsToStudentUSI")
.ToArray();

}


x.FilterResults.ForEach(
x.FilterResults.ForEach(
(y, j, s) =>
{
var viewBasedFilterDefinition = y.FilterDefinition as ViewBasedAuthorizationFilterDefinition
?? throw new InvalidOperationException("Expected a ViewBasedAuthorizationFilterDefinition instance for performing existence checks.");
?? 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
Expand All @@ -373,7 +357,7 @@ string BuildExistenceCheckSql(AuthorizationStrategyFilterResults[] resultsWithPe
s.Append(')');
}, s);

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

sql.Append(" THEN 1 ELSE 0 END AS IsAuthorized");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@

-- 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.

BEGIN
DECLARE
@claimId AS INT,
@claimName AS nvarchar(max),
@parentResourceClaimId AS INT,
@existingParentResourceClaimId AS INT,
@claimSetId AS INT,
@claimSetName AS nvarchar(max),
@authorizationStrategyId AS INT,
@msg AS nvarchar(max),
@createActionId AS INT,
@readActionId AS INT,
@updateActionId AS INT,
@deleteActionId AS INT,
@readChangesActionId AS INT,
@resourceClaimActionId AS INT,
@claimSetResourceClaimActionId AS INT

DECLARE @claimIdStack AS TABLE (Id INT IDENTITY, ResourceClaimId INT)

SELECT @createActionId = ActionId
FROM [dbo].[Actions] WHERE ActionName = 'Create';

SELECT @readActionId = ActionId
FROM [dbo].[Actions] WHERE ActionName = 'Read';

SELECT @updateActionId = ActionId
FROM [dbo].[Actions] WHERE ActionName = 'Update';

SELECT @deleteActionId = ActionId
FROM [dbo].[Actions] WHERE ActionName = 'Delete';

SELECT @readChangesActionId = ActionId
FROM [dbo].[Actions] WHERE ActionName = 'ReadChanges';

BEGIN TRANSACTION

-- Push claimId to the stack
INSERT INTO @claimIdStack (ResourceClaimId) VALUES (@claimId)

-- Processing children of root
----------------------------------------------------------------------------------------------------------------------------
-- Resource Claim: 'http://ed-fi.org/ods/identity/claims/domains/relationshipBasedData'
----------------------------------------------------------------------------------------------------------------------------
SET @claimName = 'http://ed-fi.org/ods/identity/claims/domains/relationshipBasedData'
SET @claimId = NULL

SELECT @claimId = ResourceClaimId, @existingParentResourceClaimId = ParentResourceClaimId
FROM dbo.ResourceClaims
WHERE ClaimName = @claimName

SELECT @parentResourceClaimId = ResourceClaimId
FROM @claimIdStack
WHERE Id = (SELECT Max(Id) FROM @claimIdStack)

IF @claimId IS NULL
BEGIN
PRINT 'Creating new claim: ' + @claimName

INSERT INTO dbo.ResourceClaims(ResourceName, ClaimName, ParentResourceClaimId)
VALUES ('relationshipBasedData', 'http://ed-fi.org/ods/identity/claims/domains/relationshipBasedData', @parentResourceClaimId)

SET @claimId = SCOPE_IDENTITY()
END
ELSE
BEGIN
IF @parentResourceClaimId != @existingParentResourceClaimId OR (@parentResourceClaimId IS NULL AND @existingParentResourceClaimId IS NOT NULL) OR (@parentResourceClaimId IS NOT NULL AND @existingParentResourceClaimId IS NULL)
BEGIN
PRINT 'Repointing claim ''' + @claimName + ''' (ResourceClaimId=' + CONVERT(nvarchar, @claimId) + ') to new parent (ResourceClaimId=' + CONVERT(nvarchar, @parentResourceClaimId) + ')'

UPDATE dbo.ResourceClaims
SET ParentResourceClaimId = @parentResourceClaimId
WHERE ResourceClaimId = @claimId
END
END

-- Push claimId to the stack
INSERT INTO @claimIdStack (ResourceClaimId) VALUES (@claimId)

-- Processing children of http://ed-fi.org/ods/identity/claims/domains/relationshipBasedData
----------------------------------------------------------------------------------------------------------------------------
-- Resource Claim: 'http://ed-fi.org/ods/identity/claims/studentParentAssociation'
----------------------------------------------------------------------------------------------------------------------------
SET @claimName = 'http://ed-fi.org/ods/identity/claims/studentParentAssociation'
SET @claimId = NULL

SELECT @claimId = ResourceClaimId, @existingParentResourceClaimId = ParentResourceClaimId
FROM dbo.ResourceClaims
WHERE ClaimName = @claimName

SELECT @parentResourceClaimId = ResourceClaimId
FROM @claimIdStack
WHERE Id = (SELECT Max(Id) FROM @claimIdStack)

IF @claimId IS NULL
BEGIN
PRINT 'Creating new claim: ' + @claimName

INSERT INTO dbo.ResourceClaims(ResourceName, ClaimName, ParentResourceClaimId)
VALUES ('studentParentAssociation', 'http://ed-fi.org/ods/identity/claims/studentParentAssociation', @parentResourceClaimId)

SET @claimId = SCOPE_IDENTITY()
END
ELSE
BEGIN
IF @parentResourceClaimId != @existingParentResourceClaimId OR (@parentResourceClaimId IS NULL AND @existingParentResourceClaimId IS NOT NULL) OR (@parentResourceClaimId IS NOT NULL AND @existingParentResourceClaimId IS NULL)
BEGIN
PRINT 'Repointing claim ''' + @claimName + ''' (ResourceClaimId=' + CONVERT(nvarchar, @claimId) + ') to new parent (ResourceClaimId=' + CONVERT(nvarchar, @parentResourceClaimId) + ')'

UPDATE dbo.ResourceClaims
SET ParentResourceClaimId = @parentResourceClaimId
WHERE ResourceClaimId = @claimId
END
END

-- Setting default authorization metadata
PRINT 'Deleting default action authorizations for resource claim ''' + @claimName + ''' (claimId=' + CONVERT(nvarchar, @claimId) + ').'

DELETE FROM dbo.ResourceClaimActionAuthorizationStrategies
WHERE ResourceClaimActionId IN (SELECT ResourceClaimActionId FROM dbo.ResourceClaimActions WHERE ResourceClaimId = @claimId);

DELETE FROM dbo.ResourceClaimActions
WHERE ResourceClaimId = @claimId

-- Default Create authorization
PRINT 'Creating action ''Create'' for resource claim ''' + @claimName + ''' (claimId=' + CONVERT(nvarchar, @claimId) + ').'
INSERT INTO dbo.ResourceClaimActions(ResourceClaimId, ActionId)
VALUES (@claimId, @CreateActionId)

SET @resourceClaimActionId = SCOPE_IDENTITY()


SET @authorizationStrategyId = NULL

SELECT @authorizationStrategyId = a.AuthorizationStrategyId
FROM dbo.AuthorizationStrategies a
WHERE a.AuthorizationStrategyName = 'RelationshipsWithStudentsOnly'

IF @authorizationStrategyId IS NULL
BEGIN
SET @msg = 'AuthorizationStrategy does not exist: ''RelationshipsWithStudentsOnly''';
THROW 50000, @msg, 1
END

PRINT 'Adding authorization strategy ''RelationshipsWithStudentsOnly'' for resource claim ''' + @claimName + ''' (claimId=' + CONVERT(nvarchar, @claimId) + ').'
INSERT INTO dbo.ResourceClaimActionAuthorizationStrategies(ResourceClaimActionId, AuthorizationStrategyId)
VALUES (@resourceClaimActionId, @authorizationStrategyId)


-- Default Read authorization
PRINT 'Creating action ''Read'' for resource claim ''' + @claimName + ''' (claimId=' + CONVERT(nvarchar, @claimId) + ').'
INSERT INTO dbo.ResourceClaimActions(ResourceClaimId, ActionId)
VALUES (@claimId, @ReadActionId)

SET @resourceClaimActionId = SCOPE_IDENTITY()


SET @authorizationStrategyId = NULL

SELECT @authorizationStrategyId = a.AuthorizationStrategyId
FROM dbo.AuthorizationStrategies a
WHERE a.AuthorizationStrategyName = 'RelationshipsWithStudentsOnly'

IF @authorizationStrategyId IS NULL
BEGIN
SET @msg = 'AuthorizationStrategy does not exist: ''RelationshipsWithStudentsOnly''';
THROW 50000, @msg, 1
END

PRINT 'Adding authorization strategy ''RelationshipsWithStudentsOnly'' for resource claim ''' + @claimName + ''' (claimId=' + CONVERT(nvarchar, @claimId) + ').'
INSERT INTO dbo.ResourceClaimActionAuthorizationStrategies(ResourceClaimActionId, AuthorizationStrategyId)
VALUES (@resourceClaimActionId, @authorizationStrategyId)


-- Default Update authorization
PRINT 'Creating action ''Update'' for resource claim ''' + @claimName + ''' (claimId=' + CONVERT(nvarchar, @claimId) + ').'
INSERT INTO dbo.ResourceClaimActions(ResourceClaimId, ActionId)
VALUES (@claimId, @UpdateActionId)

SET @resourceClaimActionId = SCOPE_IDENTITY()


SET @authorizationStrategyId = NULL

SELECT @authorizationStrategyId = a.AuthorizationStrategyId
FROM dbo.AuthorizationStrategies a
WHERE a.AuthorizationStrategyName = 'RelationshipsWithStudentsOnly'

IF @authorizationStrategyId IS NULL
BEGIN
SET @msg = 'AuthorizationStrategy does not exist: ''RelationshipsWithStudentsOnly''';
THROW 50000, @msg, 1
END

PRINT 'Adding authorization strategy ''RelationshipsWithStudentsOnly'' for resource claim ''' + @claimName + ''' (claimId=' + CONVERT(nvarchar, @claimId) + ').'
INSERT INTO dbo.ResourceClaimActionAuthorizationStrategies(ResourceClaimActionId, AuthorizationStrategyId)
VALUES (@resourceClaimActionId, @authorizationStrategyId)


-- Default Delete authorization
PRINT 'Creating action ''Delete'' for resource claim ''' + @claimName + ''' (claimId=' + CONVERT(nvarchar, @claimId) + ').'
INSERT INTO dbo.ResourceClaimActions(ResourceClaimId, ActionId)
VALUES (@claimId, @DeleteActionId)

SET @resourceClaimActionId = SCOPE_IDENTITY()


SET @authorizationStrategyId = NULL

SELECT @authorizationStrategyId = a.AuthorizationStrategyId
FROM dbo.AuthorizationStrategies a
WHERE a.AuthorizationStrategyName = 'RelationshipsWithStudentsOnly'

IF @authorizationStrategyId IS NULL
BEGIN
SET @msg = 'AuthorizationStrategy does not exist: ''RelationshipsWithStudentsOnly''';
THROW 50000, @msg, 1
END

PRINT 'Adding authorization strategy ''RelationshipsWithStudentsOnly'' for resource claim ''' + @claimName + ''' (claimId=' + CONVERT(nvarchar, @claimId) + ').'
INSERT INTO dbo.ResourceClaimActionAuthorizationStrategies(ResourceClaimActionId, AuthorizationStrategyId)
VALUES (@resourceClaimActionId, @authorizationStrategyId)


-- Default ReadChanges authorization
PRINT 'Creating action ''ReadChanges'' for resource claim ''' + @claimName + ''' (claimId=' + CONVERT(nvarchar, @claimId) + ').'
INSERT INTO dbo.ResourceClaimActions(ResourceClaimId, ActionId)
VALUES (@claimId, @ReadChangesActionId)

SET @resourceClaimActionId = SCOPE_IDENTITY()


SET @authorizationStrategyId = NULL

SELECT @authorizationStrategyId = a.AuthorizationStrategyId
FROM dbo.AuthorizationStrategies a
WHERE a.AuthorizationStrategyName = 'RelationshipsWithEdOrgsAndPeopleIncludingDeletes'

IF @authorizationStrategyId IS NULL
BEGIN
SET @msg = 'AuthorizationStrategy does not exist: ''RelationshipsWithEdOrgsAndPeopleIncludingDeletes''';
THROW 50000, @msg, 1
END

PRINT 'Adding authorization strategy ''RelationshipsWithEdOrgsAndPeopleIncludingDeletes'' for resource claim ''' + @claimName + ''' (claimId=' + CONVERT(nvarchar, @claimId) + ').'
INSERT INTO dbo.ResourceClaimActionAuthorizationStrategies(ResourceClaimActionId, AuthorizationStrategyId)
VALUES (@resourceClaimActionId, @authorizationStrategyId)



-- Pop the stack
DELETE FROM @claimIdStack WHERE Id = (SELECT Max(Id) FROM @claimIdStack)


-- Pop the stack
DELETE FROM @claimIdStack WHERE Id = (SELECT Max(Id) FROM @claimIdStack)


COMMIT TRANSACTION
END
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<SecurityMetadata>
<Claims>
<Claim name="http://ed-fi.org/ods/identity/claims/domains/relationshipBasedData">
<Claims>
<Claim name="http://ed-fi.org/ods/identity/claims/studentParentAssociation">
<DefaultAuthorization>
<Action name="Create">
<AuthorizationStrategies>
<AuthorizationStrategy name="RelationshipsWithStudentsOnly" />
</AuthorizationStrategies>
</Action>
<Action name="Read">
<AuthorizationStrategies>
<AuthorizationStrategy name="RelationshipsWithStudentsOnly" />
</AuthorizationStrategies>
</Action>
<Action name="Update">
<AuthorizationStrategies>
<AuthorizationStrategy name="RelationshipsWithStudentsOnly" />
</AuthorizationStrategies>
</Action>
<Action name="Delete">
<AuthorizationStrategies>
<AuthorizationStrategy name="RelationshipsWithStudentsOnly" />
</AuthorizationStrategies>
</Action>
<Action name="ReadChanges">
<AuthorizationStrategies>
<AuthorizationStrategy
name="RelationshipsWithEdOrgsAndPeopleIncludingDeletes" />
</AuthorizationStrategies>
</Action>
</DefaultAuthorization>
</Claim>
</Claims>
</Claim>
</Claims>
</SecurityMetadata>
Loading

0 comments on commit 54bfc56

Please sign in to comment.