public void TestDelegateDecision() { using (var fake = new AutoFake()) { var provider = fake.Resolve <IServiceLocator>(); var transitionRepository = new InMemoryRepository <Transition>(new List <Transition>()); FakeNode node = new FakeNode(); transitionRepository.Add(new Transition() { From = node, Name = "pass" }); A.CallTo(() => provider.GetInstance <IRepository <Transition> >()).Returns(transitionRepository); ServiceLocator.SetLocatorProvider(() => provider); DelegationHelper delegationHelper = new DelegationHelper(); DelegationDef delegationDef = new DelegationDef(); delegationDef.ClassName = "DecisionTest"; ExecutionContext context = new ExecutionContext(null, null, null); context.Node = node; Assert.AreEqual("pass", delegationHelper.DelegateDecision(delegationDef, context).Name); } }
public async Task<ActionResult> DeleteRule([FromBody] RequestToDeleteRuleList rulesToDelete) { if (!ModelState.IsValid) { return BadRequest(ModelState); } List<Rule> deletionResults = await _pap.TryDeleteDelegationPolicyRules(rulesToDelete); int ruleCountToDelete = DelegationHelper.GetRulesCountToDeleteFromRequestToDelete(rulesToDelete); int deletionResultsCount = deletionResults.Count; if (deletionResultsCount == ruleCountToDelete) { return StatusCode(200, deletionResults); } string rulesToDeleteSerialized = JsonSerializer.Serialize(rulesToDelete); if (deletionResultsCount > 0) { string deletionResultsSerialized = JsonSerializer.Serialize(deletionResults); _logger.LogInformation("Partial deletion completed deleted {deletionResultsCount} of {ruleCountToDelete}.\n{rulesToDeleteSerialized}\n{deletionResultsSerialized}", deletionResultsCount, ruleCountToDelete, rulesToDeleteSerialized, deletionResultsSerialized); return StatusCode(206, deletionResults); } _logger.LogInformation("Deletion could not be completed. None of the rules could be processed, indicating invalid or incomplete input:\n{rulesToDeleteSerialized}", rulesToDeleteSerialized); return StatusCode(400, $"Unable to complete deletion"); }
public async Task<ActionResult> DeletePolicy([FromBody] RequestToDeletePolicyList policiesToDelete) { if (!ModelState.IsValid) { return BadRequest(ModelState); } List<Rule> deletionResults = await _pap.TryDeleteDelegationPolicies(policiesToDelete); int countPolicies = DelegationHelper.GetPolicyCount(deletionResults); int policiesToDeleteCount = policiesToDelete.Count; if (countPolicies == policiesToDeleteCount) { return StatusCode(200, deletionResults); } string policiesToDeleteSerialized = JsonSerializer.Serialize(policiesToDelete); if (countPolicies > 0) { string deletionResultsSerialized = JsonSerializer.Serialize(deletionResults); _logger.LogInformation("Partial deletion completed deleted {countPolicies} of {policiesToDeleteCount}.\n{deletionResultsSerialized}", countPolicies, policiesToDeleteCount, deletionResultsSerialized); return StatusCode(206, deletionResults); } _logger.LogInformation("Deletion could not be completed. None of the rules could be processed, indicating invalid or incomplete input:\n{policiesToDeleteSerialized}", policiesToDeleteSerialized); return StatusCode(400, $"Unable to complete deletion"); }
private async Task <List <Rule> > DeleteRulesInPolicy(RequestToDelete rulesToDelete) { string coveredBy = DelegationHelper.GetCoveredByFromMatch(rulesToDelete.PolicyMatch.CoveredBy, out int?coveredByUserId, out int?coveredByPartyId); DelegationHelper.TryGetResourceFromAttributeMatch(rulesToDelete.PolicyMatch.Resource, out string org, out string app); string policyPath; try { policyPath = PolicyHelper.GetAltinnAppDelegationPolicyPath(org, app, rulesToDelete.PolicyMatch.OfferedByPartyId.ToString(), coveredByUserId, coveredByPartyId); } catch (Exception ex) { string rulesToDeleteString = string.Join(", ", rulesToDelete.RuleIds); _logger.LogError(ex, "Not possible to build policy path App: {org}/{app} CoveredBy: {coveredBy} OfferedBy: {policyToDelete.PolicyMatch.OfferedByPartyId} RuleIds: {rulesToDeleteString}", org, app, coveredBy, rulesToDelete.PolicyMatch.OfferedByPartyId, rulesToDeleteString); 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); } List <Rule> currentRules = await ProcessPolicyFile(policyPath, org, app, rulesToDelete); return(currentRules); }
public void UpdateUserDelegationTest() { //新增或修改 string userID = UuidHelper.NewUuidString(); string duserID = UuidHelper.NewUuidString(); WfClientDelegation delegation = DelegationHelper.PrepareDelegation(); delegation.SourceUserID = userID; WfClientProcessDescriptorServiceProxy.Instance.UpdateUserDelegation(delegation);//新增加 int count = WfClientProcessDescriptorServiceProxy.Instance.LoadUserDelegations(delegation.SourceUserID).Count; Assert.AreEqual(1, count); delegation.DestinationUserID = duserID; //修改被委托人信息 WfClientProcessDescriptorServiceProxy.Instance.UpdateUserDelegation(delegation); //新增加 count = WfClientProcessDescriptorServiceProxy.Instance.LoadUserDelegations(delegation.SourceUserID).Count; Assert.AreEqual(2, count); delegation.StartTime = System.DateTime.Now.Date; WfClientProcessDescriptorServiceProxy.Instance.UpdateUserDelegation(delegation);//更新 count = WfClientProcessDescriptorServiceProxy.Instance.LoadUserDelegations(delegation.SourceUserID).Count; Assert.AreEqual(2, count); WfClientDelegationCollection list = WfClientProcessDescriptorServiceProxy.Instance.LoadUserDelegations(delegation.SourceUserID); WfClientDelegation delegation2 = list.Find(w => w.DestinationUserID == duserID); //传递过程,客户端扩展的属性会丢失 delegation.ApplicationName = string.Empty; delegation.TenantCode = string.Empty; delegation.ProgramName = string.Empty; delegation.AreSame(delegation2); }
public async Task<ActionResult<List<Rule>>> GetRules([FromBody] RuleQuery ruleQuery, [FromQuery] bool onlyDirectDelegations = false) { List<int> coveredByPartyIds = new List<int>(); List<int> coveredByUserIds = new List<int>(); List<int> offeredByPartyIds = new List<int>(); List<string> appIds = new List<string>(); if (ruleQuery.KeyRolePartyIds.Any(id => id != 0)) { coveredByPartyIds.AddRange(ruleQuery.KeyRolePartyIds); } if (ruleQuery.ParentPartyId != 0) { offeredByPartyIds.Add(ruleQuery.ParentPartyId); } foreach (List<AttributeMatch> resource in ruleQuery.Resources) { string org = resource.FirstOrDefault(match => match.Id == XacmlRequestAttribute.OrgAttribute)?.Value; string app = resource.FirstOrDefault(match => match.Id == XacmlRequestAttribute.AppAttribute)?.Value; if (!string.IsNullOrEmpty(org) && !string.IsNullOrEmpty(app)) { appIds.Add($"{org}/{app}"); } } if (DelegationHelper.TryGetCoveredByPartyIdFromMatch(ruleQuery.CoveredBy, out int partyId)) { coveredByPartyIds.Add(partyId); } else if (DelegationHelper.TryGetCoveredByUserIdFromMatch(ruleQuery.CoveredBy, out int userId)) { coveredByUserIds.Add(userId); } if (ruleQuery.OfferedByPartyId != 0) { offeredByPartyIds.Add(ruleQuery.OfferedByPartyId); } if (offeredByPartyIds.Count == 0) { _logger.LogInformation($"Unable to get the rules: Missing offeredbyPartyId value."); return StatusCode(400, $"Unable to get the rules: Missing offeredbyPartyId value."); } if (offeredByPartyIds.Count == 0 && coveredByPartyIds.Count == 0 && coveredByUserIds.Count == 0) { _logger.LogInformation($"Unable to get the rules: Missing offeredby and coveredby values."); return StatusCode(400, $"Unable to get the rules: Missing offeredby and coveredby values."); } List<Rule> rulesList = await _pip.GetRulesAsync(appIds, offeredByPartyIds, coveredByPartyIds, coveredByUserIds); DelegationHelper.SetRuleType(rulesList, ruleQuery.OfferedByPartyId, ruleQuery.KeyRolePartyIds, ruleQuery.CoveredBy, ruleQuery.ParentPartyId); return Ok(rulesList); }
public async void PolicyContainsMatchingRule_PolicyContainsRule_InvalidApp_False() { // Arrange Rule rule = TestDataHelper.GetRuleModel(20001337, 50001337, "20001336", AltinnXacmlConstants.MatchAttributeIdentifiers.UserAttribute, "read", "org2", "app1"); XacmlPolicy policy = await _prpMock.GetPolicyAsync("org1", "app1"); // Act bool actual = DelegationHelper.PolicyContainsMatchingRule(policy, rule); // Assert Assert.False(actual); }
public async void PolicyContainsMatchingRule_PolicyContainsRule_PolicyResourcesOutOfOrder_True() { // Arrange Rule rule = TestDataHelper.GetRuleModel(20001337, 50001337, "20001336", AltinnXacmlConstants.MatchAttributeIdentifiers.UserAttribute, "read", "org1", "unorderedresources"); XacmlPolicy policy = await _prpMock.GetPolicyAsync("org1", "unorderedresources"); // Act bool actual = DelegationHelper.PolicyContainsMatchingRule(policy, rule); // Assert Assert.True(actual); }
public async void PolicyContainsMatchingRule_PolicyContainsRule_PolicyWithoutAppLevelResource_False() { // Arrange Rule rule = TestDataHelper.GetRuleModel(20001337, 50001337, "20001336", AltinnXacmlConstants.MatchAttributeIdentifiers.UserAttribute, "eat", "org1", "singlecomplexrule"); XacmlPolicy policy = await _prpMock.GetPolicyAsync("org1", "singlecomplexrule"); // Act bool actual = DelegationHelper.PolicyContainsMatchingRule(policy, rule); // Assert Assert.False(actual); }
public void TestDelegateFork() { DelegationHelper delegationHelper = new DelegationHelper(); DelegationDef delegationDef = new DelegationDef(); delegationDef.ClassName = "ForkTest"; ExecutionContext context = new ExecutionContext(null, null, null); delegationHelper.DelegateFork(delegationDef, context); }
public void TestDelegateSerializer() { DelegationHelper delegationHelper = new DelegationHelper(); DelegationDef delegationDef = new DelegationDef(); delegationDef.ClassName = "SerializerTest"; var serializer = delegationHelper.DelegateSerializer(delegationDef); Evaluation result = (Evaluation)serializer.Deserialize("approve"); Assert.AreEqual(Evaluation.APPROVE, result); }
public void TestDelegateJoin() { DelegationHelper delegationHelper = new DelegationHelper(); DelegationDef delegationDef = new DelegationDef(); delegationDef.ClassName = "JoinTest"; ExecutionContext context = new ExecutionContext(null, null, null); bool reactiveFlow = delegationHelper.DelegateJoin(delegationDef, context); Assert.IsFalse(reactiveFlow); }
public void SortRulesByDelegationPolicyPath_ThreeAppsSameOfferedByAndCoveredBy_Success() { // Arrange int delegatedByUserId = 20001336; int offeredByPartyId = 50001337; string coveredBy = "20001337"; string coveredByType = AltinnXacmlConstants.MatchAttributeIdentifiers.UserAttribute; List <Rule> unsortedRules = new List <Rule> { TestDataHelper.GetRuleModel(delegatedByUserId, offeredByPartyId, coveredBy, coveredByType, "read", "org1", "app1"), TestDataHelper.GetRuleModel(delegatedByUserId, offeredByPartyId, coveredBy, coveredByType, "read", "org2", "app1"), TestDataHelper.GetRuleModel(delegatedByUserId, offeredByPartyId, coveredBy, coveredByType, "read", "org1", "App2"), TestDataHelper.GetRuleModel(delegatedByUserId, offeredByPartyId, coveredBy, coveredByType, "write", "org1", "app1", "task1"), // Should be sorted together with the first rule TestDataHelper.GetRuleModel(delegatedByUserId, offeredByPartyId, coveredBy, coveredByType, "read", "org1", "app1", task: null, "event1") // Should be sorted together with the first rule }; Dictionary <string, List <Rule> > expected = new Dictionary <string, List <Rule> >(); expected.Add($"org1/app1/{offeredByPartyId}/u{coveredBy}/delegationpolicy.xml", new List <Rule> { TestDataHelper.GetRuleModel(delegatedByUserId, offeredByPartyId, coveredBy, coveredByType, "read", "org1", "app1"), TestDataHelper.GetRuleModel(delegatedByUserId, offeredByPartyId, coveredBy, coveredByType, "write", "org1", "app1", "task1"), TestDataHelper.GetRuleModel(delegatedByUserId, offeredByPartyId, coveredBy, coveredByType, "read", "org1", "app1", task: null, "event1") }); expected.Add($"org2/app1/{offeredByPartyId}/u{coveredBy}/delegationpolicy.xml", new List <Rule> { TestDataHelper.GetRuleModel(delegatedByUserId, offeredByPartyId, coveredBy, coveredByType, "read", "org2", "app1") }); expected.Add($"org1/App2/{offeredByPartyId}/u{coveredBy}/delegationpolicy.xml", new List <Rule> { TestDataHelper.GetRuleModel(delegatedByUserId, offeredByPartyId, coveredBy, coveredByType, "read", "org1", "App2") }); // Act Dictionary <string, List <Rule> > actual = DelegationHelper.SortRulesByDelegationPolicyPath(unsortedRules, out List <Rule> unsortables); // Assert Assert.NotNull(actual); Assert.Empty(unsortables); Assert.Equal(expected.Keys.Count, actual.Keys.Count); foreach (string expectedPathKey in expected.Keys) { Assert.True(actual.ContainsKey(expectedPathKey)); Assert.Equal(expected[expectedPathKey].Count, actual[expectedPathKey].Count); AssertionUtil.AssertEqual(expected[expectedPathKey], actual[expectedPathKey]); } }
/// <inheritdoc/> public async Task <List <Rule> > TryWriteDelegationPolicyRules(List <Rule> rules) { List <Rule> result = new List <Rule>(); Dictionary <string, List <Rule> > delegationDict = DelegationHelper.SortRulesByDelegationPolicyPath(rules, out List <Rule> unsortables); foreach (string delegationPolicypath in delegationDict.Keys) { bool writePolicySuccess = false; try { writePolicySuccess = await WriteDelegationPolicyInternal(delegationPolicypath, delegationDict[delegationPolicypath]); } catch (Exception ex) { _logger.LogError(ex, "An exception occured while processing authorization rules for delegation on delegation policy path: {delegationPolicypath}", delegationPolicypath); } foreach (Rule rule in delegationDict[delegationPolicypath]) { if (writePolicySuccess) { rule.CreatedSuccessfully = true; rule.Type = RuleType.DirectlyDelegated; } else { rule.RuleId = string.Empty; } result.Add(rule); } } if (unsortables.Count > 0) { string unsortablesJson = JsonSerializer.Serialize(unsortables); _logger.LogError("One or more rules could not be processed because of incomplete input:\n{unsortablesJson}", unsortablesJson); result.AddRange(unsortables); } return(result); }
public void SortRulesByDelegationPolicyPath_Unsortables_Success() { // Arrange int delegatedByUserId = 20001336; int offeredByPartyId = 50001337; List <Rule> unsortedRules = new List <Rule> { TestDataHelper.GetRuleModel(delegatedByUserId, offeredByPartyId, "20001337", AltinnXacmlConstants.MatchAttributeIdentifiers.UserAttribute, "read", "org1", "app1", "task1"), TestDataHelper.GetRuleModel(delegatedByUserId, offeredByPartyId, "20001337", AltinnXacmlConstants.MatchAttributeIdentifiers.UserAttribute, "read", null, "app1"), TestDataHelper.GetRuleModel(delegatedByUserId, offeredByPartyId, "20001337", AltinnXacmlConstants.MatchAttributeIdentifiers.UserAttribute, "write", "org1", "app1") }; Dictionary <string, List <Rule> > expected = new Dictionary <string, List <Rule> >(); expected.Add($"org1/app1/{offeredByPartyId}/u20001337/delegationpolicy.xml", new List <Rule> { TestDataHelper.GetRuleModel(delegatedByUserId, offeredByPartyId, "20001337", AltinnXacmlConstants.MatchAttributeIdentifiers.UserAttribute, "read", "org1", "app1", "task1"), TestDataHelper.GetRuleModel(delegatedByUserId, offeredByPartyId, "20001337", AltinnXacmlConstants.MatchAttributeIdentifiers.UserAttribute, "write", "org1", "app1") }); List <Rule> expectedUnsortable = new List <Rule> { TestDataHelper.GetRuleModel(delegatedByUserId, offeredByPartyId, "20001337", AltinnXacmlConstants.MatchAttributeIdentifiers.UserAttribute, "read", null, "app1") }; // Act Dictionary <string, List <Rule> > actual = DelegationHelper.SortRulesByDelegationPolicyPath(unsortedRules, out List <Rule> unsortables); // Assert Assert.NotNull(actual); Assert.Equal(expectedUnsortable.Count, unsortables.Count); AssertionUtil.AssertEqual(expectedUnsortable, unsortables); Assert.Equal(expected.Keys.Count, actual.Keys.Count); foreach (string expectedPathKey in expected.Keys) { Assert.True(actual.ContainsKey(expectedPathKey)); Assert.Equal(expected[expectedPathKey].Count, actual[expectedPathKey].Count); AssertionUtil.AssertEqual(expected[expectedPathKey], actual[expectedPathKey]); } }
public void LoadUserDelegationsTest() { string userID = UuidHelper.NewUuidString(); WfClientDelegationCollection delegations = DelegationHelper.PrepareDelegations(userID); WfClientDelegationCollection sd = WfClientProcessDescriptorServiceProxy.Instance.LoadUserDelegations(userID); //传递过程,客户端扩展的属性会丢失 delegations.ForEach(action => { action.ApplicationName = string.Empty; action.ProgramName = string.Empty; action.TenantCode = string.Empty; }); //默认排序 sd.Sort((m, n) => m.SourceUserName.CompareTo(n.SourceUserName)); delegations.AreSame(sd); }
public void TestDelegateAction() { DelegationHelper delegationHelper = new DelegationHelper(); DelegationDef delegationDef = new DelegationDef(); delegationDef.ClassName = "ActionTest"; delegationDef.Configuration = "<cfg>" + "<parameter name = \"to\" > previousActor </parameter>" + "<parameter name = \"subject\" > you requested a holiday </parameter>" + "<parameter name = \"message\" > you requested a holiday from ${ start date}" + "to ${ end date}" + "with comment ${ comment}</parameter>" + "</cfg> "; ExecutionContext context = new ExecutionContext(null, null, null); delegationHelper.DelegateAction(delegationDef, context); Assert.IsTrue(context.Configuration.ContainsKey("test")); Assert.AreEqual("1234", context.Configuration["test"]); }
public void DeleteUserDelegationTest() { string userID = UuidHelper.NewUuidString(); WfClientDelegationCollection delegations = DelegationHelper.PrepareDelegations(userID); WfClientDelegationCollection delegations2 = DelegationHelper.PrepareDelegations(userID); delegations2.ForEach(action => delegations.Add(action));//同一委托人构建多条委托数据 int count = delegations.Count; Assert.IsTrue(count > 2); WfClientDelegation delegation = delegations[0]; WfClientProcessDescriptorServiceProxy.Instance.DeleteUserDelegation(delegation); int tmpCount = WfClientProcessDescriptorServiceProxy.Instance.LoadUserDelegations(userID).Count; Assert.AreEqual(count - 1, tmpCount); WfClientProcessDescriptorServiceProxy.Instance.DeleteUserDelegation(userID); tmpCount = WfClientProcessDescriptorServiceProxy.Instance.LoadUserDelegations(userID).Count; Assert.AreEqual(0, tmpCount); }
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); }
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); } }
static SchedulerComponentImpl() { delegationHelper = DelegationHelper.Instance; }
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); }