Skip to content
Snippets Groups Projects
Commit fd3b7048 authored by kaiyou's avatar kaiyou
Browse files

Merge branch '110-update-python-deps' into 'main'

Resolve "Mise à jour des dépendences python"

Closes #110

See merge request !76
parents b15e0cfb dd1c88d6
No related branches found
No related tags found
No related merge requests found
...@@ -67,29 +67,33 @@ class ImageCaptchaField(fields.CaptchaField): ...@@ -67,29 +67,33 @@ class ImageCaptchaField(fields.CaptchaField):
'<p><img src="data:image/png;base64,{}"></p>'.format(output) '<p><img src="data:image/png;base64,{}"></p>'.format(output)
) + super(ImageCaptchaField, self).__call__(**kwargs) ) + super(ImageCaptchaField, self).__call__(**kwargs)
def get_size(self, text, scale=(1, 1)):
left, top, right, bottom = self.font.getbbox(text)
sx, sy = scale
return (int(sx * (right-left)), int(sy * (bottom-top)))
def make_char(self, char, rotation_range=15): def make_char(self, char, rotation_range=15):
""" Renders a character """ Renders a character
""" """
drawn = " {} ".format(char) drawn = " {} ".format(char)
rotation = random.randrange(-rotation_range, rotation_range) rotation = random.randrange(-rotation_range, rotation_range)
image = Image.new("L", self.font.getsize(drawn), self.bgcolor) bbox = self.font.getbbox(drawn)
image = Image.new("L", self.get_size(drawn, (2, 2)), self.bgcolor)
draw = ImageDraw.Draw(image) draw = ImageDraw.Draw(image)
draw.text((0, 0), drawn, font=self.font, fill=self.fgcolor) draw.text((0, 0), drawn, font=self.font, fill=self.fgcolor)
return image.rotate(rotation, expand=0, resample=Image.BICUBIC) \ return image.rotate(rotation, expand=True, fillcolor=self.bgcolor, resample=Image.BICUBIC)
.crop(image.getbbox())
def make_text(self, text, **kwargs): def make_text(self, text, **kwargs):
""" Renders a text """ Renders a text
""" """
size = self.font.getsize(text) size = self.get_size(text, (4, 3))
size = (size[0] * 2, int(size[1] * 1.433))
image = Image.new("RGB", size, self.bgcolor) image = Image.new("RGB", size, self.bgcolor)
xpos = 2 xpos = 2
for char in text: for char in text:
charimage = self.make_char(char) charimage = self.make_char(char)
image.paste(charimage, (xpos, 4, xpos + charimage.size[0], 4 + charimage.size[1])) image.paste(charimage, (xpos, 4, xpos + charimage.size[0], 4 + charimage.size[1]))
xpos = xpos + 2 + charimage.size[0] xpos = xpos + 2 + charimage.size[0]
return image.crop((0, 0, xpos + 1, size[1])) return image
def make_image(self, challenge): def make_image(self, challenge):
pass pass
......
from passlib import context, hash from passlib import context, hash
from flask import current_app as app from flask import current_app as app
from sqlalchemy.ext import declarative, mutable from sqlalchemy import orm, types, schema, sql
from sqlalchemy.orm.collections import attribute_mapped_collection from sqlalchemy.ext import mutable
from flask_babel import lazy_gettext as _ from flask_babel import lazy_gettext as _
from hiboo import actions from hiboo import actions
import flask_sqlalchemy import flask_sqlalchemy
import flask_babel
import sqlalchemy
import datetime import datetime
import json import json
import uuid import uuid
...@@ -30,32 +28,32 @@ def log(category, value=None, comment=None, user=None, profile=None, ...@@ -30,32 +28,32 @@ def log(category, value=None, comment=None, user=None, profile=None,
db.session.add(event) db.session.add(event)
class Base(flask_sqlalchemy.Model): class Base(orm.DeclarativeBase):
""" Base class for all models """ Base class for all models
""" """
metadata = sqlalchemy.schema.MetaData( metadata = schema.MetaData(
naming_convention={ naming_convention={
"fk": "%(table_name)s_%(column_0_name)s_fkey", "fk": "%(table_name)s_%(column_0_name)s_fkey",
"pk": "%(table_name)s_pkey" "pk": "%(table_name)s_pkey"
} }
) )
@declarative.declared_attr @orm.declared_attr
def uuid(cls): def uuid(cls):
return sqlalchemy.Column(sqlalchemy.String(36), primary_key=True, return schema.Column(types.String(36), primary_key=True,
default=lambda: str(uuid.uuid4())) default=lambda: str(uuid.uuid4()))
@declarative.declared_attr @orm.declared_attr
def created_at(cls): def created_at(cls):
return sqlalchemy.Column(sqlalchemy.DateTime, nullable=False, default=datetime.datetime.now) return schema.Column(types.DateTime, nullable=False, default=datetime.datetime.now)
@declarative.declared_attr @orm.declared_attr
def updated_at(cls): def updated_at(cls):
return sqlalchemy.Column(sqlalchemy.DateTime, nullable=True, onupdate=datetime.datetime.now) return schema.Column(types.DateTime, nullable=True, onupdate=datetime.datetime.now)
@declarative.declared_attr @orm.declared_attr
def comment(cls): def comment(cls):
return sqlalchemy.Column(sqlalchemy.String(255), nullable=True) return schema.Column(types.String(255), nullable=True)
db = flask_sqlalchemy.SQLAlchemy(model_class=Base) db = flask_sqlalchemy.SQLAlchemy(model_class=Base)
...@@ -143,7 +141,7 @@ class User(db.Model): ...@@ -143,7 +141,7 @@ class User(db.Model):
.filter(Profile.uuid == None) .filter(Profile.uuid == None)
.filter( .filter(
cls.get_timeout() > cls.get_timeout() >
sqlalchemy.sql.func.coalesce(cls.updated_at, cls.created_at) sql.func.coalesce(cls.updated_at, cls.created_at)
)) ))
for user in unused.all(): for user in unused.all():
print("Deleting user {}".format(user.username)) print("Deleting user {}".format(user.username))
...@@ -173,7 +171,7 @@ class Auth(db.Model): ...@@ -173,7 +171,7 @@ class Auth(db.Model):
user_uuid = db.Column(db.String(36), db.ForeignKey(User.uuid)) user_uuid = db.Column(db.String(36), db.ForeignKey(User.uuid))
user = db.relationship(User, user = db.relationship(User,
backref=db.backref('auths', backref=db.backref('auths',
collection_class=attribute_mapped_collection('realm'), collection_class=orm.attribute_mapped_collection('realm'),
cascade='all, delete-orphan')) cascade='all, delete-orphan'))
value = db.Column(db.String) value = db.Column(db.String)
extra = db.Column(mutable.MutableDict.as_mutable(JSONEncoded)) extra = db.Column(mutable.MutableDict.as_mutable(JSONEncoded))
...@@ -320,9 +318,9 @@ class Profile(db.Model): ...@@ -320,9 +318,9 @@ class Profile(db.Model):
@classmethod @classmethod
def transition_ready(cls): def transition_ready(cls):
return cls.query.filter(sqlalchemy.or_( return cls.query.filter(sql.expression.or_(
cls.transition_step.in_ ([cls.START, cls.DONE]), cls.transition_step.in_ ([cls.START, cls.DONE]),
sqlalchemy.and_( sql.expression.and_(
cls.transition_step == cls.INIT, cls.transition_step == cls.INIT,
datetime.datetime.now() > cls.transition_time datetime.datetime.now() > cls.transition_time
) )
......
...@@ -81,15 +81,13 @@ limiter = flask_limiter.Limiter(key_func=lambda: current_user.id) ...@@ -81,15 +81,13 @@ limiter = flask_limiter.Limiter(key_func=lambda: current_user.id)
# Application translation # Application translation
translation = flask_babel.Babel()
@translation.localeselector
def get_locale(): def get_locale():
return babel.negotiate_locale( return babel.negotiate_locale(
[l.replace('-', '_') for l in flask.request.accept_languages.values()], [l.replace('-', '_') for l in flask.request.accept_languages.values()],
list(map(str, translation.list_translations())) list(map(str, translation.list_translations()))
) )
translation = flask_babel.Babel(locale_selector=get_locale)
# Data migrate # Data migrate
migrate = flask_migrate.Migrate() migrate = flask_migrate.Migrate()
......
Source diff could not be displayed: it is too large. Options to address this: view the blob.
...@@ -27,31 +27,31 @@ authors = [ ...@@ -27,31 +27,31 @@ authors = [
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.9" python = "^3.9"
Flask = "^2.2.3" Flask = "^3.0.1"
Flask-Login = "^0.6.2" Flask-Login = "^0.6.2"
Flask-SQLAlchemy = "^2.5.1" Flask-SQLAlchemy = "^3.1.1"
flask-babel = "^2.0.0" flask-babel = "^4.0.0"
Flask-Migrate = "^3.1.0" Flask-Migrate = "^4.0.5"
Flask-WTF = "^1.1.1" Flask-WTF = "^1.2.1"
Flask-Limiter = "^2.5.0" Flask-Limiter = "^3.5.0"
flask-redis = "^0.4.0" flask-redis = "^0.4.0"
Flask-DebugToolbar = "^0.13.1" Flask-DebugToolbar = "^0.14.1"
SQLAlchemy = "^1.4.0" SQLAlchemy = "^2.0.25"
WTForms-Components = "^0.10.5" WTForms-Components = "^0.10.5"
passlib = "^1.7.4" passlib = "^1.7.4"
PyYAML = "^6.0" PyYAML = "^6.0.1"
bcrypt = "^3.2.2" bcrypt = "^4.1.2"
pysaml2 = "^7.4.1" pysaml2 = "^7.5.0"
xmlsec = "^1.3.13" xmlsec = "^1.3.13"
cryptography = "^37.0.4" cryptography = "^42.0.2"
Authlib = "^1.2.0" Authlib = "^1.3.0"
terminaltables = "^3.1.10" terminaltables = "^3.1.10"
Werkzeug = "^2.2.3" Werkzeug = "^3.0.1"
email-validator = "^1.3.1" email-validator = "^2.1.0.post1"
pyotp = "^2.8.0" pyotp = "^2.9.0"
qrcode = "^7.4.2" qrcode = "^7.4.2"
jwcrypto = "^1.4.2" jwcrypto = "^1.5.1"
Pillow = "^9.5.0" Pillow = "^10.2.0"
[tool.poetry.group.dev] [tool.poetry.group.dev]
optional = true optional = true
......
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