Пример #1
0
        /// <inheritdoc/>
        public async Task <DelegationChange> InsertDelegation(DelegationChange delegationChange)
        {
            try
            {
                await using NpgsqlConnection conn = new NpgsqlConnection(_connectionString);
                await conn.OpenAsync();

                NpgsqlCommand pgcom = new NpgsqlCommand(insertDelegationChangeFunc, conn);
                pgcom.Parameters.AddWithValue("_delegationChangeType", delegationChange.DelegationChangeType);
                pgcom.Parameters.AddWithValue("_altinnAppId", delegationChange.AltinnAppId);
                pgcom.Parameters.AddWithValue("_offeredByPartyId", delegationChange.OfferedByPartyId);
                pgcom.Parameters.AddWithValue("_coveredByUserId", delegationChange.CoveredByUserId.HasValue ? delegationChange.CoveredByUserId.Value : DBNull.Value);
                pgcom.Parameters.AddWithValue("_coveredByPartyId", delegationChange.CoveredByPartyId.HasValue ? delegationChange.CoveredByPartyId.Value : DBNull.Value);
                pgcom.Parameters.AddWithValue("_performedByUserId", delegationChange.PerformedByUserId);
                pgcom.Parameters.AddWithValue("_blobStoragePolicyPath", delegationChange.BlobStoragePolicyPath);
                pgcom.Parameters.AddWithValue("_blobStorageVersionId", delegationChange.BlobStorageVersionId);

                using NpgsqlDataReader reader = await pgcom.ExecuteReaderAsync();

                if (reader.Read())
                {
                    return(GetDelegationChange(reader));
                }

                return(null);
            }
            catch (Exception e)
            {
                _logger.LogError(e, "Authorization // DelegationMetadataRepository // Insert // Exception");
                throw;
            }
        }
