diff --git a/app/__init__.py b/app/__init__.py index f041332..23b52b7 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -87,7 +87,7 @@ def flatpage(path): def check_for_ban(): if current_user.is_authenticated: if current_user.rank == models.UserRank.BANNED: - flash("You have been banned.", "error") + flash("You have been banned.", "danger") logout_user() return redirect(url_for('user.login')) elif current_user.rank == models.UserRank.NOT_JOINED: diff --git a/app/blueprints/admin/admin.py b/app/blueprints/admin/admin.py index 6de85d0..9af9c17 100644 --- a/app/blueprints/admin/admin.py +++ b/app/blueprints/admin/admin.py @@ -71,7 +71,7 @@ def admin_page(): elif action == "restore": package = Package.query.get(request.form["package"]) if package is None: - flash("Unknown package", "error") + flash("Unknown package", "danger") else: package.soft_deleted = False db.session.commit() @@ -115,7 +115,7 @@ def admin_page(): db.session.commit() else: - flash("Unknown action: " + action, "error") + flash("Unknown action: " + action, "danger") deleted_packages = Package.query.filter_by(soft_deleted=True).all() return render_template("admin/list.html", deleted_packages=deleted_packages) @@ -132,11 +132,11 @@ def switch_user(): if request.method == "POST" and form.validate(): user = User.query.filter_by(username=form["username"].data).first() if user is None: - flash("Unable to find user", "error") + flash("Unable to find user", "danger") elif loginUser(user): return redirect(url_for("users.profile", username=current_user.username)) else: - flash("Unable to login as user", "error") + flash("Unable to login as user", "danger") # Process GET or invalid POST diff --git a/app/blueprints/users/githublogin.py b/app/blueprints/github/__init__.py similarity index 87% rename from app/blueprints/users/githublogin.py rename to app/blueprints/github/__init__.py index a029361..8a04390 100644 --- a/app/blueprints/users/githublogin.py +++ b/app/blueprints/github/__init__.py @@ -14,25 +14,25 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +from flask import Blueprint -from flask import * -from flask_user import * -from flask_login import login_user, logout_user +bp = Blueprint("github", __name__) + +from flask import redirect, url_for, request, flash +from flask_user import current_user from sqlalchemy import func -import flask_menu as menu from flask_github import GitHub -from . import bp from app import github -from app.models import * +from app.models import db, User from app.utils import loginUser -@bp.route("/user/github/start/") -def github_signin(): +@bp.route("/github/start/") +def start(): return github.authorize("") @bp.route("/user/github/callback/") @github.authorized_handler -def github_authorized(oauth_token): +def callback(oauth_token): next_url = request.args.get("next") if oauth_token is None: flash("Authorization failed [err=gh-oauth-login-failed]", "danger") @@ -62,7 +62,7 @@ def github_authorized(oauth_token): # If not logged in, log in else: if userByGithub is None: - flash("Unable to find an account for that Github user", "error") + flash("Unable to find an account for that Github user", "danger") return redirect(url_for("users.claim")) elif loginUser(userByGithub): if not current_user.hasPassword(): diff --git a/app/blueprints/packages/editrequests.py b/app/blueprints/packages/editrequests.py index 5ee9cd1..ee0d162 100644 --- a/app/blueprints/packages/editrequests.py +++ b/app/blueprints/packages/editrequests.py @@ -50,7 +50,7 @@ def create_edit_editrequest_page(package, id=None): abort(403) if erequest.status != 0: - flash("Can't edit EditRequest, it has already been merged or rejected", "error") + flash("Can't edit EditRequest, it has already been merged or rejected", "danger") return redirect(erequest.getURL()) edited_package = Package(package) @@ -127,7 +127,7 @@ def view_editrequest_page(package, id): @is_package_page def approve_editrequest_page(package, id): if not package.checkPerm(current_user, Permission.APPROVE_CHANGES): - flash("You don't have permission to do that.", "error") + flash("You don't have permission to do that.", "danger") return redirect(package.getDetailsURL()) erequest = EditRequest.query.get(id) @@ -135,7 +135,7 @@ def approve_editrequest_page(package, id): abort(404) if erequest.status != 0: - flash("Edit request has already been resolved", "error") + flash("Edit request has already been resolved", "danger") else: erequest.status = 1 @@ -152,7 +152,7 @@ def approve_editrequest_page(package, id): @is_package_page def reject_editrequest_page(package, id): if not package.checkPerm(current_user, Permission.APPROVE_CHANGES): - flash("You don't have permission to do that.", "error") + flash("You don't have permission to do that.", "danger") return redirect(package.getDetailsURL()) erequest = EditRequest.query.get(id) @@ -160,7 +160,7 @@ def reject_editrequest_page(package, id): abort(404) if erequest.status != 0: - flash("Edit request has already been resolved", "error") + flash("Edit request has already been resolved", "danger") else: erequest.status = 2 diff --git a/app/blueprints/packages/packages.py b/app/blueprints/packages/packages.py index 6ae6d5a..fd699b8 100644 --- a/app/blueprints/packages/packages.py +++ b/app/blueprints/packages/packages.py @@ -161,7 +161,7 @@ def download(package): not "text/html" in request.accept_mimetypes: return "", 204 else: - flash("No download available.", "error") + flash("No download available.", "danger") return redirect(package.getDetailsURL()) else: PackageRelease.query.filter_by(id=release.id).update({ @@ -204,11 +204,11 @@ def create_edit(author=None, name=None): else: author = User.query.filter_by(username=author).first() if author is None: - flash("Unable to find that user", "error") + flash("Unable to find that user", "danger") return redirect(url_for("packages.create_edit")) if not author.checkPerm(current_user, Permission.CHANGE_AUTHOR): - flash("Permission denied", "error") + flash("Permission denied", "danger") return redirect(url_for("packages.create_edit")) else: @@ -240,7 +240,7 @@ def create_edit(author=None, name=None): if package.soft_deleted: Package.query.filter_by(name=form["name"].data, author_id=author.id).delete() else: - flash("Package already exists!", "error") + flash("Package already exists!", "danger") return redirect(url_for("packages.create_edit")) package = Package() @@ -313,10 +313,10 @@ def create_edit(author=None, name=None): @is_package_page def approve(package): if not package.checkPerm(current_user, Permission.APPROVE_NEW): - flash("You don't have permission to do that.", "error") + flash("You don't have permission to do that.", "danger") elif package.approved: - flash("Package has already been approved", "error") + flash("Package has already been approved", "danger") else: package.approved = True @@ -341,7 +341,7 @@ def remove(package): if "delete" in request.form: if not package.checkPerm(current_user, Permission.DELETE_PACKAGE): - flash("You don't have permission to do that.", "error") + flash("You don't have permission to do that.", "danger") return redirect(package.getDetailsURL()) package.soft_deleted = True @@ -356,7 +356,7 @@ def remove(package): return redirect(url) elif "unapprove" in request.form: if not package.checkPerm(current_user, Permission.UNAPPROVE_PACKAGE): - flash("You don't have permission to do that.", "error") + flash("You don't have permission to do that.", "danger") return redirect(package.getDetailsURL()) package.approved = False diff --git a/app/blueprints/threads/__init__.py b/app/blueprints/threads/__init__.py index 8d6c22d..a55d55e 100644 --- a/app/blueprints/threads/__init__.py +++ b/app/blueprints/threads/__init__.py @@ -142,7 +142,7 @@ def new(): if "pid" in request.args: package = Package.query.get(int(request.args.get("pid"))) if package is None: - flash("Unable to find that package!", "error") + flash("Unable to find that package!", "danger") # Don't allow making orphan threads on approved packages for now if package is None: @@ -156,12 +156,12 @@ def new(): # Check that user can make the thread if not package.checkPerm(current_user, Permission.CREATE_THREAD): - flash("Unable to create thread!", "error") + flash("Unable to create thread!", "danger") return redirect(url_for("homepage.home")) # Only allow creating one thread when not approved elif is_review_thread and package.review_thread is not None: - flash("A review thread already exists!", "error") + flash("A review thread already exists!", "danger") return redirect(url_for("threads.view", id=package.review_thread.id)) elif not current_user.canOpenThreadRL(): diff --git a/app/blueprints/users/__init__.py b/app/blueprints/users/__init__.py index 98cf34a..2e2f965 100644 --- a/app/blueprints/users/__init__.py +++ b/app/blueprints/users/__init__.py @@ -2,4 +2,4 @@ from flask import Blueprint bp = Blueprint("users", __name__) -from . import githublogin, profile +from . import profile, claim diff --git a/app/blueprints/users/claim.py b/app/blueprints/users/claim.py new file mode 100644 index 0000000..7c6283d --- /dev/null +++ b/app/blueprints/users/claim.py @@ -0,0 +1,98 @@ +# Content DB +# Copyright (C) 2018 rubenwardy +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +from . import bp +from flask import redirect, render_template, session, request, flash, url_for +from flask_user import current_user +from app.models import db, User, UserRank +from app.utils import randomString, loginUser, rank_required +from app.tasks.forumtasks import checkForumAccount +from app.tasks.phpbbparser import getProfile + +@bp.route("/user/claim/", methods=["GET", "POST"]) +def claim(): + username = request.args.get("username") + if username is None: + username = "" + else: + method = request.args.get("method") + user = User.query.filter_by(forums_username=username).first() + if user and user.rank.atLeast(UserRank.NEW_MEMBER): + flash("User has already been claimed", "danger") + return redirect(url_for("users.claim")) + elif user is None and method == "github": + flash("Unable to get Github username for user", "danger") + return redirect(url_for("users.claim")) + elif user is None: + flash("Unable to find that user", "danger") + return redirect(url_for("users.claim")) + + if user is not None and method == "github": + return redirect(url_for("github.start")) + + token = None + if "forum_token" in session: + token = session["forum_token"] + else: + token = randomString(32) + session["forum_token"] = token + + if request.method == "POST": + ctype = request.form.get("claim_type") + username = request.form.get("username") + + if username is None or len(username.strip()) < 2: + flash("Invalid username", "danger") + elif ctype == "github": + task = checkForumAccount.delay(username) + return redirect(url_for("tasks.check", id=task.id, r=url_for("users.claim", username=username, method="github"))) + elif ctype == "forum": + user = User.query.filter_by(forums_username=username).first() + if user is not None and user.rank.atLeast(UserRank.NEW_MEMBER): + flash("That user has already been claimed!", "danger") + return redirect(url_for("users.claim")) + + # Get signature + sig = None + try: + profile = getProfile("https://forum.minetest.net", username) + sig = profile.signature + except IOError: + flash("Unable to get forum signature - does the user exist?", "danger") + return redirect(url_for("users.claim", username=username)) + + # Look for key + if token in sig: + if user is None: + user = User(username) + user.forums_username = username + db.session.add(user) + db.session.commit() + + if loginUser(user): + return redirect(url_for("users.set_password")) + else: + flash("Unable to login as user", "danger") + return redirect(url_for("users.claim", username=username)) + + else: + flash("Could not find the key in your signature!", "danger") + return redirect(url_for("users.claim", username=username)) + else: + flash("Unknown claim type", "danger") + + return render_template("users/claim.html", username=username, key=token) diff --git a/app/blueprints/users/profile.py b/app/blueprints/users/profile.py index 0036fa9..a4e194e 100644 --- a/app/blueprints/users/profile.py +++ b/app/blueprints/users/profile.py @@ -71,7 +71,7 @@ def profile(username): if current_user.rank.atLeast(newRank): user.rank = form["rank"].data else: - flash("Can't promote a user to a rank higher than yourself!", "error") + flash("Can't promote a user to a rank higher than yourself!", "danger") if user.checkPerm(current_user, Permission.CHANGE_EMAIL): newEmail = form["email"].data @@ -147,7 +147,7 @@ def send_email(username): next_url = url_for("users.profile", username=user.username) if user.email is None: - flash("User has no email address!", "error") + flash("User has no email address!", "danger") return redirect(next_url) form = SendEmailForm(request.form) @@ -214,91 +214,17 @@ def set_password(): else: return redirect(url_for("user.login")) else: - flash("Passwords do not match", "error") + flash("Passwords do not match", "danger") return render_template("users/set_password.html", form=form, optional=request.args.get("optional")) -@bp.route("/user/claim/", methods=["GET", "POST"]) -def claim(): - username = request.args.get("username") - if username is None: - username = "" - else: - method = request.args.get("method") - user = User.query.filter_by(forums_username=username).first() - if user and user.rank.atLeast(UserRank.NEW_MEMBER): - flash("User has already been claimed", "error") - return redirect(url_for("users.claim")) - elif user is None and method == "github": - flash("Unable to get Github username for user", "error") - return redirect(url_for("users.claim")) - elif user is None: - flash("Unable to find that user", "error") - return redirect(url_for("users.claim")) - - if user is not None and method == "github": - return redirect(url_for("users.github_signin")) - - token = None - if "forum_token" in session: - token = session["forum_token"] - else: - token = randomString(32) - session["forum_token"] = token - - if request.method == "POST": - ctype = request.form.get("claim_type") - username = request.form.get("username") - - if username is None or len(username.strip()) < 2: - flash("Invalid username", "error") - elif ctype == "github": - task = checkForumAccount.delay(username) - return redirect(url_for("tasks.check", id=task.id, r=url_for("users.claim", username=username, method="github"))) - elif ctype == "forum": - user = User.query.filter_by(forums_username=username).first() - if user is not None and user.rank.atLeast(UserRank.NEW_MEMBER): - flash("That user has already been claimed!", "error") - return redirect(url_for("users.claim")) - - # Get signature - sig = None - try: - profile = getProfile("https://forum.minetest.net", username) - sig = profile.signature - except IOError: - flash("Unable to get forum signature - does the user exist?", "error") - return redirect(url_for("users.claim", username=username)) - - # Look for key - if token in sig: - if user is None: - user = User(username) - user.forums_username = username - db.session.add(user) - db.session.commit() - - if loginUser(user): - return redirect(url_for("users.set_password")) - else: - flash("Unable to login as user", "error") - return redirect(url_for("users.claim", username=username)) - - else: - flash("Could not find the key in your signature!", "error") - return redirect(url_for("users.claim", username=username)) - else: - flash("Unknown claim type", "error") - - return render_template("users/claim.html", username=username, key=token) - @bp.route("/users/verify/") def verify_email(): token = request.args.get("token") ver = UserEmailVerification.query.filter_by(token=token).first() if ver is None: - flash("Unknown verification token!", "error") + flash("Unknown verification token!", "danger") else: ver.user.email = ver.email db.session.delete(ver) diff --git a/app/templates/flask_user/login.html b/app/templates/flask_user/login.html index 3e93d38..87f5428 100644 --- a/app/templates/flask_user/login.html +++ b/app/templates/flask_user/login.html @@ -60,7 +60,7 @@ Sign in {% from "flask_user/_macros.html" import render_field, render_checkbox_field, render_submit_field %}

