From c212b1aa6d907c53773e72b4310fa38444083689 Mon Sep 17 00:00:00 2001
From: Will Hunt <half-shot@molrams.com>
Date: Thu, 23 Feb 2017 09:47:19 +0000
Subject: [PATCH] Add adminme tool, for giving users powers on bridge rooms.
 Tools are now written in typescript

---
 package.json     |   5 ++-
 tools/addbot.js  |  18 --------
 tools/addbot.ts  |  25 +++++++++++
 tools/adminme.ts | 114 +++++++++++++++++++++++++++++++++++++++++++++++
 tsconfig.json    |   3 +-
 5 files changed, 145 insertions(+), 20 deletions(-)
 delete mode 100644 tools/addbot.js
 create mode 100644 tools/addbot.ts
 create mode 100644 tools/adminme.ts

diff --git a/package.json b/package.json
index 5b7c30c..59e7cfa 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,8 @@
     "coverage": "istanbul --include-all-sources cover -x build/src/discordas.js _mocha -- build/test/ -R spec",
     "build": "tsc",
     "start": "npm run-script build && node ./build/src/discordas.js -p 9005 -c config.yaml",
-    "getbotlink": "node ./tools/addbot.js"
+    "getbotlink": "node ./build/tools/addbot.js",
+    "adminme": "node ./build/tools/adminme.js"
   },
   "repository": {
     "type": "git",
@@ -33,6 +34,8 @@
     "@types/node": "^7.0.5",
     "@types/sqlite3": "^2.2.32",
     "bluebird": "^3.4.7",
+    "command-line-args": "^4.0.1",
+    "command-line-usage": "^4.0.0",
     "discord.js": "^11.0.0",
     "js-yaml": "^3.8.1",
     "marked": "^0.3.6",
diff --git a/tools/addbot.js b/tools/addbot.js
deleted file mode 100644
index 86d55da..0000000
--- a/tools/addbot.js
+++ /dev/null
@@ -1,18 +0,0 @@
-const yaml = require("js-yaml");
-const fs = require("fs");
-const flags = require("../node_modules/discord.js/src/util/Constants.js").PermissionFlags;
-const yamlConfig = yaml.safeLoad(fs.readFileSync("config.yaml", "utf8"));
-if (yamlConfig === null) {
-  console.error("You have an error in your discord config.");
-}
-const client_id = yamlConfig.auth.clientID;
-const perms = flags.READ_MESSAGES |
-  flags.SEND_MESSAGES |
-  flags.CHANGE_NICKNAME |
-  flags.CONNECT |
-  flags.SPEAK |
-  flags.EMBED_LINKS |
-  flags.ATTACH_FILES |
-  flags.READ_MESSAGE_HISTORY;
-
-console.log(`Go to https://discordapp.com/api/oauth2/authorize?client_id=${client_id}&scope=bot&permissions=${perms} to invite the bot into a guild.`);
diff --git a/tools/addbot.ts b/tools/addbot.ts
new file mode 100644
index 0000000..f54d66b
--- /dev/null
+++ b/tools/addbot.ts
@@ -0,0 +1,25 @@
+ /* tslint:disable:no-bitwise no-console no-var-requires */
+/**
+ * Generates a URL you can use to authorize a bot with a guild.
+ */
+import * as yaml from "js-yaml";
+import * as fs from "fs";
+
+const flags = require("../../node_modules/discord.js/src/util/Constants.js").PermissionFlags;
+const yamlConfig = yaml.safeLoad(fs.readFileSync("config.yaml", "utf8"));
+if (yamlConfig === null) {
+  console.error("You have an error in your discord config.");
+}
+const clientId = yamlConfig.auth.clientID;
+
+const perms = flags.READ_MESSAGES |
+  flags.SEND_MESSAGES |
+  flags.CHANGE_NICKNAME |
+  flags.CONNECT |
+  flags.SPEAK |
+  flags.EMBED_LINKS |
+  flags.ATTACH_FILES |
+  flags.READ_MESSAGE_HISTORY;
+
+const url = `https://discordapp.com/api/oauth2/authorize?client_id=${clientId}&scope=bot&permissions=${perms}`;
+console.log(`Go to ${url} to invite the bot into a guild.`);
diff --git a/tools/adminme.ts b/tools/adminme.ts
new file mode 100644
index 0000000..60a6211
--- /dev/null
+++ b/tools/adminme.ts
@@ -0,0 +1,114 @@
+/* tslint:disable:no-console */
+/**
+ * Allows you to become an admin for a room the bot is in control of.
+ */
+
+import { Cli, Bridge, AppServiceRegistration, ClientFactory } from "matrix-appservice-bridge";
+import * as log from "npmlog";
+import * as yaml from "js-yaml";
+import * as fs from "fs";
+import * as args from "command-line-args";
+import * as usage from "command-line-usage";
+import { DiscordBridgeConfig } from "../src/config";
+
+const optionDefinitions = [
+  {
+    name: "help",
+    alias: "h",
+    type: Boolean,
+    description: "Display this usage guide."},
+  {
+    name: "config",
+    alias: "c",
+    type: String,
+    defaultValue: "config.yaml",
+    description: "The AS config file.",
+    typeLabel: "<config.yaml>" },
+  {
+    name: "roomid",
+    alias: "r",
+    type: String,
+    description: "The roomid to modify"},
+  {
+    name: "userid",
+    alias: "u",
+    type: String,
+    description: "The userid to give powers"},
+  {
+    name: "power",
+    alias: "p",
+    type: Number,
+    defaultValue: 100,
+    description: "The power to set",
+    typeLabel: "<0-100>" },
+];
+
+const options = args(optionDefinitions);
+
+if (options.help) {
+  /* tslint:disable:no-console */
+  console.log(usage([
+    {
+      header: "Admin Me",
+      content: "A tool to give a user a power level in a bot user controlled room."},
+    {
+      header: "Options",
+      optionList: optionDefinitions,
+    },
+  ]));
+  process.exit(0);
+}
+
+if (!options.roomid) {
+  console.error("Missing roomid parameter. Check -h");
+  process.exit(1);
+}
+
+if (!options.userid) {
+  console.error("Missing userid parameter. Check -h");
+  process.exit(1);
+}
+
+const yamlConfig = yaml.safeLoad(fs.readFileSync("discord-registration.yaml", "utf8"));
+const registration = AppServiceRegistration.fromObject(yamlConfig);
+const config: DiscordBridgeConfig = yaml.safeLoad(fs.readFileSync(options.config, "utf8")) as DiscordBridgeConfig;
+
+if (registration === null) {
+ throw new Error("Failed to parse registration file");
+}
+
+const clientFactory = new ClientFactory({
+ appServiceUserId: "@" + registration.sender_localpart + ":" + config.bridge.domain,
+ token: registration.as_token,
+ url: config.bridge.homeserverUrl,
+});
+
+const client = clientFactory.getClientAs();
+client.startClient();
+client.on("sync", (state, prevState, data) => {
+  switch (state) {
+    case "ERROR":
+      console.error("Sync failed.", data);
+      break;
+    case "SYNCING":
+      console.log("Syncing.");
+      break;
+    case "PREPARED":
+      const room = client.getRoom(options.roomid);
+      if (room === null) {
+        console.error("Room not found.");
+        process.exit(1);
+      }
+      const levels = room.getLiveTimeline().getState("f").getStateEvents("m.room.power_levels")[0];
+      client.setPowerLevel(options.roomid, options.userid, options.power, levels).then(() => {
+        console.log("Power levels set");
+        process.exit(0);
+      }).catch((err) => {
+        console.error("Could not apply power levels: ", err);
+        process.exit(1);
+      })
+      break;
+    default:
+      break;
+  }
+});
diff --git a/tsconfig.json b/tsconfig.json
index c5651a0..a888421 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -11,6 +11,7 @@
     "compileOnSave": true,
     "include": [
         "src/**/*",
-        "test/**/*"
+        "test/**/*",
+        "tools/**/*"
     ]
 }
-- 
GitLab