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); }
/// <summary> /// Creates a Rule representation based on a search and a xacmlRule found in a XacmlPolicyFile based on the search /// </summary> /// <param name="search">The search used to find the correct rule</param> /// <param name="xacmlRule">XacmlRule found by the search param to enrich the result with Action and Resource</param> /// <returns>The created Rule</returns> public static Rule CreateRuleFromPolicyAndRuleMatch(RequestToDelete search, XacmlRule xacmlRule) { Rule rule = new Rule { RuleId = xacmlRule.RuleId, CreatedSuccessfully = true, DelegatedByUserId = search.DeletedByUserId, OfferedByPartyId = search.PolicyMatch.OfferedByPartyId, CoveredBy = search.PolicyMatch.CoveredBy, Resource = GetResourceFromXcamlRule(xacmlRule), Action = GetActionValueFromRule(xacmlRule) }; return(rule); }
public static RequestToDelete GetRequestToDeleteModel(int lastChangedByUserId, int offeredByPartyId, string org, string app, List <string> ruleIds = null, int?coveredByPartyId = null, int?coveredByUserId = null) { AttributeMatch coveredBy = new AttributeMatch(); if (coveredByUserId == null) { coveredBy.Id = AltinnXacmlConstants.MatchAttributeIdentifiers.PartyAttribute; coveredBy.Value = coveredByPartyId.ToString(); } else { coveredBy.Id = AltinnXacmlConstants.MatchAttributeIdentifiers.UserAttribute; coveredBy.Value = coveredByUserId.ToString(); } RequestToDelete requestToDelete = new RequestToDelete { DeletedByUserId = lastChangedByUserId, PolicyMatch = new PolicyMatch { CoveredBy = new List <AttributeMatch> { coveredBy }, OfferedByPartyId = offeredByPartyId, Resource = new List <AttributeMatch> { new AttributeMatch { Id = AltinnXacmlConstants.MatchAttributeIdentifiers.OrgAttribute, Value = org }, new AttributeMatch { Id = AltinnXacmlConstants.MatchAttributeIdentifiers.AppAttribute, Value = app } } }, RuleIds = ruleIds }; return(requestToDelete); }
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); } }
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); }