{%trans%}Sign in with Github{%endtrans%}

diff --git a/app/templates/users/profile.html b/app/templates/users/profile.html index bd4875d..d2f5baa 100644 --- a/app/templates/users/profile.html +++ b/app/templates/users/profile.html @@ -57,7 +57,7 @@ {% if user.github_username %} GitHub {% elif user == current_user %} - Link Github + Link Github {% endif %} {% if user.website_url %} diff --git a/app/utils.py b/app/utils.py index 9ce7836..f44622d 100644 --- a/app/utils.py +++ b/app/utils.py @@ -48,7 +48,7 @@ def randomString(n): def doFileUpload(file, fileType, fileTypeDesc): if not file or file is None or file.filename == "": - flash("No selected file", "error") + flash("No selected file", "danger") return None, None assert os.path.isdir(app.config["UPLOAD_DIR"]), "UPLOAD_DIR must exist" @@ -114,7 +114,7 @@ def loginUser(user): return False if user.rank == UserRank.BANNED: - flash("You have been banned.", "error") + flash("You have been banned.", "danger") return False user.active = True @@ -125,7 +125,7 @@ def loginUser(user): # Check if user account has been disabled if not _call_or_get(user.is_active): - flash("Your account has not been enabled.", "error") + flash("Your account has not been enabled.", "danger") return False # Use Flask-Login to sign in user