mirror of
https://github.com/minetest/contentdb.git
synced 2024-11-08 08:33:45 +01:00
Add user account claiming
This commit is contained in:
parent
31615da169
commit
ff8bf992a9
@ -41,4 +41,4 @@ def make_celery(app):
|
||||
|
||||
celery = make_celery(app)
|
||||
|
||||
from . import importtasks
|
||||
from . import importtasks, forumtasks
|
||||
|
33
app/tasks/forumtasks.py
Normal file
33
app/tasks/forumtasks.py
Normal file
@ -0,0 +1,33 @@
|
||||
import flask
|
||||
from flask.ext.sqlalchemy import SQLAlchemy
|
||||
from app import app
|
||||
from app.models import *
|
||||
from app.tasks import celery
|
||||
from .phpbbparser import getProfile
|
||||
|
||||
@celery.task()
|
||||
def checkForumAccount(username, token=None):
|
||||
try:
|
||||
profile = getProfile("https://forum.minetest.net", username)
|
||||
except OSError:
|
||||
return
|
||||
|
||||
user = User.query.filter_by(forums_username=username).first()
|
||||
|
||||
# Create user
|
||||
needsSaving = False
|
||||
if user is None:
|
||||
user = User(username)
|
||||
user.forums_username = username
|
||||
db.session.add(user)
|
||||
|
||||
# Get github username
|
||||
github_username = profile.get("github")
|
||||
if github_username is not None and github_username.strip() != "":
|
||||
print("Updated github username")
|
||||
user.github_username = github_username
|
||||
needsSaving = True
|
||||
|
||||
# Save
|
||||
if needsSaving:
|
||||
db.session.commit()
|
72
app/tasks/phpbbparser.py
Normal file
72
app/tasks/phpbbparser.py
Normal file
@ -0,0 +1,72 @@
|
||||
import urllib, socket
|
||||
from bs4 import *
|
||||
from urllib.parse import urljoin
|
||||
import urllib.request
|
||||
import os.path
|
||||
import time
|
||||
|
||||
class Profile:
|
||||
def __init__(self, username):
|
||||
self.username = username
|
||||
self.signature = ""
|
||||
self.properties = {}
|
||||
|
||||
def set(self, key, value):
|
||||
self.properties[key] = value
|
||||
|
||||
def get(self, key):
|
||||
return self.properties[key] if key in self.properties else None
|
||||
|
||||
def __str__(self):
|
||||
return self.username + "\n" + str(self.signature) + "\n" + str(self.properties)
|
||||
|
||||
def __extract_properties(profile, soup):
|
||||
el = soup.find(id="viewprofile")
|
||||
if el is None:
|
||||
return None
|
||||
|
||||
res = el.find_all("dl", class_ = "left-box details")
|
||||
if len(res) != 1:
|
||||
return None
|
||||
|
||||
catch_next_key = None
|
||||
|
||||
# Look through
|
||||
for element in res[0].children:
|
||||
if element.name == "dt":
|
||||
if catch_next_key is None:
|
||||
catch_next_key = element.text.lower()[:-1].strip()
|
||||
else:
|
||||
print("Unexpected dt!")
|
||||
|
||||
elif element.name == "dd":
|
||||
if catch_next_key is None:
|
||||
print("Unexpected dd!")
|
||||
else:
|
||||
if catch_next_key != "groups":
|
||||
profile.set(catch_next_key, element.text)
|
||||
catch_next_key = None
|
||||
|
||||
elif element and element.name is not None:
|
||||
print("Unexpected other")
|
||||
|
||||
def __extract_signature(soup):
|
||||
res = soup.find_all("div", class_="signature")
|
||||
if (len(res) != 1):
|
||||
return None
|
||||
else:
|
||||
return res[0]
|
||||
|
||||
def getProfile(url, username):
|
||||
url = url + "/memberlist.php?mode=viewprofile&un=" + username
|
||||
|
||||
contents = urllib.request.urlopen(url).read().decode("utf-8")
|
||||
soup = BeautifulSoup(contents, "lxml")
|
||||
if soup is None:
|
||||
return None
|
||||
else:
|
||||
profile = Profile(username)
|
||||
profile.signature = __extract_signature(soup)
|
||||
__extract_properties(profile, soup)
|
||||
|
||||
return profile
|
@ -61,26 +61,17 @@ Sign in
|
||||
{# Submit button #}
|
||||
{{ render_submit_field(form.submit, tabindex=180) }}
|
||||
</form>
|
||||
|
||||
<a href="{{ url_for('github_signin_page') }}">GitHub</a>
|
||||
</div>
|
||||
|
||||
<div class="right">
|
||||
<aside class="box box_grey">
|
||||
<h2>New here?</h2>
|
||||
|
||||
<div class="box box_grey alert alert-error">
|
||||
Please use Github login instead!
|
||||
</div>
|
||||
<p>Create an account using your forum account.</p>
|
||||
|
||||
{% if user_manager.enable_register and not user_manager.require_invitation %}
|
||||
<a href="{{ url_for('github_signin_page') }}">{%trans%}Create an account{%endtrans%}</a>
|
||||
{% endif %}
|
||||
</aside>
|
||||
|
||||
|
||||
<aside class="box box_grey">
|
||||
<h2>OAUTH</h2>
|
||||
|
||||
<a href="{{ url_for('github_signin_page') }}">GitHub</a>
|
||||
<a href="{{ url_for('user_claim_page') }}" class="button">{%trans%}Claim your account{%endtrans%}</a>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
|
98
app/templates/users/claim.html
Normal file
98
app/templates/users/claim.html
Normal file
@ -0,0 +1,98 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}
|
||||
Verify forum account
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="box box_grey">
|
||||
<h2>{{ self.title() }}</h2>
|
||||
|
||||
<p>
|
||||
Create an account by linking it to your forum account and optionally
|
||||
your github account.
|
||||
</p>
|
||||
|
||||
{% if current_user.is_authenticated %}
|
||||
<p>
|
||||
Please log out to continue.
|
||||
</p>
|
||||
<p>
|
||||
<a href="{{ url_for('user.logout', next=url_for('user_claim_page')) }}" class="button">Logout</a>
|
||||
</p>
|
||||
{% else %}
|
||||
<p>
|
||||
<b>Don't have a forum account?</b>
|
||||
Unfortunately, you need a forum account to register.
|
||||
This is because you also need to create forum topics for any packages
|
||||
you may upload.
|
||||
</p>
|
||||
|
||||
<a href="https://forum.minetest.net/ucp.php?mode=register">
|
||||
Create a Forum Account
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if not current_user.is_authenticated %}
|
||||
<div class="box box_grey">
|
||||
<h2>Option 1 - Use GitHub field in forum profile</h2>
|
||||
|
||||
<form method="post" action="{{ url_for('user_claim_page') }}">
|
||||
<input type="hidden" name="claim_type" value="github">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
|
||||
<p>
|
||||
Enter your forum username here:
|
||||
</p>
|
||||
|
||||
<input type="text" name="username" value="{{ username }}" required placeholder="Forum username">
|
||||
|
||||
<p>
|
||||
You'll need to have the GitHub field in your forum profile
|
||||
filled out. Log into the forum and
|
||||
<a href="https://forum.minetest.net/ucp.php?i=173">
|
||||
do that here</a>.
|
||||
</p>
|
||||
|
||||
<input type="submit" value="Next: log in with GitHub">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!--<div class="box box_grey">
|
||||
<h2>Option 2 - Paste verification token into signature</h2>
|
||||
|
||||
<form method="post" action="{{ url_for('user_claim_page') }}">
|
||||
<input type="hidden" name="claim_type" value="forum">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
|
||||
<p>
|
||||
Enter your forum username here:
|
||||
</p>
|
||||
|
||||
<input type="text" name="username" value="{{ username }}" required placeholder="Forum username">
|
||||
|
||||
<p>
|
||||
Go to
|
||||
<a href="https://forum.minetest.net/ucp.php?i=profile&mode=signature">
|
||||
User Control Panel > Profile > Edit signature
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
Paste this into your signature:
|
||||
</p>
|
||||
|
||||
<input type="text" value="{{ key }}" readonly size=32>
|
||||
|
||||
<p>
|
||||
Click next so we can check it.
|
||||
</p>
|
||||
<p>
|
||||
Don't worry, you can remove it after this is done.
|
||||
</p>
|
||||
|
||||
<input type="submit" value="Next">
|
||||
</form>
|
||||
</div>-->
|
||||
{% endif %}
|
||||
{% endblock %}
|
@ -43,16 +43,8 @@ def github_authorized(oauth_token):
|
||||
# If not logged in, log in
|
||||
else:
|
||||
if userByGithub is None:
|
||||
newUser = User(username)
|
||||
newUser.github_username = username
|
||||
db.session.add(newUser)
|
||||
db.session.commit()
|
||||
|
||||
if not loginUser(newUser):
|
||||
raise Exception("Unable to login as user we just created")
|
||||
|
||||
flash("Created an account", "success")
|
||||
return redirect(url_for("user_profile_page", username=username))
|
||||
flash("Unable to find an account for that Github user", "error")
|
||||
return redirect(url_for("user_claim_page"))
|
||||
elif loginUser(userByGithub):
|
||||
return redirect(next_url or url_for("home_page"))
|
||||
else:
|
||||
|
@ -22,7 +22,6 @@ def new_getmeta_page():
|
||||
})
|
||||
|
||||
@app.route("/tasks/<id>/")
|
||||
@login_required
|
||||
def check_task(id):
|
||||
result = celery.AsyncResult(id)
|
||||
status = result.status
|
||||
@ -51,7 +50,6 @@ def check_task(id):
|
||||
abort(422)
|
||||
|
||||
if status == "SUCCESS":
|
||||
flash("Task complete!", "success")
|
||||
return redirect(r)
|
||||
else:
|
||||
return render_template("tasks/view.html", info=info)
|
||||
|
@ -8,7 +8,8 @@ from flask_wtf import FlaskForm
|
||||
from flask_user.forms import RegisterForm
|
||||
from wtforms import *
|
||||
from wtforms.validators import *
|
||||
from .utils import rank_required
|
||||
from .utils import rank_required, randomString
|
||||
from app.tasks.forumtasks import checkForumAccount
|
||||
|
||||
class MyRegisterForm(RegisterForm):
|
||||
display_name = StringField("Display name")
|
||||
@ -59,3 +60,42 @@ def user_profile_page(username):
|
||||
# Process GET or invalid POST
|
||||
return render_template("users/user_profile_page.html",
|
||||
user=user, form=form)
|
||||
|
||||
|
||||
@app.route("/users/claim/", methods=["GET", "POST"])
|
||||
def user_claim_page():
|
||||
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("user_claim_page"))
|
||||
elif user is None and method == "github":
|
||||
flash("Unable to get Github username for user", "error")
|
||||
return redirect(url_for("user_claim_page"))
|
||||
elif user is None:
|
||||
flash("Unable to find that user", "error")
|
||||
return redirect(url_for("user_claim_page"))
|
||||
|
||||
if user is not None and method == "github":
|
||||
return redirect(url_for("github_signin_page"))
|
||||
|
||||
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("check_task", id=task.id, r=url_for("user_claim_page", username=username, method="github")))
|
||||
elif ctype == "forum":
|
||||
token = request.form.get("token")
|
||||
flash("Unimplemented", "error")
|
||||
else:
|
||||
flash("Unknown claim type", "error")
|
||||
|
||||
return render_template("users/claim.html", username=username, key=randomString(32))
|
||||
|
@ -8,3 +8,5 @@ GitHub-Flask>=3.2.0
|
||||
pyScss==1.3.4
|
||||
celery==4.0.2
|
||||
redis==2.10.6
|
||||
beautifulsoup4==4.6.0
|
||||
lxml==4.2.1
|
||||
|
Loading…
Reference in New Issue
Block a user