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); }