Пример #2
0
 private static DelegationChangeEventList GetDelegationChangeList()
 {
     return(new DelegationChangeEventList
     {
         DelegationChangeEvents = new List <DelegationChangeEvent>
         {
             new()
             {
                 EventType = DelegationChangeEventType.Grant,
                 DelegationChange = new DelegationChange
                 {
                     DelegationChangeId = 1,
                     AltinnAppId = "ttd/testapp",
                     OfferedByPartyId = 123,
                     CoveredByPartyId = 234,
                     PerformedByUserId = 567,
                     Created = DateTime.UtcNow
                 }
             },
             new()
             {
                 EventType = DelegationChangeEventType.Revoke,
                 DelegationChange = new DelegationChange
                 {
                     DelegationChangeId = 2,
                     AltinnAppId = "ttd/testapp",
                     OfferedByPartyId = 123,
                     CoveredByPartyId = 234,
                     PerformedByUserId = 567,
                     Created = DateTime.UtcNow
                 }
             },
             new()
             {
                 EventType = DelegationChangeEventType.Grant,
                 DelegationChange = new DelegationChange
                 {
                     DelegationChangeId = 3,
                     AltinnAppId = "ttd/testapp",
                     OfferedByPartyId = 123,
                     CoveredByUserId = 345,
                     PerformedByUserId = 567,
                     Created = DateTime.UtcNow
                 }
             },
             new()
             {
                 EventType = DelegationChangeEventType.RevokeLast,
                 DelegationChange = new DelegationChange
                 {
                     DelegationChangeId = 4,
                     AltinnAppId = "ttd/testapp",
                     OfferedByPartyId = 123,
                     CoveredByUserId = 345,
                     PerformedByUserId = 567,
                     Created = DateTime.UtcNow
                 }
             }
         }
     });
Пример #3
0
        /// <summary>
        /// Converts the delegation change to a delegation change event and pushes it to the event queue.
        /// Throws exception if something fails
        /// </summary>
        /// <param name="delegationChange">The delegation change stored in postgresql</param>
        public async Task <SendReceipt> Push(DelegationChange delegationChange)
        {
            DelegationChangeEventList dceList = _eventMapperService.MapToDelegationChangeEventList(new List <DelegationChange> {
                delegationChange
            });
            QueueClient queueClient = await GetQueueClient();

            return(await queueClient.SendMessageAsync(JsonSerializer.Serialize(dceList)));
        }
Пример #4
0
        /// <summary>
        /// Mocks pushing delegation changes to the event queue
        /// </summary>
        /// <param name="delegationChange">The delegation change stored in postgresql</param>
        public Task <SendReceipt> Push(DelegationChange delegationChange)
        {
            if (string.IsNullOrEmpty(delegationChange.AltinnAppId) || delegationChange.AltinnAppId == "error/delegationeventfail")
            {
                throw new Exception("DelegationChangeEventQueue || Push || Error");
            }

            return(Task.FromResult((SendReceipt)null));
        }
Пример #5
0
    public void MapEventWithCoveredByUser()
    {
        // Arrange
        EventMapperService        service = new();
        DateTime                  now     = DateTime.Now;
        DelegationChangeEventList input   = new()
        {
            DelegationChangeEvents = new List <DelegationChangeEvent>
            {
                new()
                {
                    EventType        = DelegationChangeEventType.Grant,
                    DelegationChange = new DelegationChange
                    {
                        DelegationChangeId = 1,
                        AltinnAppId        = "ttd/testapp",
                        OfferedByPartyId   = 123,
                        CoveredByUserId    = 234,
                        PerformedByUserId  = 567,
                        Created            = now
                    }
                }
            }
        };

        List <PlatformDelegationEvent> expectedOutput = new List <PlatformDelegationEvent>()
        {
            new()
            {
                PolicyChangeId    = 1,
                EventType         = DelegationChangeEventType.Grant,
                AltinnAppId       = "ttd/testapp",
                OfferedByPartyId  = 123,
                CoveredByPartyId  = 0,
                CoveredByUserId   = 234,
                PerformedByUserId = 567,
                Created           = now
            }
        };

        // Act
        List <PlatformDelegationEvent> output = service.MapToPlatformEventList(input);

        // Assert
        expectedOutput.Should().BeEquivalentTo(output);
    }
}
Пример #6
0
        public static void AssertEqual(List <DelegationChange> expected, List <DelegationChange> actual)
        {
            if (expected == null)
            {
                Assert.Null(actual);
                return;
            }

            Assert.Equal(expected.Count, actual.Count);
            foreach (DelegationChange expectedEntity in expected)
            {
                DelegationChange actualentity = actual.FirstOrDefault(a => a.AltinnAppId == expectedEntity.AltinnAppId &&
                                                                      a.BlobStoragePolicyPath == expectedEntity.BlobStoragePolicyPath &&
                                                                      a.CoveredByPartyId == expectedEntity.CoveredByPartyId &&
                                                                      a.CoveredByUserId == expectedEntity.CoveredByUserId &&
                                                                      a.OfferedByPartyId == expectedEntity.OfferedByPartyId &&
                                                                      a.DelegationChangeType == expectedEntity.DelegationChangeType);
                Assert.NotNull(actualentity);
            }
        }
Пример #7
0
        public Task <DelegationChange> InsertDelegation(DelegationChange delegationChange)
        {
            List <DelegationChange> current;
            string coveredBy = delegationChange.CoveredByPartyId != null ? $"p{delegationChange.CoveredByPartyId}" : $"u{delegationChange.CoveredByUserId}";
            string key       = $"{delegationChange.AltinnAppId}/{delegationChange.OfferedByPartyId}/{coveredBy}";

            if (MetadataChanges.ContainsKey(key))
            {
                current = MetadataChanges[key];
            }
            else
            {
                current = new List <DelegationChange>();
                MetadataChanges[key] = current;
            }

            DelegationChange currentDelegationChange = new DelegationChange
            {
                DelegationChangeId    = 1337,
                DelegationChangeType  = delegationChange.DelegationChangeType,
                AltinnAppId           = delegationChange.AltinnAppId,
                OfferedByPartyId      = delegationChange.OfferedByPartyId,
                CoveredByPartyId      = delegationChange.CoveredByPartyId,
                CoveredByUserId       = delegationChange.CoveredByUserId,
                PerformedByUserId     = delegationChange.PerformedByUserId,
                BlobStoragePolicyPath = delegationChange.BlobStoragePolicyPath,
                BlobStorageVersionId  = delegationChange.BlobStorageVersionId,
                Created = DateTime.Now
            };

            current.Add(currentDelegationChange);

            if (string.IsNullOrEmpty(delegationChange.AltinnAppId) || delegationChange.AltinnAppId == "error/postgrewritechangefail")
            {
                currentDelegationChange.DelegationChangeId = 0;
                return(Task.FromResult(currentDelegationChange));
            }

            return(Task.FromResult(currentDelegationChange));
        }
