Skip to content
Snippets Groups Projects
Verified Commit 7ad681e7 authored by ornanovitch's avatar ornanovitch
Browse files

Merge branch 'master' into 2-design

parents 93477939 4bfa51f0
No related branches found
No related tags found
No related merge requests found
......@@ -2,6 +2,7 @@ from hiboo import models, utils, security
from hiboo.account import blueprint, forms
from flask_babel import lazy_gettext as _
from flask import session
from authlib.jose import JsonWebToken
import datetime
import flask_login
......@@ -32,6 +33,20 @@ def signout():
@blueprint.route("/signup", methods=["GET", "POST"])
def signup():
if not flask.current_app.config['OPEN_SIGNUP']:
token = flask.request.args.get('token') or flask.abort(403)
key = flask.current_app.config["SECRET_KEY"]
jwt = JsonWebToken(['HS512'])
claims_options = {
'exp': {'essential': True, 'value': datetime.datetime.now().timestamp()},
'aud': {'essential': True, 'value': flask.url_for('.signup')}
}
try:
claims = jwt.decode(token, key, claims_options=claims_options)
claims.validate()
except Exception as e:
flask.flash(_("Invalid or expired signup link"), "danger")
return flask.redirect(flask.url_for(".signin"))
form = forms.SignupForm()
if form.validate_on_submit():
conflict = models.User.query.filter_by(username=form.username.data).first()
......@@ -72,4 +87,4 @@ def reset(token_uuid):
models.db.session.commit()
flask.flash(_("Successfully reset your password"), "success")
return flask.redirect(flask.url_for(".signin"))
return flask.render_template("account_reset.html", form=form)
\ No newline at end of file
return flask.render_template("account_reset.html", form=form)
......@@ -43,8 +43,8 @@ class SynapseApplication(base.SAMLApplication):
def configure(self, form):
return {
"acs": form.application_uri.data + "/_matrix/saml2/authn_response",
"entityid": form.application_uri.data + "/_matrix/saml2/metadata.xml",
"acs": form.application_uri.data + "/_synapse/client/saml2/authn_response",
"entityid": form.application_uri.data + "/_synapse/client/saml2/metadata.xml",
"sign_mode": "response"
}
......
......@@ -6,10 +6,10 @@
<dd><pre>{{ url_for("sso.oidc_discovery", service_uuid=service.uuid, _external=True) }}</pre></dd>
<dt>Client ID</dt>
<dd><pre>service.config["client_id"]</pre></dd>
<dd><pre>{{ service.config["client_id"] }}</pre></dd>
<dt>Client secret</dt>
<dd><pre>service.config["client_secret"]</pre></dd>
<dd><pre>{{ service.config["client_secret"] }}</pre></dd>
<dt>Scope</dt>
<dd><pre>openid email profile</pre></dd>
......@@ -20,4 +20,4 @@
<dt>Email property</dt>
<dd><pre>email</pre></dd>
{% include "application_oidc.html" %}
\ No newline at end of file
{% include "application_oidc.html" %}
from flask import cli
from hiboo import models
from hiboo.profile import common
import time
tasks = cli.AppGroup("tasks")
......@@ -19,3 +22,10 @@ def tasks_loop():
while True:
common.apply_all_transitions()
time.sleep(30)
@tasks.command("purge")
def purge():
# Temporary command to list purgeable accounts before we include
# this in the main task loop
print(models.User.get_unused().all())
......@@ -14,6 +14,7 @@ DEFAULT_CONFIG = {
'TEMPLATES_AUTO_RELOAD': False,
'MAIL_DOMAIN': 'tedomum.net',
'WEBSITE_NAME': 'Hiboo',
'OPEN_SIGNUP': True,
'API_TOKEN': 'changeMe'
}
......
......@@ -114,6 +114,17 @@ class User(db.Model):
profile.status = Profile.ACTIVE
return profile
@classmethod
def get_unused(cls, interval=datetime.timedelta(hours=2)):
return (cls.query
.join(cls.profiles.and_(Profile.status != Profile.PURGED), isouter=True)
.filter(Profile.uuid == None)
.filter(
datetime.datetime.now() - interval >
sqlalchemy.sql.func.coalesce(cls.updated_at, cls.created_at)
)
)
class Auth(db.Model):
""" An authenticator is a method to authenticate a user.
......
......@@ -24,3 +24,7 @@
</div>
</div>
{% endblock %}
{% block actions %}
<a href="{{ url_for(".invite") }}" class="btn btn-primary">{% trans %}Sign-up link{% endtrans %}</a>
{% endblock %}
from hiboo.user import blueprint, forms
from hiboo import models, utils, security
from flask_babel import lazy_gettext as _
from authlib.jose import jwt
import datetime
import flask
......@@ -39,4 +40,21 @@ def password_reset(user_uuid):
models.db.session.commit()
reset_link = flask.url_for("account.reset", token_uuid=token.uuid, _external=True)
flask.flash(_("Reset link: {}").format(reset_link), "success")
return flask.redirect(flask.url_for(".details", user_uuid=user.uuid))
\ No newline at end of file
return flask.redirect(flask.url_for(".details", user_uuid=user.uuid))
@blueprint.route("/invite", methods=["GET", "POST"])
@security.admin_required()
@security.confirmation_required("generate a signup link")
def invite():
expired = datetime.datetime.now() + datetime.timedelta(days=1)
payload = {
"exp": int(expired.timestamp()),
"aud": flask.url_for('account.signup')
}
header = {"alg": "HS512"}
key = flask.current_app.config["SECRET_KEY"]
token = jwt.encode(header, payload, key)
signup_link = flask.url_for("account.signup", token=token, _external=True)
flask.flash(_("Signup link: {}").format(signup_link), "success")
return flask.redirect(flask.url_for("user.list"))
alembic==1.4.2
alembic==1.6.5
argon2-cffi==20.1.0
astroid==2.4.2
Authlib==0.14.1
Babel==2.8.0
Authlib==0.15.4
axon @ git+https://forge.tedomum.net/tedomum/axon.git@5980a68da60c8de3fb7cbc8402a0f3db84bc3693
Babel==2.9.1
bcrypt==3.2.0
blinker==1.4
certifi==2020.4.5.1
cffi==1.14.0
chardet==3.0.4
certifi==2021.5.30
cffi==1.14.6
charset-normalizer==2.0.3
click==7.1.2
cryptography==3.1.1
decorator==4.4.2
defusedxml==0.6.0
dnspython==1.16.0
email-validator==1.1.0
Flask==1.1.2
cryptography==3.4.7
decorator==5.0.9
defusedxml==0.7.1
Deprecated==1.2.12
dnspython==2.1.0
elementpath==2.2.3
email-validator==1.1.3
Flask==1.1.4
Flask-Babel==2.0.0
Flask-DebugToolbar==0.11.0
Flask-Limiter==1.4
Flask-Login==0.5.0
Flask-Migrate==2.5.3
Flask-Migrate==3.0.1
flask-redis==0.4.0
Flask-Script==2.0.6
Flask-SQLAlchemy==2.4.4
Flask-WTF==0.14.3
gunicorn==20.0.4
idna==2.9
infinity==1.4
intervals==0.8.1
isort==4.3.21
Flask-SQLAlchemy==2.5.1
Flask-WTF==0.15.1
greenlet==1.1.0
gunicorn==20.1.0
idna==3.2
importlib-resources==5.2.0
infinity==1.5
intervals==0.9.2
itsdangerous==1.1.0
Jinja2==2.11.2
jwcrypto==0.8
lazy-object-proxy==1.4.3
Jinja2==2.11.3
jwcrypto==0.9.1
limits==1.5.1
lxml==4.5.0
Mako==1.1.2
MarkupSafe==1.1.1
mccabe==0.6.1
mysqlclient==2.0.1
lxml==4.6.3
Mako==1.1.4
MarkupSafe==2.0.1
mysqlclient==2.0.3
passlib==1.7.4
Pillow==7.1.2
pkgconfig==1.5.1
psycopg2==2.8.6
Pillow==8.3.1
psycopg2==2.9.1
pycparser==2.20
pylint==2.5.3
pyOpenSSL==19.1.0
pysaml2==6.2.0
python-dateutil==2.8.1
pyOpenSSL==20.0.1
pysaml2==7.0.1
python-dateutil==2.8.2
python-editor==1.0.4
pytz==2020.1
PyYAML==5.3.1
redis==3.5.0
requests==2.23.0
six==1.14.0
SQLAlchemy==1.3.16
pytz==2021.1
PyYAML==5.4.1
redis==3.5.3
requests==2.26.0
six==1.16.0
SQLAlchemy==1.4.22
terminaltables==3.1.0
toml==0.10.1
urllib3==1.25.9
validators==0.14.3
urllib3==1.26.6
validators==0.18.2
Werkzeug==0.16.0
wrapt==1.12.1
WTForms==2.3.1
WTForms-Components==0.10.4
xmlsec==1.3.8
git+https://forge.tedomum.net/tedomum/axon.git
WTForms==2.3.3
WTForms-Components==0.10.5
xmlschema==1.6.4
xmlsec==1.3.11
zipp==3.5.0
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment