From e115b0678cce0f918e1985524751f95c21dd2b2d Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sun, 19 Jan 2020 19:48:41 +0000 Subject: [PATCH] Fix password issues caused by Flask-User migration --- app/blueprints/users/githublogin.py | 2 +- app/blueprints/users/profile.py | 9 +++--- app/models.py | 12 ++++++- app/templates/flask_user/login.html | 2 +- ...ublic_base.html => flask_user_layout.html} | 0 migrations/versions/a0f6c8743362_.py | 31 +++++++++++++++++++ utils/run_migrations.sh | 1 + 7 files changed, 50 insertions(+), 7 deletions(-) rename app/templates/{flask_user/public_base.html => flask_user_layout.html} (100%) create mode 100644 migrations/versions/a0f6c8743362_.py diff --git a/app/blueprints/users/githublogin.py b/app/blueprints/users/githublogin.py index 56c4412..a029361 100644 --- a/app/blueprints/users/githublogin.py +++ b/app/blueprints/users/githublogin.py @@ -65,7 +65,7 @@ def github_authorized(oauth_token): flash("Unable to find an account for that Github user", "error") return redirect(url_for("users.claim")) elif loginUser(userByGithub): - if current_user.password is None: + if not current_user.hasPassword(): return redirect(next_url or url_for("users.set_password", optional=True)) else: return redirect(next_url or url_for("homepage.home")) diff --git a/app/blueprints/users/profile.py b/app/blueprints/users/profile.py index 8e6bfe9..37ea992 100644 --- a/app/blueprints/users/profile.py +++ b/app/blueprints/users/profile.py @@ -170,7 +170,7 @@ class SetPasswordForm(FlaskForm): @bp.route("/user/set-password/", methods=["GET", "POST"]) @login_required def set_password(): - if current_user.password is not None: + if current_user.hasPassword(): return redirect(url_for("user.change_password")) form = SetPasswordForm(request.form) @@ -185,10 +185,11 @@ def set_password(): hashed_password = user_manager.hash_password(form.password.data) # Change password - user_manager.update_password(current_user, hashed_password) + current_user.password = hashed_password + db.session.commit() # Send 'password_changed' email - if user_manager.enable_email and user_manager.send_password_changed_email and current_user.email: + if user_manager.USER_ENABLE_EMAIL and current_user.email: emails.send_password_changed_email(current_user) # Send password_changed signal @@ -211,7 +212,7 @@ def set_password(): task = sendVerifyEmail.delay(newEmail, token) return redirect(url_for("tasks.check", id=task.id, r=url_for("users.profile", username=current_user.username))) else: - return redirect(url_for("users.profile", username=current_user.username)) + return redirect(url_for("user.login")) else: flash("Passwords do not match", "error") diff --git a/app/models.py b/app/models.py index 1ff2904..69eca7c 100644 --- a/app/models.py +++ b/app/models.py @@ -146,7 +146,7 @@ class User(db.Model, UserMixin): tokens = db.relationship("APIToken", backref="owner", lazy="dynamic") replies = db.relationship("ThreadReply", backref="author", lazy="dynamic") - def __init__(self, username, active=False, email=None, password=None): + def __init__(self, username, active=False, email=None, password=""): self.username = username self.email_confirmed_at = datetime.datetime.now() - datetime.timedelta(days=6000) self.display_name = username @@ -155,6 +155,9 @@ class User(db.Model, UserMixin): self.password = password self.rank = UserRank.NOT_JOINED + def hasPassword(self): + return self.password != "" + def canAccessTodoList(self): return Permission.APPROVE_NEW.check(self) or \ Permission.APPROVE_RELEASE.check(self) or \ @@ -203,6 +206,13 @@ class User(db.Model, UserMixin): return Thread.query.filter_by(author=self) \ .filter(Thread.created_at > hour_ago).count() < 2 + def __eq__(self, other): + if not self.is_authenticated or not other.is_authenticated: + return False + + assert self.id > 0 + return self.id == other.id + class UserEmailVerification(db.Model): id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey("user.id")) diff --git a/app/templates/flask_user/login.html b/app/templates/flask_user/login.html index a134388..3e93d38 100644 --- a/app/templates/flask_user/login.html +++ b/app/templates/flask_user/login.html @@ -15,7 +15,7 @@ Sign in {{ form.hidden_tag() }} {# Username or Email field #} - {% set field = form.username if user_manager.USER_ENABLE_REGISTER else form.email %} + {% set field = form.username if user_manager.USER_ENABLE_USERNAME else form.email %}
{# Label on left, "New here? Register." on right #} diff --git a/app/templates/flask_user/public_base.html b/app/templates/flask_user_layout.html similarity index 100% rename from app/templates/flask_user/public_base.html rename to app/templates/flask_user_layout.html diff --git a/migrations/versions/a0f6c8743362_.py b/migrations/versions/a0f6c8743362_.py new file mode 100644 index 0000000..2d23538 --- /dev/null +++ b/migrations/versions/a0f6c8743362_.py @@ -0,0 +1,31 @@ +"""empty message + +Revision ID: a0f6c8743362 +Revises: 64fee8e5ab34 +Create Date: 2020-01-19 19:12:39.402679 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = 'a0f6c8743362' +down_revision = '64fee8e5ab34' +branch_labels = None +depends_on = None + + +def upgrade(): + op.alter_column('user', 'password', + existing_type=sa.VARCHAR(length=255), + nullable=False, + existing_server_default=sa.text("''::character varying"), + server_default='') + + +def downgrade(): + op.alter_column('user', 'password', + existing_type=sa.VARCHAR(length=255), + nullable=True, + existing_server_default=sa.text("''::character varying")) diff --git a/utils/run_migrations.sh b/utils/run_migrations.sh index 64774af..6618919 100755 --- a/utils/run_migrations.sh +++ b/utils/run_migrations.sh @@ -2,4 +2,5 @@ # Run all pending migrations +./utils/reload.sh docker exec contentdb_app_1 sh -c "FLASK_CONFIG=../config.cfg FLASK_APP=app/__init__.py flask db upgrade"