public void DoCreateUpdateRightsTrigger(ObjectClass objClass) { var updateRightsTriggerName = Construct.SecurityRulesUpdateRightsTriggerName(objClass); var tblName = db.GetTableName(objClass.Module.SchemaName, objClass.TableName); if (db.CheckTriggerExists(tblName, updateRightsTriggerName)) db.DropTrigger(tblName, updateRightsTriggerName); var tblList = new List<RightsTrigger>(); tblList.Add(new RightsTrigger() { TblName = db.GetTableName(objClass.Module.SchemaName, objClass.TableName), TblNameRights = db.GetTableName(objClass.Module.SchemaName, Construct.SecurityRulesTableName(objClass)), ViewUnmaterializedName = db.GetTableName(objClass.Module.SchemaName, Construct.SecurityRulesRightsViewUnmaterializedName(objClass)) }); // Get all ObjectClasses that depends on current object class var list = schema.GetQuery<ObjectClass>() .Where(o => o.AccessControlList.OfType<RoleMembership>() .Where(rm => rm.Relations .Where(r => r.A.Type == objClass || r.B.Type == objClass).Count() > 0).Count() > 0) .Distinct().ToList().Where(o => o.NeedsRightsTable() && o != objClass); foreach (var dep in list) { Log.DebugFormat(" Additional update Table: {0}", dep.TableName); foreach (var ac in dep.AccessControlList.OfType<RoleMembership>()) { var rel = ac.Relations.FirstOrDefault(r => r.A.Type == objClass || r.B.Type == objClass); if (rel != null) { var rt = new RightsTrigger() { TblName = db.GetTableName(dep.Module.SchemaName, dep.TableName), TblNameRights = db.GetTableName(dep.Module.SchemaName, Construct.SecurityRulesTableName(dep)), ViewUnmaterializedName = db.GetTableName(dep.Module.SchemaName, Construct.SecurityRulesRightsViewUnmaterializedName(dep)), }; try { rt.Relations.AddRange(SchemaManager.CreateJoinList(db, dep, ac.Relations, rel)); } catch (Zetbox.Server.SchemaManagement.SchemaManager.JoinListException ex) { Log.Warn("Unable to create UpdateRightsTrigger on " + objClass, ex); return; } tblList.Add(rt); } } } // do not check fk_ChangedBy since it always changes, even when only recalculations were done. // ACLs MUST never use ChangedBy information var fkCols = objClass.GetRelationEndsWithLocalStorage() .Where(r => !(r.Type.ImplementsIChangedBy() && r.Navigator != null && r.Navigator.Name =="ChangedBy")) .Select(r => Construct.ForeignKeyColumnName(r.GetParent().GetOtherEnd(r))) .ToList(); db.CreateUpdateRightsTrigger(updateRightsTriggerName, tblName, tblList, fkCols); }
public void DoCreateUpdateRightsTrigger(Relation rel) { var updateRightsTriggerName = Construct.SecurityRulesUpdateRightsTriggerName(rel); var tblName = db.GetTableName(rel.Module.SchemaName, rel.GetRelationTableName()); if (db.CheckTriggerExists(tblName, updateRightsTriggerName)) db.DropTrigger(tblName, updateRightsTriggerName); var tblList = new List<RightsTrigger>(); // Get all ObjectClasses that depends on current relation var list = schema.GetQuery<ObjectClass>() .Where(o => o.AccessControlList.OfType<RoleMembership>() .Where(rm => rm.Relations .Where(r => r == rel).Count() > 0).Count() > 0) .Distinct().ToList().Where(o => o.NeedsRightsTable()); foreach (var dep in list) { Log.DebugFormat(" Additional update Table: {0}", dep.TableName); foreach (var ac in dep.AccessControlList.OfType<RoleMembership>()) { if (ac.Relations.Contains(rel)) { var rt = new RightsTrigger() { TblName = db.GetTableName(dep.Module.SchemaName, dep.TableName), TblNameRights = db.GetTableName(dep.Module.SchemaName, Construct.SecurityRulesTableName(dep)), ViewUnmaterializedName = db.GetTableName(dep.Module.SchemaName, Construct.SecurityRulesRightsViewUnmaterializedName(dep)), }; try { // Ignore last one - this is our n:m end var joinList = SchemaManager.CreateJoinList(db, dep, ac.Relations, rel); rt.Relations.AddRange(joinList.Take(joinList.Count - 1)); } catch (Zetbox.Server.SchemaManagement.SchemaManager.JoinListException ex) { Log.Warn("Unable to create UpdateRightsTrigger on " + rel, ex); return; } tblList.Add(rt); } } } db.CreateUpdateRightsTrigger(updateRightsTriggerName, tblName, tblList, new List<string>() { Construct.ForeignKeyColumnName(rel.A), Construct.ForeignKeyColumnName(rel.B) }); }
public void DoCreateUpdateRightsTrigger(Relation rel) { var tblName = db.GetTableName(rel.Module.SchemaName, rel.GetRelationTableName()); var updateRightsTriggerName = new TriggerRef(tblName, Construct.SecurityRulesUpdateRightsTriggerName(rel)); if (db.CheckTriggerExists(updateRightsTriggerName)) db.DropTrigger(updateRightsTriggerName); var tblList = new List<RightsTrigger>(); // Get all ObjectClasses that depends on current relation var list = schema.GetQuery<ObjectClass>() .Where(o => o.AccessControlList.OfType<RoleMembership>() .Where(rm => rm.Relations .Where(r => r == rel).Count() > 0).Count() > 0) .Distinct().ToList().Where(o => o.NeedsRightsTable()); var identity = (ObjectClass)NamedObjects.Base.Classes.Zetbox.App.Base.Identity.Find(rel.Context); foreach (var dep in list) { Log.DebugFormat(" Additional update Table: {0}", dep.TableName); foreach (var ac in dep.AccessControlList.OfType<RoleMembership>()) { if (ac.Relations.Contains(rel)) { var rt = new RightsTrigger() { TblName = dep.GetTableRef(db), TblNameRights = db.GetTableName(dep.Module.SchemaName, Construct.SecurityRulesTableName(dep)), ViewUnmaterializedName = db.GetTableName(dep.Module.SchemaName, Construct.SecurityRulesRightsViewUnmaterializedName(dep)), }; try { // Ignore last join - our n:m end has two (in & out), but we only need the incoming one var objJoinList = SchemaManager.CreateJoinList(db, dep, ac.Relations.TakeWhileInclusive(r => r != rel)); rt.ObjectRelations.AddRange(objJoinList.Take(objJoinList.Count - 1)); // Ignore last join - our n:m end has two (in & out), but we only need the incoming one var idJoinList = SchemaManager.CreateJoinList(db, identity, ac.Relations.Reverse().TakeWhileInclusive(r => r != rel)); rt.IdentityRelations.AddRange(idJoinList.Take(idJoinList.Count - 1)); } catch (Zetbox.Server.SchemaManagement.SchemaManager.JoinListException ex) { Log.Warn("Unable to create UpdateRightsTrigger on " + rel, ex); return; } tblList.Add(rt); } } } db.CreateUpdateRightsTrigger(updateRightsTriggerName, tblName, tblList, new List<string>() { Construct.ForeignKeyColumnName(rel.A), Construct.ForeignKeyColumnName(rel.B) }); }