check method

DVSceneAssetRefusal? check(
  1. DVSceneAsset asset, {
  2. required String tenant,
})

The refusal for asset under tenant, or null when it may be fetched.

Implementation

DVSceneAssetRefusal? check(DVSceneAsset asset, {required String tenant}) {
  final String ref = asset.reference;
  if (ref.isEmpty || ref.contains('\\') || ref.codeUnits.any((int c) => c < 0x20)) {
    return const DVSceneAssetRefusal(
        'the reference is empty or contains a backslash or control character');
  }
  final int? ceiling = maxBytes;
  if (ceiling != null && asset.byteLength != null && asset.byteLength! > ceiling) {
    return DVSceneAssetRefusal(
        'the asset declares ${asset.byteLength} bytes, over the $ceiling-byte ceiling');
  }
  switch (asset.source) {
    case DVSceneAssetSource.bundled:
      if (ref.contains(':') || ref.startsWith('/') || _climbs(ref)) {
        return DVSceneAssetRefusal(
            "'$ref' is not a relative bundle key");
      }
      return null;
    case DVSceneAssetSource.stored:
      if (ref.startsWith('/') || _climbs(ref)) {
        return DVSceneAssetRefusal("'$ref' climbs out of its storage prefix");
      }
      if (requireDigest && asset.sha256 == null) {
        return DVSceneAssetRefusal(
            "the stored asset '$ref' has no sha256, so its bytes cannot be verified");
      }
      if (ref.startsWith(tenantPrefix)) {
        final String owner = ref.substring(tenantPrefix.length).split('/').first;
        if (owner != tenant) {
          return DVSceneAssetRefusal(
              "'$ref' belongs to tenant '$owner', not to the current tenant '$tenant'");
        }
        return null;
      }
      if (sharedStoragePrefixes.any(ref.startsWith)) return null;
      return DVSceneAssetRefusal(
          "'$ref' is outside $tenantPrefix$tenant/ and no shared prefix covers it");
    case DVSceneAssetSource.network:
      final Uri? uri = Uri.tryParse(ref);
      if (uri == null || uri.scheme != 'https' || uri.host.isEmpty) {
        return DVSceneAssetRefusal("'$ref' is not an https URL");
      }
      if (uri.userInfo.isNotEmpty) {
        return DVSceneAssetRefusal("'$ref' carries credentials in the URL");
      }
      final String host = uri.host.toLowerCase();
      if (!allowedHosts.any((String h) => h.toLowerCase() == host)) {
        return DVSceneAssetRefusal(
            "the host '$host' is not in the scene asset policy's allowed hosts");
      }
      if (requireDigest && asset.sha256 == null) {
        return DVSceneAssetRefusal(
            "the network asset '$ref' has no sha256, so its bytes cannot be verified");
      }
      return null;
  }
}