aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md3
-rw-r--r--modules/permissions.py72
2 files changed, 74 insertions, 1 deletions
diff --git a/README.md b/README.md
index 2f108e99..eb0338aa 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,9 @@
Python3 event-driven modular IRC bot!
## Dependencies
-* [BeautifulSoup4](https://pypi.python.org/pypi/beautifulsoup4/4.3.2)
+* [BeautifulSoup4](https://pypi.python.org/pypi/beautifulsoup4)
* [twitter](https://pypi.python.org/pypi/twitter)
+* [scrypt](https://pypi.python.org/pypi/scrypt)
## Configurating
To get BitBot off the ground, there's some API-keys and the like in bot.json.example. move it to bot.json, fill in the API keys you want (and remove the modules that rely on those configs.)
diff --git a/modules/permissions.py b/modules/permissions.py
new file mode 100644
index 00000000..86757c84
--- /dev/null
+++ b/modules/permissions.py
@@ -0,0 +1,72 @@
+import base64, os
+import scrypt
+
+class Module(object):
+ def __init__(self, bot):
+ self.bot = bot
+ bot.events.on("new").on("user").hook(self.new_user)
+ bot.events.on("received").on("part").hook(self.on_part)
+ bot.events.on("received").on("command").on("identify"
+ ).hook(self.identify, private_only=True, min_args=1)
+ bot.events.on("received").on("command").on("register"
+ ).hook(self.register, private_only=True, min_args=1)
+ bot.events.on("received").on("command").on("logout"
+ ).hook(self.logout, private_only=True)
+
+ def new_user(self, event):
+ self._logout(event["user"])
+
+ def on_part(self, event):
+ if len(event["user"].channels) == 0 and event["user"].identified:
+ event["user"].send_notice("You no longer share any channels "
+ "with me so you have been signed out")
+
+ def _get_hash(self, user):
+ hash, salt = user.get_setting("authentication", (None, None))
+ return hash, salt
+ def _make_salt(self):
+ return base64.b64encode(os.urandom(64)).decode("utf8")
+ def _make_hash(self, password, salt=None):
+ salt = salt or self._make_salt()
+ hash = base64.b64encode(scrypt.hash(password, salt)).decode("utf8")
+ return hash, salt
+ def _identified(self, user):
+ user.identified = True
+ user.permissions = user.get_setting("permissions", [])
+ def _logout(self, user):
+ user.identified = False
+ user.permissions = []
+ def identify(self, event):
+ if not event["user"].identified:
+ password = event["args_split"][0]
+ hash, salt = self._get_hash(event["user"])
+ if hash and salt:
+ attempt, _ = self._make_hash(password, salt)
+ if attempt == hash:
+ self._identified(event["user"])
+ event["stdout"].write("Correct password, you have "
+ "been identified.")
+ else:
+ event["stderr"].write("Incorrect password")
+ else:
+ event["stderr"].write("This nickname is not registered")
+ else:
+ event["stderr"].write("You are already identified")
+
+ def register(self, event):
+ hash, salt = self._get_hash(event["user"])
+ if not hash and not salt:
+ password = event["args_split"][0]
+ hash, salt = self._make_hash(password)
+ event["user"].set_setting("authentication", [hash, salt])
+ self._identified(event["user"])
+ event["stdout"].write("Nickname registered successfully")
+ else:
+ event["stderr"].write("This nickname is already registered")
+
+ def logout(self, event):
+ if event["user"].identified:
+ self._logout(event["user"])
+ event["stdout"].write("You have been logged out")
+ else:
+ event["stderr"].write("You are not logged in")