From e506249bd365e6ec44a95e7c99a6fb2666c753e3 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Fri, 10 Mar 2017 10:34:27 +0100 Subject: [PATCH] Added password change command --- basicbot.py | 20 ++++++++++++++++++++ database.py | 40 +++++++++++++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/basicbot.py b/basicbot.py index 49eb5a2b..887c1625 100644 --- a/basicbot.py +++ b/basicbot.py @@ -132,10 +132,30 @@ Sintassi: `/sync `""" await update.message.chat.send_message(bot, "⚠ Username o password non validi.") +async def changepassword(bot, update, arguments): + """Cambia la tua password del Database Royal Games. + +Sintassi: `/changepassword `""" + if len(arguments) != 3: + await update.message.chat.send_message(bot, "⚠ Sintassi del comando non valida.\n`/sync `") + return + # TODO: this can be improved + # Try to login + _, logged_user = database.login(arguments[0], arguments[1]) + # Check if the login is successful + if logged_user is not None: + # Change the password + database.change_password(logged_user.username, arguments[2]) + await update.message.chat.send_message(bot, f"Il cambio password è riuscito!\n\n_Info per smanettoni: la tua password è hashata nel database come_ `{logged_user.password}`.") + else: + await update.message.chat.send_message(bot, "⚠ Username o password non validi.") + + if __name__ == "__main__": b.commands["leggi"] = leggi b.commands["diario"] = diario b.commands["discord"] = discord b.commands["sync"] = sync + b.commands["changepassword"] = changepassword b.commands["help"] = help b.run() \ No newline at end of file diff --git a/database.py b/database.py index e0cf0e79..d5d60c9b 100644 --- a/database.py +++ b/database.py @@ -3,6 +3,14 @@ from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base import bcrypt +class NoUsersMatchingError(Exception): + pass + + +class InvalidPasswordError(Exception): + pass + + # Initialize the database engine = create_engine("sqlite:///db.sqlite") Base = declarative_base() @@ -35,7 +43,24 @@ def create_user(username, password, royal=False): # Commit the changes session.commit() -def login(username, password): + +# TODO: check for vulnerabilities +def change_password(username, newpassword): + # Create a new session + session = Session() + # Hash the new password using bcrypt + hashed_password = bcrypt.hashpw(newpassword.encode("utf8"), bcrypt.gensalt()) + # Find the user entry + users = session.query(User).filter_by(username=username).all() + if len(users) == 0: + raise NoUsersMatchingError("No users with the specified username found.") + db_user = users[0] + # Change the password and commit + db_user.password = hashed_password + session.commit() + + +def login(username, password, enable_exceptions=False): """Try to login using the database password. The session is always returned, while the user object is returned if the login is successful.""" # Create a new session session = Session() @@ -43,15 +68,20 @@ def login(username, password): users = session.query(User).filter(User.username == username).all() # No user with a matching username found if len(users) == 0: - return session, None - else: - db_user = users[0] + if enable_exceptions: + raise NoUsersMatchingError("No users with the specified username found.") + else: + return session, None + db_user = users[0] # Test the password and return the session and the user if successful if bcrypt.hashpw(password.encode("utf8"), db_user.password) == db_user.password: # TODO: Maybe there's a better way to do this? return session, db_user else: - return session, None + if enable_exceptions: + raise InvalidPasswordError("The specified password doesn't match the user's.") + else: + return session, None def init_royal_db():