Пример #8
0
        private async Task <List <Rule> > DeleteAllRulesInPolicy(RequestToDelete policyToDelete)
        {
            DelegationHelper.TryGetResourceFromAttributeMatch(policyToDelete.PolicyMatch.Resource, out string org, out string app);
            string coveredBy = DelegationHelper.GetCoveredByFromMatch(policyToDelete.PolicyMatch.CoveredBy, out int?coveredByUserId, out int?coveredByPartyId);

            string policyPath;

            try
            {
                policyPath = PolicyHelper.GetAltinnAppDelegationPolicyPath(org, app, policyToDelete.PolicyMatch.OfferedByPartyId.ToString(), coveredByUserId, coveredByPartyId);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Not possible to build policy path App: {org}/{app} CoveredBy: {coveredBy} OfferedBy: {policyToDelete.PolicyMatch.OfferedByPartyId}", org, app, coveredBy, policyToDelete.PolicyMatch.OfferedByPartyId);
                return(null);
            }

            if (!await _policyRepository.PolicyExistsAsync(policyPath))
            {
                _logger.LogWarning("No blob was found for the expected path: {policyPath} this must be removed without upading the database", policyPath);
                return(null);
            }

            string leaseId = await _policyRepository.TryAcquireBlobLease(policyPath);

            if (leaseId == null)
            {
                _logger.LogError("Could not acquire blob lease on delegation policy at path: {policyPath}", policyPath);
                return(null);
            }

            try
            {
                DelegationChange currentChange = await _delegationRepository.GetCurrentDelegationChange($"{org}/{app}", policyToDelete.PolicyMatch.OfferedByPartyId, coveredByPartyId, coveredByUserId);

                if (currentChange.DelegationChangeType == DelegationChangeType.RevokeLast)
                {
                    _logger.LogWarning("The policy is already deleted for App: {org}/{app} CoveredBy: {coveredBy} OfferedBy: {policyToDelete.PolicyMatch.OfferedByPartyId}", org, app, coveredBy, policyToDelete.PolicyMatch.OfferedByPartyId);
                    return(null);
                }

                XacmlPolicy existingDelegationPolicy = await _prp.GetPolicyVersionAsync(currentChange.BlobStoragePolicyPath, currentChange.BlobStorageVersionId);

                List <Rule> currentPolicyRules = new List <Rule>();
                foreach (XacmlRule xacmlRule in existingDelegationPolicy.Rules)
                {
                    currentPolicyRules.Add(PolicyHelper.CreateRuleFromPolicyAndRuleMatch(policyToDelete, xacmlRule));
                }

                existingDelegationPolicy.Rules.Clear();

                Response <BlobContentInfo> response;
                try
                {
                    MemoryStream dataStream = PolicyHelper.GetXmlMemoryStreamFromXacmlPolicy(existingDelegationPolicy);
                    response = await _policyRepository.WritePolicyConditionallyAsync(policyPath, dataStream, leaseId);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Writing of delegation policy at path: {policyPath} failed. Is delegation blob storage account alive and well?}", policyPath);
                    return(null);
                }

                DelegationChange change = new DelegationChange
                {
                    DelegationChangeType  = DelegationChangeType.RevokeLast,
                    AltinnAppId           = $"{org}/{app}",
                    OfferedByPartyId      = policyToDelete.PolicyMatch.OfferedByPartyId,
                    CoveredByPartyId      = coveredByPartyId,
                    CoveredByUserId       = coveredByUserId,
                    PerformedByUserId     = policyToDelete.DeletedByUserId,
                    BlobStoragePolicyPath = policyPath,
                    BlobStorageVersionId  = response.Value.VersionId
                };

                change = await _delegationRepository.InsertDelegation(change);

                if (change == null || change.DelegationChangeId <= 0)
                {
                    // Comment:
                    // This means that the current version of the root blob is no longer in sync with changes in authorization postgresql delegation.delegatedpolicy table.
                    // The root blob is in effect orphaned/ignored as the delegation policies are always to be read by version, and will be overritten by the next delegation change.
                    _logger.LogError("Writing of delegation change to authorization postgresql database failed for changes to delegation policy at path: {policyPath}. is authorization postgresql database alive and well?", policyPath);
                    return(null);
                }

                try
                {
                    await _eventQueue.Push(change);
                }
                catch (Exception ex)
                {
                    _logger.LogCritical(new EventId(delegationChangeEventQueueErrorId, "DelegationChangeEventQueue.Push.Error"), ex, "DeletePolicy could not push DelegationChangeEvent to DelegationChangeEventQueue. DelegationChangeEvent must be retried for successful sync with SBL Authorization. DelegationChange: {change}", change);
                }

                return(currentPolicyRules);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "An exception occured while processing rules to delete in policy: {policyPath}", policyPath);
                return(null);
            }
            finally
            {
                _policyRepository.ReleaseBlobLease(policyPath, leaseId);
            }
        }
