Browse Source

Ensure SAS Tokens in Test Use Minimal Permissions (#46112)

* Ensure SAS Tokens in Test Use Minimal Permissions

There were some issues with the Azure implementation requiring
permissions to list all containers ue to a container exists
check. This was caught in CI this time, but going forward we
should ensure that CI is executed using a token that does not
allow listing containers.

Relates #43288
Armin Braun 6 years ago
parent
commit
6059f8e8da

+ 4 - 0
plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureBlobStore.java

@@ -68,6 +68,10 @@ public class AzureBlobStore implements BlobStore {
         return container;
     }
 
+    public AzureStorageService getService() {
+        return service;
+    }
+
     /**
      * Gets the configured {@link LocationMode} for the Azure storage requests.
      */

+ 37 - 0
plugins/repository-azure/src/test/java/org/elasticsearch/repositories/azure/AzureStorageCleanupThirdPartyTests.java

@@ -19,15 +19,25 @@
 
 package org.elasticsearch.repositories.azure;
 
+import com.microsoft.azure.storage.OperationContext;
+import com.microsoft.azure.storage.StorageException;
+import com.microsoft.azure.storage.blob.CloudBlobClient;
+import com.microsoft.azure.storage.blob.CloudBlobContainer;
+import org.elasticsearch.action.ActionRunnable;
+import org.elasticsearch.action.support.PlainActionFuture;
 import org.elasticsearch.action.support.master.AcknowledgedResponse;
 import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.collect.Tuple;
 import org.elasticsearch.common.settings.MockSecureSettings;
 import org.elasticsearch.common.settings.SecureSettings;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.repositories.AbstractThirdPartyRepositoryTestCase;
+import org.elasticsearch.repositories.blobstore.BlobStoreRepository;
 
+import java.net.HttpURLConnection;
 import java.util.Collection;
+import java.util.function.Supplier;
 
 import static org.hamcrest.Matchers.blankOrNullString;
 import static org.hamcrest.Matchers.equalTo;
@@ -71,5 +81,32 @@ public class AzureStorageCleanupThirdPartyTests extends AbstractThirdPartyReposi
                 .put("base_path", System.getProperty("test.azure.base"))
             ).get();
         assertThat(putRepositoryResponse.isAcknowledged(), equalTo(true));
+        if (Strings.hasText(System.getProperty("test.azure.sas_token"))) {
+            ensureSasTokenPermissions();
+        }
+    }
+
+    private void ensureSasTokenPermissions() {
+        final BlobStoreRepository repository = getRepository();
+        final PlainActionFuture<Void> future = PlainActionFuture.newFuture();
+        repository.threadPool().generic().execute(ActionRunnable.wrap(future, l -> {
+            final AzureBlobStore blobStore = (AzureBlobStore) repository.blobStore();
+            final String account = "default";
+            final Tuple<CloudBlobClient, Supplier<OperationContext>> client = blobStore.getService().client(account);
+            final CloudBlobContainer blobContainer = client.v1().getContainerReference(blobStore.toString());
+            try {
+                SocketAccess.doPrivilegedException(() -> blobContainer.exists(null, null, client.v2().get()));
+                future.onFailure(new RuntimeException(
+                    "The SAS token used in this test allowed for checking container existence. This test only supports tokens " +
+                        "that grant only the documented permission requirements for the Azure repository plugin."));
+            } catch (StorageException e) {
+                if (e.getHttpStatusCode() == HttpURLConnection.HTTP_UNAUTHORIZED) {
+                    future.onResponse(null);
+                } else {
+                    future.onFailure(e);
+                }
+            }
+        }));
+        future.actionGet();
     }
 }

+ 1 - 1
test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java

@@ -304,7 +304,7 @@ public abstract class AbstractThirdPartyRepositoryTestCase extends ESSingleNodeT
         return future.actionGet();
     }
 
-    private BlobStoreRepository getRepository() {
+    protected BlobStoreRepository getRepository() {
         return (BlobStoreRepository) getInstanceFromNode(RepositoriesService.class).repository("test-repo");
     }
 }