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)
|
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 #}
|
{# Submit button #}
|
||||||
{{ render_submit_field(form.submit, tabindex=180) }}
|
{{ render_submit_field(form.submit, tabindex=180) }}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<a href="{{ url_for('github_signin_page') }}">GitHub</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<aside class="box box_grey">
|
<aside class="box box_grey">
|
||||||
<h2>New here?</h2>
|
<h2>New here?</h2>
|
||||||
|
|
||||||
<div class="box box_grey alert alert-error">
|
<p>Create an account using your forum account.</p>
|
||||||
Please use Github login instead!
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% if user_manager.enable_register and not user_manager.require_invitation %}
|
<a href="{{ url_for('user_claim_page') }}" class="button">{%trans%}Claim your account{%endtrans%}</a>
|
||||||
<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>
|
|
||||||
</aside>
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
</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
|
# If not logged in, log in
|
||||||
else:
|
else:
|
||||||
if userByGithub is None:
|
if userByGithub is None:
|
||||||
newUser = User(username)
|
flash("Unable to find an account for that Github user", "error")
|
||||||
newUser.github_username = username
|
return redirect(url_for("user_claim_page"))
|
||||||
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))
|
|
||||||
elif loginUser(userByGithub):
|
elif loginUser(userByGithub):
|
||||||
return redirect(next_url or url_for("home_page"))
|
return redirect(next_url or url_for("home_page"))
|
||||||
else:
|
else:
|
||||||
|
@ -22,7 +22,6 @@ def new_getmeta_page():
|
|||||||
})
|
})
|
||||||
|
|
||||||
@app.route("/tasks/<id>/")
|
@app.route("/tasks/<id>/")
|
||||||
@login_required
|
|
||||||
def check_task(id):
|
def check_task(id):
|
||||||
result = celery.AsyncResult(id)
|
result = celery.AsyncResult(id)
|
||||||
status = result.status
|
status = result.status
|
||||||
@ -51,7 +50,6 @@ def check_task(id):
|
|||||||
abort(422)
|
abort(422)
|
||||||
|
|
||||||
if status == "SUCCESS":
|
if status == "SUCCESS":
|
||||||
flash("Task complete!", "success")
|
|
||||||
return redirect(r)
|
return redirect(r)
|
||||||
else:
|
else:
|
||||||
return render_template("tasks/view.html", info=info)
|
return render_template("tasks/view.html", info=info)
|
||||||
|
@ -8,7 +8,8 @@ from flask_wtf import FlaskForm
|
|||||||
from flask_user.forms import RegisterForm
|
from flask_user.forms import RegisterForm
|
||||||
from wtforms import *
|
from wtforms import *
|
||||||
from wtforms.validators 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):
|
class MyRegisterForm(RegisterForm):
|
||||||
display_name = StringField("Display name")
|
display_name = StringField("Display name")
|
||||||
@ -59,3 +60,42 @@ def user_profile_page(username):
|
|||||||
# Process GET or invalid POST
|
# Process GET or invalid POST
|
||||||
return render_template("users/user_profile_page.html",
|
return render_template("users/user_profile_page.html",
|
||||||
user=user, form=form)
|
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
|
pyScss==1.3.4
|
||||||
celery==4.0.2
|
celery==4.0.2
|
||||||
redis==2.10.6
|
redis==2.10.6
|
||||||
|
beautifulsoup4==4.6.0
|
||||||
|
lxml==4.2.1
|
||||||
|
Loading…
Reference in New Issue
Block a user