Пример #9
0
        private async Task <List <Rule> > ProcessPolicyFile(string policyPath, string org, string app, RequestToDelete deleteRequest)
        {
            List <Rule> currentRules = new List <Rule>();
            string      leaseId      = await _policyRepository.TryAcquireBlobLease(policyPath);

            if (leaseId == null)
            {
                _logger.LogError("Could not acquire blob lease lock on delegation policy at path: {policyPath}", policyPath);
                return(null);
            }

            try
            {
                bool             isAllRulesDeleted = false;
                string           coveredBy         = DelegationHelper.GetCoveredByFromMatch(deleteRequest.PolicyMatch.CoveredBy, out int?coveredByUserId, out int?coveredByPartyId);
                string           offeredBy         = deleteRequest.PolicyMatch.OfferedByPartyId.ToString();
                DelegationChange currentChange     = await _delegationRepository.GetCurrentDelegationChange($"{org}/{app}", deleteRequest.PolicyMatch.OfferedByPartyId, coveredByPartyId, coveredByUserId);

                XacmlPolicy existingDelegationPolicy = null;
                if (currentChange.DelegationChangeType == DelegationChangeType.RevokeLast)
                {
                    _logger.LogWarning("The policy is already deleted for App: {org}/{app} CoveredBy: {coveredBy} OfferedBy: {offeredBy}", org, app, coveredBy, offeredBy);
                    return(null);
                }

                existingDelegationPolicy = await _prp.GetPolicyVersionAsync(currentChange.BlobStoragePolicyPath, currentChange.BlobStorageVersionId);

                foreach (string ruleId in deleteRequest.RuleIds)
                {
                    XacmlRule xacmlRuleToRemove = existingDelegationPolicy.Rules.FirstOrDefault(r => r.RuleId == ruleId);
                    if (xacmlRuleToRemove == null)
                    {
                        _logger.LogWarning("The rule with id: {ruleId} does not exist in policy with path: {policyPath}", ruleId, policyPath);
                        continue;
                    }

                    existingDelegationPolicy.Rules.Remove(xacmlRuleToRemove);
                    Rule currentRule = PolicyHelper.CreateRuleFromPolicyAndRuleMatch(deleteRequest, xacmlRuleToRemove);
                    currentRules.Add(currentRule);
                }

                isAllRulesDeleted = existingDelegationPolicy.Rules.Count == 0;

                // if nothing is deleted no update has been done and policy and postgree update can be skipped
                if (currentRules.Count > 0)
                {
                    Response <BlobContentInfo> response;
                    try
                    {
                        // Write delegation policy to blob storage
                        MemoryStream dataStream = PolicyHelper.GetXmlMemoryStreamFromXacmlPolicy(existingDelegationPolicy);
                        response = await _policyRepository.WritePolicyConditionallyAsync(policyPath, dataStream, leaseId);
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, "Writing of delegation policy at path: {policyPath} failed. Is delegation blob storage account alive and well?", policyPath);
                        return(null);
                    }

                    // Write delegation change to postgresql
                    DelegationChange change = new DelegationChange
                    {
                        DelegationChangeType  = isAllRulesDeleted ? DelegationChangeType.RevokeLast : DelegationChangeType.Revoke,
                        AltinnAppId           = $"{org}/{app}",
                        OfferedByPartyId      = deleteRequest.PolicyMatch.OfferedByPartyId,
                        CoveredByPartyId      = coveredByPartyId,
                        CoveredByUserId       = coveredByUserId,
                        PerformedByUserId     = deleteRequest.DeletedByUserId,
                        BlobStoragePolicyPath = policyPath,
                        BlobStorageVersionId  = response.Value.VersionId
                    };

                    change = await _delegationRepository.InsertDelegation(change);

                    if (change == null || change.DelegationChangeId <= 0)
                    {
                        // Comment:
                        // This means that the current version of the root blob is no longer in sync with changes in authorization postgresql delegation.delegatedpolicy table.
                        // The root blob is in effect orphaned/ignored as the delegation policies are always to be read by version, and will be overritten by the next delegation change.
                        _logger.LogError("Writing of delegation change to authorization postgresql database failed for changes to delegation policy at path: {policyPath}. is authorization postgresql database alive and well?", policyPath);
                        return(null);
                    }

                    try
                    {
                        await _eventQueue.Push(change);
                    }
                    catch (Exception ex)
                    {
                        _logger.LogCritical(new EventId(delegationChangeEventQueueErrorId, "DelegationChangeEventQueue.Push.Error"), ex, "DeleteRules could not push DelegationChangeEvent to DelegationChangeEventQueue. DelegationChangeEvent must be retried for successful sync with SBL Authorization. DelegationChange: {change}", change);
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "An exception occured while processing rules to delete in policy: {policyPath}", policyPath);
                return(null);
            }
            finally
            {
                _policyRepository.ReleaseBlobLease(policyPath, leaseId);
            }

            return(currentRules);
        }
