diff --git a/backend/Origam.Gui.Win/AsPanel.cs b/backend/Origam.Gui.Win/AsPanel.cs index 0034d867d1..f07aa3e26b 100644 --- a/backend/Origam.Gui.Win/AsPanel.cs +++ b/backend/Origam.Gui.Win/AsPanel.cs @@ -2119,7 +2119,7 @@ private void UpdateRowLevelSecurity(bool forceUpdate) string field = b.BindingMemberInfo.BindingField; fieldId = (Guid)row.Table.Columns[field].ExtendedProperties["Id"]; - control.Enabled = ruleEngine.RowLevelSecurityState(originalData, actualData, field, CredentialType.Update, entityId, fieldId, isNewRow); + control.Enabled = ruleEngine.EvaluateRowLevelSecurityState(originalData, actualData, field, CredentialType.Update, entityId, fieldId, isNewRow); if(control is IAsCaptionControl) { @@ -2134,7 +2134,7 @@ private void UpdateRowLevelSecurity(bool forceUpdate) } else { - control.Visible = ruleEngine.RowLevelSecurityState(originalData, actualData, field, CredentialType.Read, entityId, fieldId, isNewRow); + control.Visible = ruleEngine.EvaluateRowLevelSecurityState(originalData, actualData, field, CredentialType.Read, entityId, fieldId, isNewRow); } } } @@ -2142,12 +2142,12 @@ private void UpdateRowLevelSecurity(bool forceUpdate) if(_originalDisplayDeleteButton) { - this.ShowDeleteButton = ruleEngine.RowLevelSecurityState(originalData, actualData, null, CredentialType.Delete, entityId, fieldId, isNewRow); + this.ShowDeleteButton = ruleEngine.EvaluateRowLevelSecurityState(originalData, actualData, null, CredentialType.Delete, entityId, fieldId, isNewRow); } if(OriginalShowNewButton) { - this.ShowNewButton = ruleEngine.RowLevelSecurityState(originalData, actualData, null, CredentialType.Create, entityId, fieldId, isNewRow); + this.ShowNewButton = ruleEngine.EvaluateRowLevelSecurityState(originalData, actualData, null, CredentialType.Create, entityId, fieldId, isNewRow); } _lastRowLevelSecurityRecordId = this.RecordId; } diff --git a/backend/Origam.Gui.Win/Grid/AsCheckStyleColumn.cs b/backend/Origam.Gui.Win/Grid/AsCheckStyleColumn.cs index 4700282c4e..cf5750eb87 100644 --- a/backend/Origam.Gui.Win/Grid/AsCheckStyleColumn.cs +++ b/backend/Origam.Gui.Win/Grid/AsCheckStyleColumn.cs @@ -67,7 +67,7 @@ protected override void Edit(CurrencyManager source, int rowNum, Rectangle bound RuleEngine ruleEngine = (this.DataGridTableStyle.DataGrid.FindForm() as AsForm).FormGenerator.FormRuleEngine; if(ruleEngine != null) { - this.ReadOnly = ! ruleEngine.RowLevelSecurityState((source.Current as DataRowView).Row, this.MappingName, Schema.EntityModel.CredentialType.Update); + this.ReadOnly = ! ruleEngine.EvaluateRowLevelSecurityState((source.Current as DataRowView).Row, this.MappingName, Schema.EntityModel.CredentialType.Update); } } else diff --git a/backend/Origam.Gui.Win/Grid/AsTextStyleColumn.cs b/backend/Origam.Gui.Win/Grid/AsTextStyleColumn.cs index ab4ed6ce65..05545a1002 100644 --- a/backend/Origam.Gui.Win/Grid/AsTextStyleColumn.cs +++ b/backend/Origam.Gui.Win/Grid/AsTextStyleColumn.cs @@ -168,7 +168,7 @@ protected override void Edit(CurrencyManager source, int rowNum, Rectangle bound this.AsTextBox.Bounds = Rectangle.Empty; return; } - AsTextBox.ReadOnly = !ruleEngine.RowLevelSecurityState((source.Current as DataRowView).Row, this.MappingName, CredentialType.Update); + AsTextBox.ReadOnly = !ruleEngine.EvaluateRowLevelSecurityState((source.Current as DataRowView).Row, this.MappingName, CredentialType.Update); } } else @@ -221,7 +221,7 @@ private RuleEngine GetRuleEngine() private bool IsReadDenied(DataRow row, RuleEngine ruleEngine) { - return !ruleEngine.RowLevelSecurityState(row, this.MappingName, CredentialType.Read); + return !ruleEngine.EvaluateRowLevelSecurityState(row, this.MappingName, CredentialType.Read); } diff --git a/backend/Origam.Gui.Win/Grid/DataGridBlobColumn.cs b/backend/Origam.Gui.Win/Grid/DataGridBlobColumn.cs index c54db2aeb4..08fd931d46 100644 --- a/backend/Origam.Gui.Win/Grid/DataGridBlobColumn.cs +++ b/backend/Origam.Gui.Win/Grid/DataGridBlobColumn.cs @@ -117,7 +117,7 @@ protected override void Edit(CurrencyManager source, int rowNum, Rectangle bound { if(_ruleEngine != null) { - _blobControl.ReadOnly = ! _ruleEngine.RowLevelSecurityState((source.Current as DataRowView).Row, this.MappingName, Schema.EntityModel.CredentialType.Update); + _blobControl.ReadOnly = ! _ruleEngine.EvaluateRowLevelSecurityState((source.Current as DataRowView).Row, this.MappingName, Schema.EntityModel.CredentialType.Update); } } else diff --git a/backend/Origam.Gui.Win/Grid/DataGridBuilder.cs b/backend/Origam.Gui.Win/Grid/DataGridBuilder.cs index 108f1d71f4..82a9486c55 100644 --- a/backend/Origam.Gui.Win/Grid/DataGridBuilder.cs +++ b/backend/Origam.Gui.Win/Grid/DataGridBuilder.cs @@ -665,7 +665,7 @@ private void grid_MouseDown(object sender, MouseEventArgs e) // Now we change the value. if(grid.DataSource != null && hti.Row < grid.BindingContext[grid.DataSource, grid.DataMember].Count) { - bool canEdit = ruleEngine.RowLevelSecurityState((cm.Current as DataRowView).Row, grid.TableStyles[0].GridColumnStyles[hti.Column].MappingName, Schema.EntityModel.CredentialType.Update); + bool canEdit = ruleEngine.EvaluateRowLevelSecurityState((cm.Current as DataRowView).Row, grid.TableStyles[0].GridColumnStyles[hti.Column].MappingName, Schema.EntityModel.CredentialType.Update); if(canEdit) { @@ -701,7 +701,7 @@ private void grid_MouseDown(object sender, MouseEventArgs e) string columnName = grid.TableStyles[0].GridColumnStyles[hti.Column].PropertyDescriptor.Name; foreach(DataRow row in selectedRows) { - bool canEdit = ruleEngine.RowLevelSecurityState(row, columnName, Schema.EntityModel.CredentialType.Update); + bool canEdit = ruleEngine.EvaluateRowLevelSecurityState(row, columnName, Schema.EntityModel.CredentialType.Update); if(canEdit) { diff --git a/backend/Origam.Gui.Win/Grid/DataGridDropdownColumn.cs b/backend/Origam.Gui.Win/Grid/DataGridDropdownColumn.cs index 9ec66df9a1..49b790ec73 100644 --- a/backend/Origam.Gui.Win/Grid/DataGridDropdownColumn.cs +++ b/backend/Origam.Gui.Win/Grid/DataGridDropdownColumn.cs @@ -142,7 +142,7 @@ protected override void Edit(CurrencyManager source, int rowNum, Rectangle bound { if(_ruleEngine != null) { - _dropDown.ReadOnly = ! _ruleEngine.RowLevelSecurityState((source.Current as DataRowView).Row, this.MappingName, Schema.EntityModel.CredentialType.Update); + _dropDown.ReadOnly = ! _ruleEngine.EvaluateRowLevelSecurityState((source.Current as DataRowView).Row, this.MappingName, Schema.EntityModel.CredentialType.Update); } } else diff --git a/backend/Origam.Gui.Win/Grid/DataViewColumn.cs b/backend/Origam.Gui.Win/Grid/DataViewColumn.cs index 9ede2ddcb5..2e8c70711b 100644 --- a/backend/Origam.Gui.Win/Grid/DataViewColumn.cs +++ b/backend/Origam.Gui.Win/Grid/DataViewColumn.cs @@ -118,7 +118,7 @@ protected override void Edit(System.Windows.Forms.CurrencyManager source, int ro RuleEngine ruleEngine = (this.DataGridTableStyle.DataGrid.FindForm() as AsForm).FormGenerator.FormRuleEngine; if(ruleEngine != null) { - AsDateBox.ReadOnly = ! ruleEngine.RowLevelSecurityState((source.Current as DataRowView).Row, this.MappingName, Schema.EntityModel.CredentialType.Update); + AsDateBox.ReadOnly = ! ruleEngine.EvaluateRowLevelSecurityState((source.Current as DataRowView).Row, this.MappingName, Schema.EntityModel.CredentialType.Update); } } else diff --git a/backend/Origam.Rule/RowSecurityStateBuilder.cs b/backend/Origam.Rule/RowSecurityStateBuilder.cs new file mode 100644 index 0000000000..5cf1776214 --- /dev/null +++ b/backend/Origam.Rule/RowSecurityStateBuilder.cs @@ -0,0 +1,258 @@ +#region license +/* +Copyright 2005 - 2021 Advantage Solutions, s. r. o. + +This file is part of ORIGAM (http://www.origam.org). + +ORIGAM is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +ORIGAM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with ORIGAM. If not, see . +*/ +#endregion + +using Origam.DA; +using Origam.Schema.EntityModel; +using Origam.Service.Core; +using System; +using System.Data; +using Origam.Extensions; + +namespace Origam.Rule +{ + public class RowSecurityStateBuilder + { + private static readonly log4net.ILog log = + log4net.LogManager.GetLogger(System.Reflection.MethodBase. + GetCurrentMethod().DeclaringType); + public RowSecurityState Result { get; private set; } + private DataRow row; + private RuleEngine ruleEngine; + private Guid entityId; + private bool isNew; + private XmlContainer originalData; + private XmlContainer actualData; + private bool isBuildable; + + + public static RowSecurityState BuildFull(RuleEngine ruleEngine, + DataRow row, object profileId, Guid formId) + { + var builder = new RowSecurityStateBuilder(row, ruleEngine); + if (!builder.isBuildable) + { + return null; + } + return builder.AddMainEntityRowStateAndFormatting() + .AddMainEntityFieldStates() + .AddRelations(profileId) + .AddDisabledActions(formId) + .Result; + } + + public static RowSecurityState BuildWithoutRelationsAndActions( + RuleEngine ruleEngine, DataRow row) + { + var builder = new RowSecurityStateBuilder(row, ruleEngine); + if (!builder.isBuildable) + { + return null; + } + return builder.AddMainEntityRowStateAndFormatting() + .AddMainEntityFieldStates() + .Result; + } + + public static RowSecurityState + BuildJustMainEntityRowLevelEvenWithoutFields(RuleEngine ruleEngine, + DataRow row) + { + var builder = new RowSecurityStateBuilder(row, ruleEngine); + if (!builder.isBuildable) + { + return null; + } + return builder.AddMainEntityRowStateAndFormatting() + .Result; + } + + private RowSecurityStateBuilder(DataRow row, RuleEngine ruleEngine) + { + if (!DatasetTools.HasRowValidParent(row) + || row.Table.ExtendedProperties.Contains("EntityId")) + { + isBuildable = false; + } + + this.ruleEngine = ruleEngine; + this.row = row; + + // get extra info from row + entityId = (Guid)row.Table.ExtendedProperties["EntityId"]; + isNew = row.RowState == DataRowState.Added + || row.RowState == DataRowState.Detached; + originalData = DatasetTools.GetRowXml(row, + DataRowVersion.Original); + actualData = DatasetTools.GetRowXml(row, + row.HasVersion(DataRowVersion.Proposed) + ? DataRowVersion.Proposed : DataRowVersion.Default); + isBuildable = true; + } + + private RowSecurityStateBuilder AddMainEntityRowStateAndFormatting() + { + if (!isBuildable) + { + return this; + } + EntityFormatting formatting = ruleEngine.Formatting(actualData, + entityId, Guid.Empty, null); + + Result = new RowSecurityState + { + Id = DatasetTools.PrimaryKey(row)[0], + BackgroundColor = formatting.BackColor.ToArgb(), + ForegroundColor = formatting.ForeColor.ToArgb(), + AllowDelete = ruleEngine.EvaluateRowLevelSecurityState( + originalData, actualData, null, CredentialType.Delete, + entityId, Guid.Empty, isNew), + AllowCreate = ruleEngine.EvaluateRowLevelSecurityState( + originalData, actualData, null, CredentialType.Create, + entityId, Guid.Empty, isNew) + }; + return this; + } + + private RowSecurityStateBuilder AddMainEntityFieldStates() + { + if (!isBuildable) + { + return this; + } + foreach (DataColumn col in row.Table.Columns) + { + if (col.ExtendedProperties.Contains("Id")) + { + Guid fieldId = (Guid)col.ExtendedProperties["Id"]; + + bool allowUpdate = ruleEngine. + EvaluateRowLevelSecurityState(originalData, + actualData, col.ColumnName, + CredentialType.Update, + entityId, fieldId, isNew); + bool allowRead = ruleEngine. + EvaluateRowLevelSecurityState(originalData, + actualData, col.ColumnName, + CredentialType.Read, + entityId, fieldId, isNew); + EntityFormatting fieldFormatting = ruleEngine. + Formatting(actualData, entityId, fieldId, null); + string dynamicLabel = ruleEngine.DynamicLabel( + actualData, entityId, fieldId, null); + Result.Columns.Add(new FieldSecurityState( + col.ColumnName, + allowUpdate, allowRead, dynamicLabel, + fieldFormatting.BackColor.ToArgb(), + fieldFormatting.ForeColor.ToArgb())); + } + } + return this; + } + + private RowSecurityStateBuilder AddRelations(object profileId) + { + if (!isBuildable) + { + return this; + } + foreach (DataRelation rel in row.Table.ChildRelations) + { + Guid childEntityId = (Guid)rel.ChildTable. + ExtendedProperties["EntityId"]; + bool isDummyRow = false; + DataRow childRow = null; + DataRow[] childRows = row.GetChildRows(rel); + try + { + if (childRows.Length > 0) + { + childRow = childRows[0]; + } + else + { + isDummyRow = true; + childRow = DatasetTools.CreateRow(row, + rel.ChildTable, rel, profileId); + + // go through each column and lookup any looked-up + // column values + foreach (DataColumn childCol in + childRow.Table.Columns) + { +#if !ORIGAM_SERVER + if (childRow.RowState != DataRowState.Unchanged + && childRow.RowState != DataRowState.Detached) + { +#endif + ruleEngine.ProcessRulesLookupFields(childRow, + childCol.ColumnName); +#if !ORIGAM_SERVER + } +#endif + } + } + XmlContainer originalChildData = DatasetTools.GetRowXml( + childRow, DataRowVersion.Original); + XmlContainer actualChildData = DatasetTools.GetRowXml( + childRow, childRow.HasVersion(DataRowVersion.Proposed) + ? DataRowVersion.Proposed : DataRowVersion.Default); + bool allowRelationCreate = ruleEngine. + EvaluateRowLevelSecurityState(originalChildData, + actualChildData, null, + CredentialType.Create, + childEntityId, Guid.Empty, + row.RowState == DataRowState.Added + || row.RowState == DataRowState.Detached + ); + Result.Relations.Add(new RelationSecurityState( + rel.ChildTable.TableName, allowRelationCreate)); + } + catch (Exception ex) + { + if (log.IsErrorEnabled) + { + log.LogOrigamError(string.Format( + "Failed evaluating security rule for " + + "child relation {0} for entity {1}", + rel?.RelationName, entityId), ex); + } + throw; + } + finally + { + if (isDummyRow && childRow != null) childRow.Delete(); + } + } + return this; + } + + private RowSecurityStateBuilder AddDisabledActions(Guid formId) + { + if (!isBuildable) + { + return this; + } + Result.DisabledActions = ruleEngine.GetDisabledActions( + originalData, actualData, entityId, formId); + return this; + } + } +} diff --git a/backend/Origam.Rule/RuleEngine.cs b/backend/Origam.Rule/RuleEngine.cs index 9e2da58f79..faa26e5afe 100644 --- a/backend/Origam.Rule/RuleEngine.cs +++ b/backend/Origam.Rule/RuleEngine.cs @@ -1123,7 +1123,7 @@ private static IOutputPad GetOutputPad() return outputPad; } - private bool ProcessRulesLookupFields(DataRow row, string columnName) + public bool ProcessRulesLookupFields(DataRow row, string columnName) { bool changed = false; DataTable t = row.Table; @@ -1647,7 +1647,7 @@ public string DynamicLabel(XmlContainer data, Guid entityId, Guid fieldId, XPath #endregion #region Row Level Security Functions - public bool RowLevelSecurityState(DataRow row, string field, CredentialType type) + public bool EvaluateRowLevelSecurityState(DataRow row, string field, CredentialType type) { if(! DatasetTools.HasRowValidParent(row)) return true; @@ -1662,7 +1662,7 @@ public bool RowLevelSecurityState(DataRow row, string field, CredentialType type fieldId = (Guid)row.Table.Columns[field].ExtendedProperties["Id"]; entityId = (Guid)row.Table.ExtendedProperties["EntityId"]; - return RowLevelSecurityState(originalData, actualData, field, type, entityId, fieldId, row.RowState == DataRowState.Added || row.RowState == DataRowState.Detached); + return EvaluateRowLevelSecurityState(originalData, actualData, field, type, entityId, fieldId, row.RowState == DataRowState.Added || row.RowState == DataRowState.Detached); } else { @@ -1670,147 +1670,6 @@ public bool RowLevelSecurityState(DataRow row, string field, CredentialType type } } - public RowSecurityState RowLevelSecurityState(DataRow row, - object profileId) - { - return RowLevelSecurityState(row, profileId, Guid.Empty); - } - - public RowSecurityState RowLevelSecurityState(DataRow row, object profileId, Guid formId) - { - if(! DatasetTools.HasRowValidParent(row)) return null; - - if(row.Table.ExtendedProperties.Contains("EntityId")) - { - Guid entityId = (Guid)row.Table.ExtendedProperties["EntityId"]; - XmlContainer originalData = DatasetTools.GetRowXml(row, - DataRowVersion.Original); - XmlContainer actualData = DatasetTools.GetRowXml(row, - row.HasVersion(DataRowVersion.Proposed) - ? DataRowVersion.Proposed : DataRowVersion.Default); - EntityFormatting formatting = Formatting(actualData, - entityId, Guid.Empty, null); - bool isNew = row.RowState == DataRowState.Added - || row.RowState == DataRowState.Detached; - RowSecurityState result = new RowSecurityState - { - Id = DatasetTools.PrimaryKey(row)[0], - BackgroundColor = formatting.BackColor.ToArgb(), - ForegroundColor = formatting.ForeColor.ToArgb(), - AllowDelete = RowLevelSecurityState(originalData, - actualData, null, CredentialType.Delete, entityId, - Guid.Empty, isNew), - AllowCreate = RowLevelSecurityState(originalData, - actualData, null, CredentialType.Create, entityId, - Guid.Empty, isNew) - }; - - // columns - foreach(DataColumn col in row.Table.Columns) - { - if(col.ExtendedProperties.Contains("Id")) - { - Guid fieldId = (Guid)col.ExtendedProperties["Id"]; - - bool allowUpdate = RowLevelSecurityState(originalData, - actualData, col.ColumnName, CredentialType.Update, - entityId, fieldId, isNew); - bool allowRead = RowLevelSecurityState(originalData, - actualData, col.ColumnName, CredentialType.Read, - entityId, fieldId, isNew); - - EntityFormatting fieldFormatting = Formatting(actualData, - entityId, fieldId, null); - string dynamicLabel = this.DynamicLabel(actualData, - entityId, fieldId, null); - - result.Columns.Add(new FieldSecurityState(col.ColumnName, - allowUpdate, allowRead, dynamicLabel, - fieldFormatting.BackColor.ToArgb(), - fieldFormatting.ForeColor.ToArgb())); - } - } - - // relations - foreach (DataRelation rel in row.Table.ChildRelations) - { - Guid childEntityId = (Guid)rel.ChildTable.ExtendedProperties["EntityId"]; - bool isDummyRow = false; - DataRow childRow = null; - DataRow[] childRows = row.GetChildRows(rel); - try - { - if (childRows.Length > 0) - { - childRow = childRows[0]; - } - else - { - isDummyRow = true; - childRow = DatasetTools.CreateRow(row, rel.ChildTable, rel, profileId); - - // go through each column and lookup any looked-up column values - foreach (DataColumn childCol in childRow.Table.Columns) - { -#if !ORIGAM_SERVER - if (childRow.RowState != DataRowState.Unchanged - && childRow.RowState != DataRowState.Detached) - { -#endif - this.ProcessRulesLookupFields(childRow, childCol.ColumnName); -#if !ORIGAM_SERVER - } -#endif - } - } - - XmlContainer originalChildData = DatasetTools.GetRowXml( - childRow, DataRowVersion.Original); - XmlContainer actualChildData = DatasetTools.GetRowXml( - childRow, childRow.HasVersion(DataRowVersion.Proposed) - ? DataRowVersion.Proposed : DataRowVersion.Default); - - bool allowRelationCreate = RowLevelSecurityState(originalChildData, - actualChildData, - null, - CredentialType.Create, - childEntityId, - Guid.Empty, - row.RowState == DataRowState.Added || row.RowState == DataRowState.Detached - ); - - result.Relations.Add(new RelationSecurityState( - rel.ChildTable.TableName, allowRelationCreate)); - } - catch (Exception ex) - { - if (log.IsErrorEnabled) - { - log.LogOrigamError(string.Format( - "Failed evaluating security rule for child relation {0} for entity {1}", - rel?.RelationName, entityId), ex); - } - throw; - } - finally - { - if (isDummyRow && childRow != null) childRow.Delete(); - } - } - - // action buttons - // TODO: resolve only those action buttons valid for a current form - passing - // a screen/section id would be neccessary - result.DisabledActions = GetDisabledActions( - originalData, actualData, entityId, formId); - return result; - } - else - { - return null; - } - } - public ArrayList GetDisabledActions( XmlContainer originalData, XmlContainer actualData, Guid entityId, Guid formId) { @@ -1900,7 +1759,7 @@ XmlContainer dataToUseForRule dataToUseForRule, action.Rule, action.Roles, null); } - public bool RowLevelSecurityState(XmlContainer originalData, XmlContainer actualData, string field, CredentialType type, Guid entityId, Guid fieldId, bool isNewRow) + public bool EvaluateRowLevelSecurityState(XmlContainer originalData, XmlContainer actualData, string field, CredentialType type, Guid entityId, Guid fieldId, bool isNewRow) { ArrayList rules = new ArrayList(); @@ -2004,8 +1863,7 @@ private bool IsRuleMatching(XmlContainer data, IRule rule, string roles, XPathNo if(rule != null) { object result = this.EvaluateRule(rule, data, contextPosition); - - if(result is bool) + if (result is bool) { return (bool)result; } diff --git a/backend/Origam.Server/Common/UIManager.cs b/backend/Origam.Server/Common/UIManager.cs index 2d2f42228b..09c917ecfe 100644 --- a/backend/Origam.Server/Common/UIManager.cs +++ b/backend/Origam.Server/Common/UIManager.cs @@ -423,7 +423,7 @@ private UIResult InitDashboardView(string objectId, string viewId) XmlContainer newRecordData = new XmlContainer(); newRecordData.Xml.AppendChild( newRecordData.Xml.CreateElement("ROOT")); - panelConfig.AllowCreate = re.RowLevelSecurityState( + panelConfig.AllowCreate = re.EvaluateRowLevelSecurityState( newRecordData, newRecordData, null, CredentialType.Create, (Guid) data.Tables[panel.Entity] diff --git a/backend/Origam.Server/Pages/XsltPageRequestHandler.cs b/backend/Origam.Server/Pages/XsltPageRequestHandler.cs index 9f52ea86ea..dd662baa29 100644 --- a/backend/Origam.Server/Pages/XsltPageRequestHandler.cs +++ b/backend/Origam.Server/Pages/XsltPageRequestHandler.cs @@ -268,7 +268,7 @@ private void ProcessReadFieldRuleState(DataSet data, RuleEngine ruleEngine) dt.Columns.Cast().ToList().ForEach(columnD => columnD.AllowDBNull = true ); foreach (DataRow dataRow in dt.Rows) { - RowSecurityState rowSecurity = ruleEngine.RowLevelSecurityState(dataRow, profileId); + RowSecurityState rowSecurity = RowSecurityStateBuilder.BuildWithoutRelationsAndActions(ruleEngine, dataRow); if (rowSecurity != null) { List listState = rowSecurity.Columns.Cast().Where(columnState => !columnState.AllowRead).ToList(); diff --git a/backend/Origam.Server/Session Stores/SessionStore.cs b/backend/Origam.Server/Session Stores/SessionStore.cs index e47ec05669..f21c8fc772 100644 --- a/backend/Origam.Server/Session Stores/SessionStore.cs +++ b/backend/Origam.Server/Session Stores/SessionStore.cs @@ -1359,7 +1359,8 @@ public ArrayList RowStates(string entity, object[] ids) } else { - result.Add(RuleEngine.RowLevelSecurityState(row, profileId, FormId)); + result.Add(RowSecurityStateBuilder.BuildFull( + RuleEngine, row, profileId, FormId)); } } finally @@ -1383,16 +1384,18 @@ private ArrayList RowStatesForDataLessSessions(string entity, object[] ids, obje RowSearchResult rowSearchResult = GetRowsFromStore(entity, ids); foreach (var row in rowSearchResult.Rows) { - result.Add(RuleEngine.RowLevelSecurityState(row, profileId, FormId)); + result.Add(RowSecurityStateBuilder.BuildFull(RuleEngine, row, profileId, FormId)); } // try to get the rest from the database if (rowSearchResult.IdsNotFoundInStore.Count > 0) { - var loadedRows = LoadMissingRows(entity, rowSearchResult.IdsNotFoundInStore); + DataRowCollection loadedRows = LoadMissingRows(entity, + rowSearchResult.IdsNotFoundInStore); foreach (DataRow row in loadedRows) { - RowSecurityState rowSecurity = this.RuleEngine.RowLevelSecurityState(row, profileId, FormId); + RowSecurityState rowSecurity = RowSecurityStateBuilder. + BuildJustMainEntityRowLevelEvenWithoutFields(this.RuleEngine, row); if (rowSecurity != null) { result.Add(rowSecurity); @@ -1577,7 +1580,8 @@ public bool IsLazyLoadedEntity(string entity) } table.Rows.Add(newRow); - if (!this.RuleEngine.RowLevelSecurityState(newRow, profile.Id, FormId).AllowCreate) + if (!RowSecurityStateBuilder.BuildJustMainEntityRowLevelEvenWithoutFields( + RuleEngine, newRow).AllowCreate) { table.Rows.Remove(newRow); throw new Exception(Resources.ErrorCreateRecordNotAllowed); @@ -1980,7 +1984,8 @@ private static void BackupChildRows(DataRow parentRow, Dictionary