From 050e6ba53387c304066d4da397b81edb3b462ba0 Mon Sep 17 00:00:00 2001
From: Adrian Cybulski <adrian@cybulski.cc>
Date: Wed, 10 Feb 2021 23:41:08 +0000
Subject: [PATCH] Query object's ACL

- Object's ACL Query
- Include object's ACL in stat
---
 lib/src/minio.dart        | 21 +++++++++++++++++++++
 lib/src/minio_models.dart |  4 ++++
 test/minio_dart_test.dart | 30 ++++++++++++++++++++++++++++++
 3 files changed, 55 insertions(+)

diff --git a/lib/src/minio.dart b/lib/src/minio.dart
index 670ddb1..a329c0a 100644
--- a/lib/src/minio.dart
+++ b/lib/src/minio.dart
@@ -11,6 +11,10 @@ import 'package:minio/src/minio_uploader.dart';
 import 'package:minio/src/utils.dart';
 import 'package:xml/xml.dart' as xml;
 
+import '../models.dart';
+import '../models.dart';
+import 'minio_helpers.dart';
+
 class Minio {
   /// Initializes a new client object.
   Minio({
@@ -981,6 +985,22 @@ class Minio {
     validate(resp, expect: 204);
   }
 
+  Future<AccessControlPolicy> getObjectACL(String bucket, String object) async {
+    MinioInvalidBucketNameError.check(bucket);
+    MinioInvalidObjectNameError.check(object);
+
+    final resp = await _client.request(
+      method: 'GET',
+      bucket: bucket,
+      object: object,
+      queries: {"acl": ""},
+    );
+
+    return AccessControlPolicy.fromXml(
+      xml.XmlDocument.parse(resp.body).firstChild,
+    );
+  }
+
   /// Stat information of the object.
   Future<StatObjectResult> statObject(String bucket, String object) async {
     MinioInvalidBucketNameError.check(bucket);
@@ -1004,6 +1024,7 @@ class Minio {
       size: int.parse(resp.headers['content-length']),
       metaData: extractMetadata(resp.headers),
       lastModified: parseRfc7231Time(resp.headers['last-modified']),
+      acl: await getObjectACL(bucket, object),
     );
   }
 }
diff --git a/lib/src/minio_models.dart b/lib/src/minio_models.dart
index d8e04fe..661bc47 100644
--- a/lib/src/minio_models.dart
+++ b/lib/src/minio_models.dart
@@ -2,6 +2,8 @@ import 'package:minio/models.dart';
 import 'package:minio/src/minio_errors.dart';
 import 'package:xml/xml.dart';
 
+import '../models.dart';
+
 class ListObjectsChunk {
   List<Object> objects;
   List<String> prefixes;
@@ -106,12 +108,14 @@ class StatObjectResult {
     this.etag,
     this.lastModified,
     this.metaData,
+    this.acl,
   });
 
   final int size;
   final String etag;
   final DateTime lastModified;
   final Map<String, String> metaData;
+  final AccessControlPolicy acl;
 }
 
 /// Build PostPolicy object that can be signed by presignedPostPolicy
diff --git a/test/minio_dart_test.dart b/test/minio_dart_test.dart
index cec0784..f75acc7 100644
--- a/test/minio_dart_test.dart
+++ b/test/minio_dart_test.dart
@@ -96,6 +96,36 @@ void main() {
     });
   });
 
+  group(
+    'getObjectACL',
+    () {
+      final bucketName = DateTime.now().millisecondsSinceEpoch.toString();
+      Directory tempDir;
+      File testFile;
+      final objectName = 'a.jpg';
+
+      setUpAll(() async {
+        tempDir = await Directory.systemTemp.createTemp();
+        testFile = await File('${tempDir.path}/$objectName').create();
+        await testFile.writeAsString('random bytes');
+
+        final minio = _getClient();
+        await minio.makeBucket(bucketName);
+
+        await minio.fPutObject(bucketName, objectName, testFile.path);
+      });
+
+      tearDownAll(() async {
+        await tempDir.delete(recursive: true);
+      });
+
+      test('getObjectACL() fetch objects acl', () async {
+        final minio = _getClient();
+        var acl = await minio.getObjectACL(bucketName, objectName);
+      });
+    },
+  );
+
   group('fPutObject', () {
     final bucketName = DateTime.now().millisecondsSinceEpoch.toString();
     Directory tempDir;
-- 
GitLab