Пример #10
0
        private async Task <bool> WriteDelegationPolicyInternal(string policyPath, List <Rule> rules)
        {
            if (!DelegationHelper.TryGetDelegationParamsFromRule(rules.First(), out string org, out string app, out int offeredByPartyId, out int?coveredByPartyId, out int?coveredByUserId, out int delegatedByUserId))
            {
                _logger.LogWarning("This should not happen. Incomplete rule model received for delegation to delegation policy at: {policyPath}. Incomplete model should have been returned in unsortable rule set by TryWriteDelegationPolicyRules. DelegationHelper.SortRulesByDelegationPolicyPath might be broken.", policyPath);
                return(false);
            }

            XacmlPolicy appPolicy = await _prp.GetPolicyAsync(org, app);

            if (appPolicy == null)
            {
                _logger.LogWarning("No valid App policy found for delegation policy path: {policyPath}", policyPath);
                return(false);
            }

            foreach (Rule rule in rules)
            {
                if (!DelegationHelper.PolicyContainsMatchingRule(appPolicy, rule))
                {
                    _logger.LogWarning("Matching rule not found in app policy. Action might not exist for Resource, or Resource itself might not exist. Delegation policy path: {policyPath}. Rule: {rule}", policyPath, rule);
                    return(false);
                }
            }

            if (!await _policyRepository.PolicyExistsAsync(policyPath))
            {
                // Create a new empty blob for lease locking
                await _policyRepository.WritePolicyAsync(policyPath, new MemoryStream());
            }

            string leaseId = await _policyRepository.TryAcquireBlobLease(policyPath);

            if (leaseId != null)
            {
                try
                {
                    // Check for a current delegation change from postgresql
                    DelegationChange currentChange = await _delegationRepository.GetCurrentDelegationChange($"{org}/{app}", offeredByPartyId, coveredByPartyId, coveredByUserId);

                    XacmlPolicy existingDelegationPolicy = null;
                    if (currentChange != null && currentChange.DelegationChangeType != DelegationChangeType.RevokeLast)
                    {
                        existingDelegationPolicy = await _prp.GetPolicyVersionAsync(policyPath, currentChange.BlobStorageVersionId);
                    }

                    // Build delegation XacmlPolicy either as a new policy or add rules to existing
                    XacmlPolicy delegationPolicy;
                    if (existingDelegationPolicy != null)
                    {
                        delegationPolicy = existingDelegationPolicy;
                        foreach (Rule rule in rules)
                        {
                            if (!DelegationHelper.PolicyContainsMatchingRule(delegationPolicy, rule))
                            {
                                delegationPolicy.Rules.Add(PolicyHelper.BuildDelegationRule(org, app, offeredByPartyId, coveredByPartyId, coveredByUserId, rule));
                            }
                        }
                    }
                    else
                    {
                        delegationPolicy = PolicyHelper.BuildDelegationPolicy(org, app, offeredByPartyId, coveredByPartyId, coveredByUserId, rules);
                    }

                    // Write delegation policy to blob storage
                    MemoryStream dataStream = PolicyHelper.GetXmlMemoryStreamFromXacmlPolicy(delegationPolicy);
                    Response <BlobContentInfo> blobResponse = await _policyRepository.WritePolicyConditionallyAsync(policyPath, dataStream, leaseId);

                    Response httpResponse = blobResponse.GetRawResponse();
                    if (httpResponse.Status != (int)HttpStatusCode.Created)
                    {
                        _logger.LogError("Writing of delegation policy at path: {policyPath} failed. Response Status Code:\n{httpResponse.Status}. Response Reason Phrase:\n{httpResponse.ReasonPhrase}", policyPath, httpResponse.Status, httpResponse.ReasonPhrase);
                        return(false);
                    }

                    // Write delegation change to postgresql
                    DelegationChange change = new DelegationChange
                    {
                        DelegationChangeType  = DelegationChangeType.Grant,
                        AltinnAppId           = $"{org}/{app}",
                        OfferedByPartyId      = offeredByPartyId,
                        CoveredByPartyId      = coveredByPartyId,
                        CoveredByUserId       = coveredByUserId,
                        PerformedByUserId     = delegatedByUserId,
                        BlobStoragePolicyPath = policyPath,
                        BlobStorageVersionId  = blobResponse.Value.VersionId
                    };

                    change = await _delegationRepository.InsertDelegation(change);

                    if (change == null || change.DelegationChangeId <= 0)
                    {
                        // Comment:
                        // This means that the current version of the root blob is no longer in sync with changes in authorization postgresql delegation.delegatedpolicy table.
                        // The root blob is in effect orphaned/ignored as the delegation policies are always to be read by version, and will be overritten by the next delegation change.
                        _logger.LogError("Writing of delegation change to authorization postgresql database failed for changes to delegation policy at path: {policyPath}", policyPath);
                        return(false);
                    }

                    try
                    {
                        await _eventQueue.Push(change);
                    }
                    catch (Exception ex)
                    {
                        _logger.LogCritical(new EventId(delegationChangeEventQueueErrorId, "DelegationChangeEventQueue.Push.Error"), ex, "AddRules could not push DelegationChangeEvent to DelegationChangeEventQueue. DelegationChangeEvent must be retried for successful sync with SBL Authorization. DelegationChange: {change}", change);
                    }

                    return(true);
                }
                finally
                {
                    _policyRepository.ReleaseBlobLease(policyPath, leaseId);
                }
            }

            _logger.LogInformation("Could not acquire blob lease lock on delegation policy at path: {policyPath}", policyPath);
            return(false);
        }
