From 11103c683de40b27a15228cfee04206a9ac892f1 Mon Sep 17 00:00:00 2001
From: Atticus <atticus@macbook36gb.local>
Date: Wed, 19 Jun 2024 08:44:19 -0600
Subject: [PATCH] fix(controllers): fix has permission to validate setting a
 controller with empty controller array

---
 src/common/utils.lua     |  7 +++----
 test/controllers.test.js | 11 +++++++++++
 tools/spawn-aos-ant.js   | 23 ++++++++++++++---------
 3 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/src/common/utils.lua b/src/common/utils.lua
index 0d93459..45a2548 100644
--- a/src/common/utils.lua
+++ b/src/common/utils.lua
@@ -221,14 +221,13 @@ function utils.validateOwner(caller)
 end
 
 function utils.assertHasPermission(from)
-	local isController = false
 	for _, c in ipairs(Controllers) do
 		if c == from then
-			isController = true
-			break
+			-- if is controller, return true
+			return
 		end
 	end
-	local hasPermission = isController == true or Balances[from] or Owner == from or ao.env.Process.Id == from
+	local hasPermission = Balances[from] == 1 or Owner == from or ao.env.Process.Id == from
 	assert(hasPermission == true, "Only controllers and owners can set controllers and records.")
 end
 
diff --git a/test/controllers.test.js b/test/controllers.test.js
index 5218324..5fbe5ba 100644
--- a/test/controllers.test.js
+++ b/test/controllers.test.js
@@ -53,5 +53,16 @@ describe('AOS-ANT Controllers', async () => {
     });
 
     assert(result.Messages[0].Data === 'Controller removed');
+
+    const addControllerResult = await handle(
+      {
+        Tags: [
+          { name: 'Action', value: 'Set-Controller' },
+          { name: 'Controller', value: STUB_ADDRESS },
+        ],
+      },
+      result.Memory,
+    );
+    assert.equal(addControllerResult.Messages[0].Data, 'Controller added');
   });
 });
diff --git a/tools/spawn-aos-ant.js b/tools/spawn-aos-ant.js
index 2f79873..dc9a7c3 100644
--- a/tools/spawn-aos-ant.js
+++ b/tools/spawn-aos-ant.js
@@ -88,16 +88,21 @@ async function main() {
     const tags = args
       ? Object.entries(args).map(([key, value]) => ({ name: key, value }))
       : [];
-    const result = await ao.dryrun({
-      process: processId,
-      tags: [...tags, { name: 'Action', value: method }],
-      data,
-      signer,
-      Owner: address,
-      From: address,
-    });
+    const result = await ao
+      .message({
+        process: processId,
+        tags: [...tags, { name: 'Action', value: method }],
+        data,
+        signer,
+        Owner: address,
+        From: address,
+      })
+      .catch((e) => e);
 
-    console.dir({ method, result }, { depth: null });
+    console.dir(
+      { method, result: result.message, type: typeof result },
+      { depth: null },
+    );
   }
 }