diff --git a/requirements.txt b/requirements.txt
index f64e3932..b6493f03 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,4 @@
+bcrypt
python-telegram-bot>=11.1.0
websockets>=7.0
pytest>=4.3.1
diff --git a/royalnet/database/tables/wikipages.py b/royalnet/database/tables/wikipages.py
index 914a59b8..0ea21aea 100644
--- a/royalnet/database/tables/wikipages.py
+++ b/royalnet/database/tables/wikipages.py
@@ -3,6 +3,7 @@ from sqlalchemy import Column, \
String
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.ext.declarative import declared_attr
+from royalnet.web.shortcuts import to_urluuid
class WikiPage:
@@ -31,3 +32,7 @@ class WikiPage:
@declared_attr
def css(self):
return Column(String)
+
+ @property
+ def page_short_id(self):
+ return to_urluuid(self.page_id)
diff --git a/royalnet/royalgames.py b/royalnet/royalgames.py
index df45a0dd..19632a27 100644
--- a/royalnet/royalgames.py
+++ b/royalnet/royalgames.py
@@ -1,3 +1,5 @@
+"""The production Royalnet, active at @royalgamesbot on Telegram and Royalbot on Discord."""
+
import os
import asyncio
import logging
diff --git a/royalnet/royalgamesweb.py b/royalnet/royalgamesweb.py
index b5a37c11..93fd819a 100644
--- a/royalnet/royalgamesweb.py
+++ b/royalnet/royalgamesweb.py
@@ -1,3 +1,5 @@
+"""The production Royalnet available at ryg.steffo.eu ."""
+
import os
from royalnet.web import create_app
from royalnet.web.royalprints import *
@@ -6,10 +8,11 @@ from royalnet.web.royalprints import *
class TestConfig:
DB_PATH = os.environ["DB_PATH"]
TG_AK = os.environ["TG_AK"]
+ SITE_NAME = "Royalnet"
app = create_app(TestConfig, [rp_home, rp_wikiview, rp_tglogin, rp_docs, rp_wikiedit, rp_mcstatus, rp_diarioview,
- rp_profile])
+ rp_profile, rp_login, rp_newaccount])
if __name__ == "__main__":
diff --git a/royalnet/web/flaskserver.py b/royalnet/web/flaskserver.py
index 260af039..b85f4c5d 100644
--- a/royalnet/web/flaskserver.py
+++ b/royalnet/web/flaskserver.py
@@ -14,7 +14,7 @@ def create_app(config_obj: typing.Type, blueprints: typing.List[Royalprint]):
Also requires a ``DB_PATH`` key in ``config_obj`` to initialize the database connection.
Warning:
- The code for this class was written at 1 AM, and I have no clue of how and why it works or even of if it really does work.
+ The code for this class was written at 1 AM, and I have no clue of how and why it works or even if it really does work.
Use with caution?
Args:
diff --git a/royalnet/web/royalprints/__init__.py b/royalnet/web/royalprints/__init__.py
index a902af18..d2dfd110 100644
--- a/royalnet/web/royalprints/__init__.py
+++ b/royalnet/web/royalprints/__init__.py
@@ -1,12 +1,26 @@
"""Some Royalprints that can be used with the Royalnet Flask server."""
-from .home import rp as rp_home
-from .wikiview import rp as rp_wikiview
-from .tglogin import rp as rp_tglogin
-from .docs import rp as rp_docs
-from .wikiedit import rp as rp_wikiedit
-from .mcstatus import rp as rp_mcstatus
-from .diarioview import rp as rp_diarioview
-from .profile import rp as rp_profile
+from . import home
+from . import wikiview
+from . import tglogin
+from . import docs
+from . import wikiedit
+from . import mcstatus
+from . import diarioview
+from . import profile
+from . import login
+from . import newaccount
-__all__ = ["rp_home", "rp_wikiview", "rp_tglogin", "rp_docs", "rp_wikiedit", "rp_mcstatus", "rp_diarioview", "rp_profile"]
+rp_home = home.rp
+rp_wikiview = wikiview.rp
+rp_tglogin = tglogin.rp
+rp_docs = docs.rp
+rp_wikiedit = wikiedit.rp
+rp_mcstatus = mcstatus.rp
+rp_diarioview = diarioview.rp
+rp_profile = profile.rp
+rp_login = login.rp
+rp_newaccount = newaccount.rp
+
+__all__ = ["rp_home", "rp_wikiview", "rp_tglogin", "rp_docs", "rp_wikiedit", "rp_mcstatus", "rp_diarioview",
+ "rp_profile", "rp_login", "rp_newaccount"]
diff --git a/royalnet/web/royalprints/diarioview/templates/diarioview_page.html b/royalnet/web/royalprints/diarioview/templates/diarioview_page.html
index 414b4962..b8c09ead 100644
--- a/royalnet/web/royalprints/diarioview/templates/diarioview_page.html
+++ b/royalnet/web/royalprints/diarioview/templates/diarioview_page.html
@@ -1,7 +1,7 @@
{% extends "base.html" %}
{% block title %}
- Pagina {{ page }} - Diario RYG
+ Diario: Pagina {{ page }}
{% endblock %}
{% block content %}
diff --git a/royalnet/web/royalprints/login/__init__.py b/royalnet/web/royalprints/login/__init__.py
new file mode 100644
index 00000000..0ee00573
--- /dev/null
+++ b/royalnet/web/royalprints/login/__init__.py
@@ -0,0 +1,42 @@
+"""A Royalnet password-based login :py:class:`royalnet.web.Royalprint`."""
+import flask as f
+import os
+import datetime
+import bcrypt
+from ...royalprint import Royalprint
+from ...shortcuts import error
+from ....database.tables import Royal
+
+
+tmpl_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates')
+rp = Royalprint("login", __name__, url_prefix="/login/password", required_tables={Royal},
+ template_folder=tmpl_dir)
+
+
+@rp.route("/")
+def login_index():
+ f.session.pop("royal", None)
+ return f.render_template("login_index.html")
+
+
+@rp.route("/done", methods=["POST"])
+def login_done():
+ alchemy, alchemy_session = f.current_app.config["ALCHEMY"], f.current_app.config["ALCHEMY_SESSION"]
+ fd = f.request.form
+ if "username" not in fd:
+ return error(400, "Nessun username inserito.")
+ royal_user = alchemy_session.query(alchemy.Royal).filter_by(username=fd["username"]).one_or_none()
+ if royal_user is None:
+ return error(404, "L'username inserito non corrisponde a nessun account registrato.")
+ if "password" not in fd:
+ return error(400, "Nessuna password inserita.")
+ if not bcrypt.checkpw(bytes(fd["password"], encoding="utf8"), royal_user.password):
+ return error(400, "La password inserita non è valida.")
+ f.session["royal"] = {
+ "uid": royal_user.uid,
+ "username": royal_user.username,
+ "avatar": royal_user.avatar,
+ "role": royal_user.role
+ }
+ f.session["login_date"] = datetime.datetime.now()
+ return f.render_template("login_success.html")
diff --git a/royalnet/web/royalprints/login/templates/login_index.html b/royalnet/web/royalprints/login/templates/login_index.html
new file mode 100644
index 00000000..974d666a
--- /dev/null
+++ b/royalnet/web/royalprints/login/templates/login_index.html
@@ -0,0 +1,49 @@
+{% extends "base.html" %}
+
+{% block title %}
+ Password Login
+{% endblock %}
+
+{% block content %}
+
+
+
+
+ Password Login
+
+
+
+
+ Non hai una password? Prova il Login con Telegram!
+
+
+ Facendo il login su questo sito, acconsenti a ricevere due biscottini che memorizzino l'account con cui hai fatto il login.
+
+
+ Essi avranno il seguente formato:
+
+
session["royal"] = {
+"uid": [il tuo id Royalnet]
+"username": [il tuo username Royalnet],
+"avatar": [il tuo avatar Royalnet],
+"role": [il tuo ruolo Royalnet]
+}
+
+session["login_date"] = [la data e l'ora di adesso]
+
+
+
+
+{% endblock %}
diff --git a/royalnet/web/royalprints/login/templates/login_success.html b/royalnet/web/royalprints/login/templates/login_success.html
new file mode 100644
index 00000000..d9005137
--- /dev/null
+++ b/royalnet/web/royalprints/login/templates/login_success.html
@@ -0,0 +1,18 @@
+{% extends "base.html" %}
+
+{% block title %}
+ Password Login riuscito
+{% endblock %}
+
+{% block content %}
+
+
+
+ Password Login
+
+
+
+ Login riuscito! Sei connesso come {{ session["royal"]["username"] }}!
+
+
+{% endblock %}
diff --git a/royalnet/web/royalprints/mcstatus/templates/mcstatus.html b/royalnet/web/royalprints/mcstatus/templates/mcstatus.html
index b90668a7..e6c3a560 100644
--- a/royalnet/web/royalprints/mcstatus/templates/mcstatus.html
+++ b/royalnet/web/royalprints/mcstatus/templates/mcstatus.html
@@ -1,7 +1,7 @@
{% extends "base.html" %}
{% block title %}
- {{ server_str }} - RYG MCstatus
+ Minecraft {{ server_str }}
{% endblock %}
{% block content %}
diff --git a/royalnet/web/royalprints/newaccount/__init__.py b/royalnet/web/royalprints/newaccount/__init__.py
new file mode 100644
index 00000000..20de4f34
--- /dev/null
+++ b/royalnet/web/royalprints/newaccount/__init__.py
@@ -0,0 +1,40 @@
+"""A :py:class:`royalnet.web.Royalprint` to create new Royals."""
+import flask as f
+import os
+import datetime
+import bcrypt
+from ...royalprint import Royalprint
+from ...shortcuts import error
+from ....database.tables import Royal, Alias
+
+
+tmpl_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates')
+rp = Royalprint("newaccount", __name__, url_prefix="/newaccount", required_tables={Royal, Alias},
+ template_folder=tmpl_dir)
+
+
+@rp.route("/", methods=["GET", "POST"])
+def login_index():
+ if f.request.method == "GET":
+ return f.render_template("newaccount_index.html")
+ elif f.request.method == "POST":
+ alchemy, alchemy_session = f.current_app.config["ALCHEMY"], f.current_app.config["ALCHEMY_SESSION"]
+ fd = f.request.form
+ if "username" not in fd:
+ return error(400, "Non è stato inserito nessun username.")
+ if "password" not in fd:
+ return error(400, "Non è stata inserita nessuna password.")
+ royal = alchemy_session.query(alchemy.Royal).filter_by(username=fd["username"]).one_or_none()
+ if royal is not None:
+ return error(403, "Esiste già un utente con quell'username.")
+ alias = alchemy_session.query(alchemy.Alias).filter_by(alias=fd["username"]).one_or_none()
+ if alias is not None:
+ return error(403, "Esiste già un utente con quell'alias.")
+ royal = alchemy.Royal(username=fd["username"],
+ password=bcrypt.hashpw(bytes(fd["password"], encoding="utf8"), bcrypt.gensalt()),
+ role="Guest")
+ alchemy_session.add(royal)
+ alias = alchemy.Alias(royal=royal, alias=royal.username.lower())
+ alchemy_session.add(alias)
+ alchemy_session.commit()
+ return f.redirect(f.url_for("login.login_index"))
diff --git a/royalnet/web/royalprints/newaccount/templates/newaccount_index.html b/royalnet/web/royalprints/newaccount/templates/newaccount_index.html
new file mode 100644
index 00000000..7d8e952b
--- /dev/null
+++ b/royalnet/web/royalprints/newaccount/templates/newaccount_index.html
@@ -0,0 +1,36 @@
+{% extends "base.html" %}
+
+{% block title %}
+ Nuovo account
+{% endblock %}
+
+{% block content %}
+
+
+
+
+ Nuovo account
+
+
+
+
+
+
+
+{% endblock %}
diff --git a/royalnet/web/royalprints/profile/templates/profile_index.html b/royalnet/web/royalprints/profile/templates/profile_index.html
index 83137d86..9ef02607 100644
--- a/royalnet/web/royalprints/profile/templates/profile_index.html
+++ b/royalnet/web/royalprints/profile/templates/profile_index.html
@@ -1,14 +1,14 @@
{% extends "base.html" %}
{% block title %}
- Indice RYGwiki
+ Elenco profili
{% endblock %}
{% block content %}
- Elenco Membri
+ Elenco profili
diff --git a/royalnet/web/royalprints/profile/templates/profile_page.html b/royalnet/web/royalprints/profile/templates/profile_page.html
index b9c549a8..b6d8ff65 100644
--- a/royalnet/web/royalprints/profile/templates/profile_page.html
+++ b/royalnet/web/royalprints/profile/templates/profile_page.html
@@ -1,7 +1,7 @@
{% extends "base.html" %}
{% block title %}
- {{ royal.username }} - Profilo RYG
+ Profilo: {{ royal.username }}
{% endblock %}
{% block content %}
diff --git a/royalnet/web/royalprints/tglogin/__init__.py b/royalnet/web/royalprints/tglogin/__init__.py
index 64fab63a..780a8ddf 100644
--- a/royalnet/web/royalprints/tglogin/__init__.py
+++ b/royalnet/web/royalprints/tglogin/__init__.py
@@ -47,4 +47,4 @@ def tglogin_done():
"role": royal_user.role
}
f.session["login_date"] = datetime.datetime.now()
- return f.render_template("tglogin_success.html")
+ return f.render_template("login_success.html")
diff --git a/royalnet/web/royalprints/tglogin/templates/tglogin_index.html b/royalnet/web/royalprints/tglogin/templates/tglogin_index.html
index 373d0ffc..b4a5ad24 100644
--- a/royalnet/web/royalprints/tglogin/templates/tglogin_index.html
+++ b/royalnet/web/royalprints/tglogin/templates/tglogin_index.html
@@ -1,7 +1,7 @@
{% extends "base.html" %}
{% block title %}
- Login with Telegram
+ Telegram Login
{% endblock %}
{% block content %}
diff --git a/royalnet/web/royalprints/tglogin/templates/tglogin_success.html b/royalnet/web/royalprints/tglogin/templates/tglogin_success.html
index 2f9590f0..1dba4f41 100644
--- a/royalnet/web/royalprints/tglogin/templates/tglogin_success.html
+++ b/royalnet/web/royalprints/tglogin/templates/tglogin_success.html
@@ -1,14 +1,14 @@
{% extends "base.html" %}
{% block title %}
- Login with Telegram
+ Telegram Login riuscito
{% endblock %}
{% block content %}
- Telegram login
+ Telegram Login
diff --git a/royalnet/web/royalprints/wikiedit/__init__.py b/royalnet/web/royalprints/wikiedit/__init__.py
index acaeea5c..3f1660e9 100644
--- a/royalnet/web/royalprints/wikiedit/__init__.py
+++ b/royalnet/web/royalprints/wikiedit/__init__.py
@@ -5,7 +5,7 @@ import os
import datetime
import difflib
from ...royalprint import Royalprint
-from ...shortcuts import error
+from ...shortcuts import error, from_urluuid
from ....database.tables import Royal, WikiPage, WikiRevision
@@ -41,17 +41,18 @@ def wikiedit_newpage():
alchemy_session.add(page)
alchemy_session.add(revision)
alchemy_session.commit()
- return f.redirect(f.url_for("wikiview.wikiview_by_id", page_id=page.page_id, title=page.title))
+ return f.redirect(f.url_for("wikiview.wikiview_by_id", page_id=page.page_short_id, title=page.title))
-@rp.route("/
", defaults={"title": ""}, methods=["GET", "POST"])
-@rp.route("//", methods=["GET", "POST"])
-def wikiedit_by_id(page_id: uuid.UUID, title: str):
+@rp.route("/", defaults={"title": ""}, methods=["GET", "POST"])
+@rp.route("//", methods=["GET", "POST"])
+def wikiedit_by_id(page_id: str, title: str):
+ page_uuid = from_urluuid(page_id)
if "royal" not in f.session:
return error(403, "Devi aver effettuato il login per modificare pagine wiki.")
alchemy, alchemy_session = f.current_app.config["ALCHEMY"], f.current_app.config["ALCHEMY_SESSION"]
- page = alchemy_session.query(alchemy.WikiPage).filter(alchemy.WikiPage.page_id == page_id).one_or_none()
+ page = alchemy_session.query(alchemy.WikiPage).filter(alchemy.WikiPage.page_id == page_uuid).one_or_none()
if page is None:
return error(404, "La pagina che stai cercando di modificare non esiste.")
@@ -75,4 +76,4 @@ def wikiedit_by_id(page_id: uuid.UUID, title: str):
page.title = fd["title"]
page.css = fd["css"] if fd["css"] != "None" else None
alchemy_session.commit()
- return f.redirect(f.url_for("wikiview.wikiview_by_id", page_id=page.page_id, title=page.title))
+ return f.redirect(f.url_for("wikiview.wikiview_by_id", page_id=page.page_short_id, title=page.title))
diff --git a/royalnet/web/royalprints/wikiedit/templates/wikiedit_page.html b/royalnet/web/royalprints/wikiedit/templates/wikiedit_page.html
index b612d07f..90023d28 100644
--- a/royalnet/web/royalprints/wikiedit/templates/wikiedit_page.html
+++ b/royalnet/web/royalprints/wikiedit/templates/wikiedit_page.html
@@ -17,14 +17,14 @@