Пример #11
0
        private static List <Rule> GetRulesFromPolicyAndDelegationChange(ICollection <XacmlRule> xacmlRules, DelegationChange delegationChange)
        {
            List <Rule> rules = new List <Rule>();

            foreach (XacmlRule xacmlRule in xacmlRules)
            {
                if (xacmlRule.Effect.Equals(XacmlEffectType.Permit) && xacmlRule.Target != null)
                {
                    Rule rule = new Rule
                    {
                        RuleId            = xacmlRule.RuleId,
                        OfferedByPartyId  = delegationChange.OfferedByPartyId,
                        DelegatedByUserId = delegationChange.PerformedByUserId,
                        CoveredBy         = new List <AttributeMatch>(),
                        Resource          = new List <AttributeMatch>()
                    };
                    AddAttributeMatchesToRule(xacmlRule.Target, rule);
                    rules.Add(rule);
                }
            }

            return(rules);
        }
Пример #12
0
        public Task <List <DelegationChange> > GetAllCurrentDelegationChanges(List <int> offeredByPartyIds, List <string> altinnAppIds, List <int> coveredByPartyIds, List <int> coveredByUserIds)
        {
            List <DelegationChange> result = new List <DelegationChange>();

            if (altinnAppIds.Any(appId => appId == "org1/app1") && offeredByPartyIds.Contains(50001337) && (coveredByUserIds != null && coveredByUserIds.Contains(20001337)))
            {
                result.Add(TestDataHelper.GetDelegationChange("org1/app1", 50001337, coveredByUserId: 20001337));
            }

            if (altinnAppIds.Any(appId => appId == "skd/taxreport") && offeredByPartyIds.Contains(1000) && (coveredByUserIds != null && coveredByUserIds.Contains(20001337)))
            {
                result.Add(TestDataHelper.GetDelegationChange("skd/taxreport", 1000, coveredByUserId: 20001337));
            }

            if (altinnAppIds.Any(appId => appId == "org1/app1") && offeredByPartyIds.Contains(50001337) && (coveredByUserIds != null && coveredByUserIds.Contains(20001338)))
            {
                DelegationChange delegation = TestDataHelper.GetDelegationChange("org1/app1", 50001337, coveredByUserId: 20001338);
                delegation.DelegationChangeType = DelegationChangeType.RevokeLast;
                result.Add(delegation);
            }

            if (altinnAppIds.Any(appId => appId == "org1/app1") && offeredByPartyIds.Contains(50001337) && (coveredByPartyIds != null && coveredByPartyIds.Contains(50001336)))
            {
                result.Add(TestDataHelper.GetDelegationChange("org1/app1", 50001337, coveredByPartyId: 50001336));
            }

            if (altinnAppIds.Contains("SKD/TaxReport") && offeredByPartyIds.Contains(50001337) && (coveredByUserIds != null && coveredByUserIds.Contains(20001336)))
            {
                result.Add(TestDataHelper.GetDelegationChange("SKD/TaxReport", 50001337, coveredByUserId: 20001336, performedByUserId: 20001337, changeType: DelegationChangeType.Grant));
            }

            if (altinnAppIds.Contains("SKD/TaxReport") && offeredByPartyIds.Contains(50001337) && (coveredByUserIds != null && coveredByUserIds.Contains(20001335)))
            {
                result.Add(TestDataHelper.GetDelegationChange("SKD/TaxReport", 50001337, coveredByPartyId: 50001335, performedByUserId: 20001337, changeType: DelegationChangeType.Grant));
            }

            if (altinnAppIds.Contains("SKD/TaxReport") && offeredByPartyIds.Contains(50001337) && (coveredByPartyIds != null && coveredByPartyIds.Contains(50001336)))
            {
                result.Add(TestDataHelper.GetDelegationChange("SKD/TaxReport", 50001337, coveredByPartyId: 50001338, performedByUserId: 20001337, changeType: DelegationChangeType.Grant));
            }

            if (altinnAppIds.Contains("SKD/TaxReport") && offeredByPartyIds.Contains(50001338) && (coveredByPartyIds != null && coveredByPartyIds.Contains(50001339)))
            {
                result.Add(TestDataHelper.GetDelegationChange("SKD/TaxReport", 50001338, coveredByPartyId: 50001339, performedByUserId: 20001338, changeType: DelegationChangeType.Grant));
            }

            if (altinnAppIds.Contains("SKD/TaxReport") && offeredByPartyIds.Contains(50001338) && (coveredByPartyIds != null && coveredByPartyIds.Contains(50001340)))
            {
                result.Add(TestDataHelper.GetDelegationChange("SKD/TaxReport", 50001338, coveredByPartyId: 50001340, performedByUserId: 20001338, changeType: DelegationChangeType.Grant));
            }

            if (altinnAppIds.Contains("SKD/TaxReport") && offeredByPartyIds.Contains(50001338) && (coveredByPartyIds != null && coveredByPartyIds.Contains(50001336)))
            {
                result.Add(TestDataHelper.GetDelegationChange("SKD/TaxReport", 50001338, coveredByPartyId: 50001336, performedByUserId: 20001339, changeType: DelegationChangeType.Grant));
            }

            if (altinnAppIds.Contains("SKD/TaxReport") && offeredByPartyIds.Contains(50001339) && (coveredByPartyIds != null && coveredByUserIds.Contains(20001336)))
            {
                result.Add(TestDataHelper.GetDelegationChange("SKD/TaxReport", 50001335, coveredByPartyId: 50001337, performedByUserId: 20001339, changeType: DelegationChangeType.Grant));
            }

            return(Task.FromResult(result));
        }