diff --git a/loginsecurity.py b/loginsecurity.py new file mode 100644 index 0000000..6822ad9 --- /dev/null +++ b/loginsecurity.py @@ -0,0 +1,121 @@ +from helpers import * +from basecommands import simplecommand +import bcrypt +from time import time as now +import thread + + +wait_time = 60 #seconds +admin_perm = "utils.loginsecurity.admin" +min_pass_length = 6 + +run_kick_thread = True +blocked_events = ["block.BlockBreakEvent", "block.BlockPlaceEvent", "player.PlayerMoveEvent"] +passwords = open_json_file("loginpasswords", {}) + +#if passwords == None: (set default value to None ^^) +# Keep everyone from playing? (Insecure) + +withholdings = {} #pname : jointime + + +def save_passwords(): + save_json_file("loginpasswords", passwords) + + +def matches(password, user): + hashed = passwords.get(uid(user)) + return bcrypt.hashpw(password, hashed) == hashed + + +@simplecommand("login", + usage = "", + description = "Logs you in if matches your password.", + senderLimit = 0, + helpNoargs = True) +def login_command(sender, command, label, args): + password = " ".join(args) + if matches(password, sender): + del withholdings[sender.getName()] + return "&aLogged in successfully!" + return "&cInvalid password" + + +@simplecommand("register", + usage = "", + description = "Registers you with . Next time you join, log in with /login", + senderLimit = 0, + helpNoArgs = True) +def register_command(sender, command, label, args): + uuid = uid(sender) + if uuid in passwords: + return "&cYou are already registered!" + password = " ".join(args) + if len(password) < min_pass_length: + return "&cThe password has to be made up of at least 8 characters!" + hashed = bcrypt.hashpw(password, bcrypt.gensalt(16)) + passwords[uuid] = hashed + return "&cPassword set. Use /login upon join." + + +@simplecommand("rmpass", + usage = "", + description = "Removes your password if the password matches", + senderLimit = 0, + helpNoArgs = True) +def rmpass_command(sender, command, label, args): + password = " ".join(args) + if matches(password, sender): + del passwords[uuid(sender)] + return "&aPassword removed successfully. You will not be prompted anymore." + return "&cInvalid password" + + +@simplecommand("rmotherpass", + aliases = ["lacrmpass"], + usage = "", + description = "Removes password of and sends them a notification", + helpNoArgs = True) +def rmotherpass_command(sender, command, label, args): + user = server.getOfflinePlayer(args[0]) + if user: + del passwords[uid(user)] + runas(server.getConsoleSender(), colorify("mail send %s &cYour password was reset by a staff member. Use &o/register&c to set a new one.")) + return "&sPassword of %s reset successfully" % user.getName() + return "&cThat player could not be found" + + +@hook.event("player.PlayerJoinEvent", "highest") +def on_join(event): + user = event.getPlayer() + if get_id(user) in passwords: + withholdings[user.getName()] = now() + + +@hook.event("player.PlayerQuitEvent", "normal") +def on_quit(event): + del withholdings[event.getPlayer().getName()] + + +def kick_thread(): + wait_time_millis = wait_time * 1000 + while True: + if not run_kick_thread: + info("Exiting LoginSecurity kicking thread!") + thread.exit() + time.sleep(1) + moment = now() + for name, jointime in withholdings.iteritems(): + if moment - jointime > wait_time_millis: + server.getPlayer(name).kickPlayer(colorify("&cLogin timed out")) + + +thread.start_new_thread(kick_thread, ()) + +for blocked_event in blocked_events: + @hook.event(blocked_event, "low") + def on_blocked_event(event): + user = event.getPlayer() + if user.getName() in withholdings: + event.setCancelled(True) + msg(user, "&cYou have to log in first! Use /login ") diff --git a/main.py b/main.py index 7101f69..cfda6aa 100644 --- a/main.py +++ b/main.py @@ -73,7 +73,9 @@ shared["load_modules"] = [ #adds snowbrawl minigame #"snowbrawl", # Adds /tm [player] for a messages to be sent to this player via /msg - "pmtoggle" + "pmtoggle", + # Replacement for LoginSecurity + "loginsecurity" # NOTICE: If you add something here, please add a small descriptive comment above! ] shared["modules"] = {}