diff --git a/contracts/RightsManager.sol b/contracts/RightsManager.sol index 64cf96f..b2245d5 100644 --- a/contracts/RightsManager.sol +++ b/contracts/RightsManager.sol @@ -412,19 +412,4 @@ contract RightsManager is _registerPolicy(account, contentId, policy); emit GrantedAccess(account, contentId); } - - /// @inheritdoc IRightsAccessController - /// @notice Removes a specific policy associated with a given content ID. - /// @dev This function allows the removal of a policy from the list of policies linked to a specific content ID. - /// @param contentId The ID of the content from which the policy is to be removed. - /// @param policy The address of the policy that needs to be removed. - /// @return True if the policy was removed succesfully, false otherwise. - function removePolicy( - uint256 contentId, - address policy - ) external onlyRegisteredContent(contentId) returns (bool) { - // remove registered policy to account and content id.. - return _removePolicy(_msgSender(), contentId, policy); - // TODO add event - } } diff --git a/contracts/Treasury.sol b/contracts/Treasury.sol index 6acfa0d..06ed5f7 100644 --- a/contracts/Treasury.sol +++ b/contracts/Treasury.sol @@ -51,15 +51,13 @@ contract Treasury is } /// @notice Withdraws funds from the contract to a specified recipient's address. - /// @param recipient The address that will receive the withdrawn funds. /// @param amount The amount of tokens to withdraw. /// @param currency The currency to associate fees with. Use address(0) for the native coin. /// @dev This function can only be called by the owner of the contract or an authorized entity. function withdraw( - address recipient, uint256 amount, address currency - ) public override onlyGov {} + ) public onlyGov {} // TODO multisignature withdraw } diff --git a/contracts/base/upgradeable/extensions/RightsManagerContentAccessUpgradeable.sol b/contracts/base/upgradeable/extensions/RightsManagerContentAccessUpgradeable.sol index 040f9b1..730f927 100644 --- a/contracts/base/upgradeable/extensions/RightsManagerContentAccessUpgradeable.sol +++ b/contracts/base/upgradeable/extensions/RightsManagerContentAccessUpgradeable.sol @@ -60,37 +60,30 @@ abstract contract RightsManagerContentAccessUpgradeable is _; } - /// @notice Registers a policy for a specific account and content ID. - /// @dev This function adds a policy to the ACL storage, granting access to the specified account for the given content ID. - /// @param account The address of the account to be granted access. - /// @param contentId The ID of the content for which access is being granted. - /// @param policy The address of the contract responsible for validating the conditions of the license. + /// @notice Registers a new policy for a specific account and content ID, maintaining a chain of precedence. + /// @dev This function manages the ACL (Access Control List) storage by adding a new policy for the given account and content ID. + /// It ensures that only a fixed number of policies (defined by MAX_POLICIES) are active at any time by removing the oldest policy + /// when the limit is reached. The newest policy is always added to the end of the list, following a LIFO (Last-In-First-Out) precedence. + /// @param account The address of the account to be granted access through the policy. + /// @param contentId The ID of the content for which the access policy is being registered. + /// @param policy The address of the policy contract responsible for validating the conditions of the license. function _registerPolicy( address account, uint256 contentId, address policy ) internal { ACLStorage storage $ = _getACLStorage(); - // to avoid abuse or misusing of the protocol, we limit the maximum policies allowed.. - if ($._acl[contentId][account].length() >= MAX_POLICIES) - revert MaxPoliciesReached(); + // Ensure the total number of policies does not exceed MAX_POLICIES + // rolling policies window registry.. + if ($._acl[contentId][account].length() >= MAX_POLICIES) { + // Remove the oldest policy (first in the list) to maintain the policy limit + address oldest = $._acl[contentId][account].at(0); + $._acl[contentId][account].remove(oldest); + } + // Add the new policy as the most recent, following LIFO precedence $._acl[contentId][account].add(policy); } - /// @notice Removes a policy for a specific account and content ID. - /// @dev This function removes a policy from the ACL storage, revoking access to the specified account for the given content ID. - /// @param account The address of the account for which access is being revoked. - /// @param contentId The ID of the content for which access is being revoked. - /// @param policy The address of the policy to be removed. - function _removePolicy( - address account, - uint256 contentId, - address policy - ) internal returns (bool) { - ACLStorage storage $ = _getACLStorage(); - return $._acl[contentId][account].remove(policy); - } - /// @notice Verifies whether access is allowed for a specific account and content based on a given license. /// @param account The address of the account to verify access for. /// @param contentId The ID of the content for which access is being checked. @@ -125,6 +118,10 @@ abstract contract RightsManagerContentAccessUpgradeable is return $._acl[contentId][account].values(); } + // TODO potential improvement getChainedPolicies + // allowing concatenate policies to evaluate compliance... + // This approach supports complex access control scenarios where multiple factors need to be considered. + /// @inheritdoc IRightsAccessController /// @notice Retrieves the first active policy for a specific user and content in LIFO order. /// @param account The address of the account to evaluate. diff --git a/contracts/interfaces/IRepository.sol b/contracts/interfaces/IRepository.sol index a08372d..726ab7c 100644 --- a/contracts/interfaces/IRepository.sol +++ b/contracts/interfaces/IRepository.sol @@ -8,11 +8,9 @@ import "contracts/libraries/Types.sol"; * @notice This interface defines the methods for a repository to manage and query contract addresses. */ interface IRepository { - /** - * @notice Returns the address of the contract registered under the given key. - * @param key The key associated with the contract address. - * @return The address of the registered contract. - * @dev Reverts if the contract is not registered. - */ + /// @notice Returns the address of the contract registered under the given key. + /// @param key The key associated with the contract address. + /// @return The address of the registered contract. + /// @dev Reverts if the contract is not registered. function getContract(T.ContractTypes key) external view returns (address); } diff --git a/contracts/interfaces/IRightsAccessController.sol b/contracts/interfaces/IRightsAccessController.sol index 538fc59..666b38f 100644 --- a/contracts/interfaces/IRightsAccessController.sol +++ b/contracts/interfaces/IRightsAccessController.sol @@ -3,25 +3,6 @@ pragma solidity ^0.8.24; import "contracts/libraries/Types.sol"; interface IRightsAccessController { - /// @notice Registers and enforces access for a specific account to a content ID based on the conditions set by a policy. - /// @param account The address of the account to be granted access to the content. - /// @param contentId The unique identifier of the content for which access is being registered. - /// @param policy The address of the policy contract responsible for validating and enforcing the access conditions. - /// @dev Access is granted only if the specified policy contract is valid and has the necessary delegation rights. - /// If the policy conditions are not met, access will not be registered, and the operation will be rejected. - function registerPolicy( - uint256 contentId, - address policy, - address account - ) external payable; - - /// @notice Removes a specific policy associated with a given content ID. - /// @dev This function allows the removal of a policy from the list of policies linked to a specific content ID. - /// @param contentId The ID of the content from which the policy is to be removed. - /// @param policy The address of the policy that needs to be removed. - /// @return True if the policy was removed succesfully, false otherwise. - function removePolicy(uint256 contentId, address policy) external; - /// @notice Retrieves the first active policy for a specific user and content in LIFO order. /// @param account The address of the account to evaluate. /// @param contentId The content ID to evaluate policies for. diff --git a/contracts/interfaces/IRightsAccessControllerRegistrar.sol b/contracts/interfaces/IRightsAccessControllerRegistrar.sol new file mode 100644 index 0000000..90814a2 --- /dev/null +++ b/contracts/interfaces/IRightsAccessControllerRegistrar.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; +import "contracts/libraries/Types.sol"; + +interface IRightsAccessControllerRegistrar { + /// @notice Registers and enforces access for a specific account to a content ID based on the conditions set by a policy. + /// @param account The address of the account to be granted access to the content. + /// @param contentId The unique identifier of the content for which access is being registered. + /// @param policy The address of the policy contract responsible for validating and enforcing the access conditions. + /// @dev Access is granted only if the specified policy contract is valid and has the necessary delegation rights. + /// If the policy conditions are not met, access will not be registered, and the operation will be rejected. + function registerPolicy( + uint256 contentId, + address policy, + address account + ) external payable; +} diff --git a/contracts/interfaces/IRightsCustodial.sol b/contracts/interfaces/IRightsCustodial.sol index 03d779d..b874132 100644 --- a/contracts/interfaces/IRightsCustodial.sol +++ b/contracts/interfaces/IRightsCustodial.sol @@ -2,16 +2,7 @@ pragma solidity ^0.8.24; interface IRightsCustodial { - /// @notice Assigns distribution rights over the content. - /// @dev The distributor must be active. - /// @param contentId The ID of the content to assign. - /// @param distributor The address of the distributor to assign the content to. - function grantCustody( - uint256 contentId, - address distributor - ) external; - - /// @notice Retrieves the custodial address for the given content ID and ensures it is active. + /// @notice Retrieves the custodial address for the given content ID and ensures it is active. /// @param contentId The ID of the content. /// @return The address of the active custodial. function getCustody(uint256 contentId) external view returns (address); diff --git a/contracts/interfaces/IRightsCustodialGranter.sol b/contracts/interfaces/IRightsCustodialGranter.sol new file mode 100644 index 0000000..8267963 --- /dev/null +++ b/contracts/interfaces/IRightsCustodialGranter.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +interface IRightsCustodialManager { + /// @notice Assigns distribution rights over the content. + /// @dev The distributor must be active. + /// @param contentId The ID of the content to assign. + /// @param distributor The address of the distributor to assign the content to. + function grantCustody(uint256 contentId, address distributor) external; + +} diff --git a/contracts/interfaces/IRightsDelegable.sol b/contracts/interfaces/IRightsDelegable.sol index 85d7ea6..23e78f4 100644 --- a/contracts/interfaces/IRightsDelegable.sol +++ b/contracts/interfaces/IRightsDelegable.sol @@ -3,16 +3,6 @@ pragma solidity ^0.8.24; import "contracts/libraries/Types.sol"; interface IRightsDelegable { - /// @notice Delegates rights for a specific content ID to a grantee. - /// @param grantee The address of the account or contract to delegate rights to. - /// @param contentId The content ID for which rights are being delegated. - function delegateRights(address grantee, uint256 contentId) external; - - /// @notice Revokes the delegation of rights for a grantee. - /// @param grantee The address of the account or contract to revoke rights to. - /// @param contentId The content ID for which rights are being revoked. - function revokeRights(address grantee, uint256 contentId) external; - /// @notice Retrieves all content IDs for which rights have been delegated to a grantee. /// @param grantee The address of the account or contract whose delegated rights are being queried. /// @return An array of content IDs that have been delegated to the specified grantee. diff --git a/contracts/interfaces/IRightsDelegableDelegator.sol b/contracts/interfaces/IRightsDelegableDelegator.sol new file mode 100644 index 0000000..c14b19f --- /dev/null +++ b/contracts/interfaces/IRightsDelegableDelegator.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; +import "contracts/libraries/Types.sol"; + +interface IRightsDelegableDelegator { + + /// @notice Delegates rights for a specific content ID to a grantee. + /// @param grantee The address of the account or contract to delegate rights to. + /// @param contentId The content ID for which rights are being delegated. + function delegateRights(address grantee, uint256 contentId) external; + + /// @notice Revokes the delegation of rights for a grantee. + /// @param grantee The address of the account or contract to revoke rights to. + /// @param contentId The content ID for which rights are being revoked. + function revokeRights(address grantee, uint256 contentId) external; + +} diff --git a/contracts/interfaces/IRightsDelegableRevoker.sol b/contracts/interfaces/IRightsDelegableRevoker.sol new file mode 100644 index 0000000..12722de --- /dev/null +++ b/contracts/interfaces/IRightsDelegableRevoker.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; +import "contracts/libraries/Types.sol"; + +interface IRightsDelegableRevoker { + + /// @notice Revokes the delegation of rights for a grantee. + /// @param grantee The address of the account or contract to revoke rights to. + /// @param contentId The content ID for which rights are being revoked. + function revokeRights(address grantee, uint256 contentId) external; + +} diff --git a/contracts/interfaces/IRightsManager.sol b/contracts/interfaces/IRightsManager.sol index 2e4252c..f297467 100644 --- a/contracts/interfaces/IRightsManager.sol +++ b/contracts/interfaces/IRightsManager.sol @@ -8,7 +8,11 @@ import "./IFeesManager.sol"; import "./IDisburser.sol"; import "./IRightsCustodial.sol"; import "./IRightsDelegable.sol"; +import "./IRightsCustodialGranter.sol"; +import "./IRightsDelegableDelegator.sol"; +import "./IRightsDelegableRevoker.sol"; import "./IRightsAccessController.sol"; +import "./IRightsAccessControllerRegistrar.sol"; import "./IContentVault.sol"; interface IRightsManager is @@ -19,10 +23,16 @@ interface IRightsManager is IFundsManager, IRightsCustodial, IRightsDelegable, - IRightsAccessController + IRightsAccessController, + IRightsCustodialGranter, + IRightsDelegableRevoker, + IRightsDelegableDelegator, + IRightsAccessControllerRegistrar { /// @notice Checks if the content is eligible for distribution. /// @param contentId The ID of the content. /// @return True if the content can be distributed, false otherwise. - function isEligibleForDistribution(uint256 contentId) external returns (bool); + function isEligibleForDistribution( + uint256 contentId + ) external returns (bool); }