/// <summary> /// Filter what rows are included in the list based on the value of includeRemovedUsers. /// </summary> /// <param name="row">The row to examine.</param> /// <returns>False if IncludeRemovedUsers is false and the user has been removed; true otherwise.</returns> protected override bool Filter(DataRow row) { RightsHolderRow rightsHolderRow = null; UserRow[] userRow; if (row is RightsHolderRow) { rightsHolderRow = row as RightsHolderRow; } else if (row is EntityRow) { EntityRow entityRow = row as EntityRow; if (entityRow.GetRightsHolderRows().Length != 0) { rightsHolderRow = entityRow.GetRightsHolderRows()[0]; } } else { throw new RowNotHandledException("row isn't the right kind of row"); } userRow = rightsHolderRow.GetUserRows(); return(this.includeRemovedUsers || userRow.Length == 0 || !userRow[0].IsRemoved); }
/// <summary> /// Determine whether a rights holder has particular rights on an entity. /// </summary> /// <param name="rightsHolderRow">The rights holder</param> /// <param name="entity">The entity.</param> /// <param name="right">The required rights.</param> /// <returns>True if the rights holder has the specified rights to the entity.</returns> public static Boolean HasAccess(RightsHolderRow rightsHolderRow, EntityRow entity, AccessRight right) { // TODO: Remove this method? Current there are no calls to this method. // NOTE: This must be used in a background thread. Boolean grantedAccess = false; lock (DataModel.SyncRoot) { UserRow userRow = DataModel.User.UserKey.Find(rightsHolderRow.RightsHolderId); // See if the rights holder themself has access. foreach (AccessControlRow accessControlRow in rightsHolderRow.GetAccessControlRows()) { if (accessControlRow.EntityId == entity.EntityId && (accessControlRow.AccessRightRow.AccessRightCode & right) == right) { grantedAccess = true; } } if (userRow != null) { foreach (GroupUsersRow groupUsersRow in userRow.GetGroupUsersRows()) { if (AccessControl.HasAccess(groupUsersRow.GroupRow.RightsHolderRow, entity, right)) { grantedAccess = true; } } } } return(grantedAccess); }
/// <summary> /// Load rights holder specific information. /// </summary> protected override void FinishLoad() { RightsHolderRow rightsHolderRow = DataModel.RightsHolder.RightsHolderKey.Find(this.EntityId); base.FinishLoad(); tenant = new Tenant(DataModel.Tenant.TenantKey.Find(this.TenantId)); }
/// <summary> /// Grant a particular rights holder specific rights to an entity. /// </summary> /// <param name="rightsHolderId">The rights holder's id.</param> /// <param name="entityId">The entity's id.</param> /// <param name="rightId">The specific right's id.</param> /// <returns>The id of the AccessControl row.</returns> internal static Guid GrantAccess(Guid rightsHolderId, Guid entityId, Guid rightId) { DataModelTransaction transaction = DataModelTransaction.Current; DataModel dataModel = new DataModel(); Guid currentUserId = TradingSupport.UserId; UserRow currentUserRow = DataModel.User.UserKey.Find(currentUserId); RightsHolderRow rightsHolderRow = DataModel.RightsHolder.RightsHolderKey.Find(rightsHolderId); Guid rightsHolderTenantId; AccessControlRow accessControlRow = DataModel.AccessControl.AccessControlKeyRightsHolderIdEntityId.Find(rightsHolderId, entityId); Guid accessControlId = Guid.Empty; // Determine whether current user has write access to the entity. if (!DataModelFilters.HasAccess(transaction, currentUserId, entityId, AccessRight.Write)) { throw new FaultException <SecurityFault>( new SecurityFault(String.Format("{0} does not write permission to {1}", rightsHolderId, entityId))); } rightsHolderRow.AcquireReaderLock(transaction); rightsHolderTenantId = rightsHolderRow.TenantId; rightsHolderRow.ReleaseReaderLock(transaction.TransactionId); // Determine whether current user's tenant is upstream from rights holder we're modifying. if (!DataModelFilters.HasTenantAccess(transaction, currentUserId, rightsHolderTenantId)) { throw new FaultException <SecurityFault>( new SecurityFault(String.Format("{0} does not control over tenant {1}", rightsHolderId, rightsHolderTenantId))); } if (accessControlRow != null) { accessControlRow.AcquireWriterLock(transaction); accessControlId = accessControlRow.AccessControlId; dataModel.UpdateAccessControl( accessControlRow.AccessControlId, new object[] { accessControlRow.AccessControlId }, rightId, entityId, rightsHolderId, accessControlRow.RowVersion, rightsHolderTenantId); } else { accessControlId = Guid.NewGuid(); dataModel.CreateAccessControl( accessControlId, rightId, entityId, rightsHolderId, rightsHolderTenantId); } return(accessControlId); }
/// <summary> /// Find the organization an entity belongs to. /// </summary> /// <param name="transaction">The current transaction.</param> /// <returns>The organization's entity Id.</returns> private Guid FindOrganization(DataModelTransaction transaction) { Guid userId = TradingSupport.UserId; RightsHolderRow rightsHolderRow = DataModel.RightsHolder.RightsHolderKey.Find(userId); Guid organization; if (rightsHolderRow == null) { throw new FaultException <OptimisticConcurrencyFault>( new OptimisticConcurrencyFault("RightsHolder", new object[] { userId }), "The current user has been deleted"); } rightsHolderRow.AcquireReaderLock(transaction); organization = rightsHolderRow.TenantId; rightsHolderRow.ReleaseLock(transaction.TransactionId); return(organization); }
/// <summary> /// Revoke any and all access a rights holder has to an entity. /// </summary> /// <param name="rightsHolderId">The rights holder's id.</param> /// <param name="entityId">The entity's id.</param> /// <returns>The error code.</returns> internal static ErrorCode RevokeAccess(Guid rightsHolderId, Guid entityId) { DataModelTransaction transaction = DataModelTransaction.Current; DataModel dataModel = new DataModel(); Guid currentUserId = TradingSupport.UserId; UserRow currentUserRow = DataModel.User.UserKey.Find(currentUserId); RightsHolderRow rightsHolderRow = DataModel.RightsHolder.RightsHolderKey.Find(rightsHolderId); Guid rightsHolderTenantId; AccessControlRow accessControlRow = DataModel.AccessControl.AccessControlKeyRightsHolderIdEntityId.Find(rightsHolderId, entityId); // Determine whether current user has write access to the entity. if (!DataModelFilters.HasAccess(transaction, currentUserId, entityId, AccessRight.Write)) { return(ErrorCode.AccessDenied); } rightsHolderRow.AcquireReaderLock(transaction); rightsHolderTenantId = rightsHolderRow.TenantId; rightsHolderRow.ReleaseReaderLock(transaction.TransactionId); // Determine whether current user's tenant is upstream from rights holder we're modifying. if (!DataModelFilters.HasTenantAccess(transaction, currentUserId, rightsHolderTenantId)) { return(ErrorCode.AccessDenied); } if (accessControlRow != null) { accessControlRow.AcquireWriterLock(transaction); dataModel.DestroyAccessControl(new object[] { accessControlRow.AccessControlId }, accessControlRow.RowVersion); } else { return(ErrorCode.RecordNotFound); } return(ErrorCode.Success); }