2021-05-29 18:22:51 +02:00
|
|
|
# -*- coding: UTF-8 -*
|
|
|
|
|
|
|
|
|
|
|
|
"""Application Flask: ScoDoc
|
|
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
2021-08-10 09:30:08 +02:00
|
|
|
|
2021-05-29 18:22:51 +02:00
|
|
|
from __future__ import print_function
|
|
|
|
|
2021-06-24 10:59:03 +02:00
|
|
|
import os
|
2021-05-29 18:22:51 +02:00
|
|
|
from pprint import pprint as pp
|
2021-05-31 09:57:23 +02:00
|
|
|
import sys
|
2021-05-29 18:22:51 +02:00
|
|
|
|
|
|
|
import click
|
|
|
|
import flask
|
2021-06-24 10:59:03 +02:00
|
|
|
from flask.cli import with_appcontext
|
2021-05-29 18:22:51 +02:00
|
|
|
from app import create_app, cli, db
|
2021-06-24 10:59:03 +02:00
|
|
|
|
2021-05-29 18:22:51 +02:00
|
|
|
from app.auth.models import User, Role, UserRole
|
2021-06-14 18:08:52 +02:00
|
|
|
from app.views import notes, scolar, absences
|
2021-07-05 00:07:17 +02:00
|
|
|
import app.utils as utils
|
2021-05-29 18:22:51 +02:00
|
|
|
|
|
|
|
from config import Config
|
|
|
|
|
|
|
|
app = create_app()
|
|
|
|
cli.register(app)
|
|
|
|
|
|
|
|
|
|
|
|
@app.shell_context_processor
|
|
|
|
def make_shell_context():
|
2021-07-25 22:31:59 +02:00
|
|
|
from app.scodoc import notesdb as ndb
|
2021-07-29 10:19:00 +02:00
|
|
|
from app.scodoc import sco_utils as scu
|
2021-08-01 09:52:28 +02:00
|
|
|
from flask_login import login_user, logout_user, current_user
|
|
|
|
|
|
|
|
admin_role = Role.query.filter_by(name="SuperAdmin").first()
|
|
|
|
admin = (
|
|
|
|
User.query.join(UserRole)
|
|
|
|
.filter((UserRole.user_id == User.id) & (UserRole.role_id == admin_role.id))
|
|
|
|
.first()
|
|
|
|
)
|
2021-07-25 22:31:59 +02:00
|
|
|
|
2021-05-29 18:22:51 +02:00
|
|
|
return {
|
|
|
|
"db": db,
|
|
|
|
"User": User,
|
|
|
|
"Role": Role,
|
|
|
|
"UserRole": UserRole,
|
2021-06-14 18:08:52 +02:00
|
|
|
"notes": notes,
|
|
|
|
"scolar": scolar,
|
2021-07-25 22:31:59 +02:00
|
|
|
"ndb": ndb,
|
2021-07-29 10:19:00 +02:00
|
|
|
"scu": scu,
|
2021-05-29 18:22:51 +02:00
|
|
|
"pp": pp,
|
|
|
|
"flask": flask,
|
|
|
|
"current_app": flask.current_app,
|
2021-08-01 09:52:28 +02:00
|
|
|
"current_user": current_user,
|
|
|
|
"login_user": login_user,
|
|
|
|
"logout_user": logout_user,
|
|
|
|
"admin": admin,
|
|
|
|
"ctx": app.test_request_context(),
|
2021-05-29 18:22:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-08-01 09:52:28 +02:00
|
|
|
# ctx.push()
|
|
|
|
# login_user(admin)
|
|
|
|
|
|
|
|
|
2021-05-29 18:22:51 +02:00
|
|
|
@app.cli.command()
|
2021-07-05 00:07:17 +02:00
|
|
|
def user_db_init(): # user-db-init
|
2021-05-29 18:22:51 +02:00
|
|
|
"""Initialize the users database."""
|
|
|
|
click.echo("Init the db")
|
|
|
|
# Create roles:
|
|
|
|
Role.insert_roles()
|
|
|
|
click.echo("created initial roles")
|
|
|
|
# Ensure that admin exists
|
|
|
|
if Config.SCODOC_ADMIN_MAIL:
|
2021-06-26 21:57:54 +02:00
|
|
|
admin_user_name = Config.SCODOC_ADMIN_LOGIN
|
|
|
|
user = User.query.filter_by(user_name=admin_user_name).first()
|
2021-05-29 18:22:51 +02:00
|
|
|
if not user:
|
2021-06-26 21:57:54 +02:00
|
|
|
user = User(user_name=admin_user_name, email=Config.SCODOC_ADMIN_MAIL)
|
2021-05-29 18:22:51 +02:00
|
|
|
db.session.add(user)
|
|
|
|
db.session.commit()
|
|
|
|
click.echo(
|
2021-06-26 21:57:54 +02:00
|
|
|
"created initial admin user, login: {u.user_name}, email: {u.email}".format(
|
2021-05-29 18:22:51 +02:00
|
|
|
u=user
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@app.cli.command()
|
2021-05-31 09:57:23 +02:00
|
|
|
def user_db_clear():
|
2021-05-29 18:22:51 +02:00
|
|
|
"""Erase (drop) all tables of users database !"""
|
2021-05-31 09:57:23 +02:00
|
|
|
click.echo("Erasing the users database !")
|
|
|
|
_clear_users_db()
|
2021-05-29 18:22:51 +02:00
|
|
|
|
|
|
|
|
2021-05-31 09:57:23 +02:00
|
|
|
def _clear_users_db():
|
2021-05-29 18:22:51 +02:00
|
|
|
"""Erase (drop) all tables of users database !"""
|
2021-05-31 09:57:23 +02:00
|
|
|
click.confirm("This will erase all users.\nDo you want to continue?", abort=True)
|
2021-05-29 18:22:51 +02:00
|
|
|
db.reflect()
|
|
|
|
db.drop_all()
|
|
|
|
db.session.commit()
|
2021-05-31 09:57:23 +02:00
|
|
|
|
|
|
|
|
|
|
|
@app.cli.command()
|
|
|
|
@click.argument("username")
|
|
|
|
@click.argument("role")
|
|
|
|
@click.argument("dept")
|
2021-07-05 21:56:28 +02:00
|
|
|
def user_create(username, role, dept): # user-create
|
2021-05-31 09:57:23 +02:00
|
|
|
"Create a new user"
|
|
|
|
r = Role.get_named_role(role)
|
|
|
|
if not r:
|
2021-07-05 21:56:28 +02:00
|
|
|
sys.stderr.write("user_create: role {r} does not exists\n".format(r=role))
|
2021-05-31 09:57:23 +02:00
|
|
|
return 1
|
2021-06-26 21:57:54 +02:00
|
|
|
u = User.query.filter_by(user_name=username).first()
|
2021-05-31 09:57:23 +02:00
|
|
|
if u:
|
2021-07-05 21:56:28 +02:00
|
|
|
sys.stderr.write("user_create: user {u} already exists\n".format(u=u))
|
2021-05-31 09:57:23 +02:00
|
|
|
return 2
|
2021-07-05 21:56:28 +02:00
|
|
|
if dept == "@all":
|
|
|
|
dept = None
|
2021-06-26 21:57:54 +02:00
|
|
|
u = User(user_name=username, dept=dept)
|
2021-05-31 09:57:23 +02:00
|
|
|
u.add_role(r, dept)
|
|
|
|
db.session.add(u)
|
|
|
|
db.session.commit()
|
|
|
|
click.echo(
|
2021-06-26 21:57:54 +02:00
|
|
|
"created user, login: {u.user_name}, with role {r} in dept. {dept}".format(
|
2021-05-31 09:57:23 +02:00
|
|
|
u=u, r=r, dept=dept
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@app.cli.command()
|
|
|
|
@click.argument("username")
|
|
|
|
@click.password_option()
|
2021-07-05 21:56:28 +02:00
|
|
|
def user_password(username, password=None): # user-password
|
2021-05-31 09:57:23 +02:00
|
|
|
"Set (or change) user's password"
|
|
|
|
if not password:
|
|
|
|
sys.stderr.write("user_password: missing password")
|
|
|
|
return 1
|
2021-06-26 21:57:54 +02:00
|
|
|
u = User.query.filter_by(user_name=username).first()
|
2021-05-31 09:57:23 +02:00
|
|
|
if not u:
|
|
|
|
sys.stderr.write("user_password: user {} does not exists".format(username))
|
|
|
|
return 1
|
|
|
|
|
|
|
|
u.set_password(password)
|
|
|
|
db.session.add(u)
|
|
|
|
db.session.commit()
|
|
|
|
click.echo("changed password for user {}".format(u))
|
2021-06-24 10:59:03 +02:00
|
|
|
|
|
|
|
|
|
|
|
@app.cli.command()
|
|
|
|
@click.argument("dept")
|
2021-07-30 09:36:30 +02:00
|
|
|
def sco_delete_dept(dept): # sco-delete-dept
|
2021-06-24 10:59:03 +02:00
|
|
|
"Delete existing departement"
|
2021-08-07 08:42:57 +02:00
|
|
|
if os.system('tools/delete_dept.sh -n "{}"'.format(dept)):
|
2021-06-24 10:59:03 +02:00
|
|
|
sys.stderr.write("error deleting dept " + dept)
|
|
|
|
return 1
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
|
@app.cli.command()
|
|
|
|
@click.argument("dept")
|
2021-07-30 09:36:30 +02:00
|
|
|
def sco_create_dept(dept): # sco-create-dept
|
2021-06-24 10:59:03 +02:00
|
|
|
"Create new departement"
|
2021-08-07 08:42:57 +02:00
|
|
|
if os.system(f'tools/create_dept.sh -n "{dept}"'):
|
2021-07-30 09:36:30 +02:00
|
|
|
sys.stderr.write(f"error creating dept {dept}\n")
|
2021-06-24 10:59:03 +02:00
|
|
|
return 1
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
|
@app.cli.command()
|
|
|
|
@click.argument("filename")
|
|
|
|
@with_appcontext
|
|
|
|
def test_interactive(filename=None):
|
|
|
|
"Run interactive test"
|
|
|
|
import flask_login
|
|
|
|
from app import decorators
|
|
|
|
|
|
|
|
click.echo("Executing {}".format(filename))
|
|
|
|
with app.test_request_context(""):
|
|
|
|
u = User.query.first()
|
|
|
|
flask_login.login_user(u)
|
|
|
|
REQUEST = decorators.ZRequest()
|
|
|
|
exec(open(filename).read())
|
|
|
|
|
|
|
|
click.echo("Done.")
|
2021-07-05 00:07:17 +02:00
|
|
|
|
|
|
|
|
|
|
|
@app.cli.command()
|
|
|
|
@with_appcontext
|
|
|
|
def user_db_import_scodoc7(): # user-db-import-scodoc7
|
|
|
|
"""Import used defined in ScoDoc7 postgresql database into ScoDoc8
|
|
|
|
The old database SCOUSERS must be alive and readable by the current user.
|
2021-07-27 16:07:03 +02:00
|
|
|
This script is typically run as unix user "scodoc".
|
|
|
|
The original SCOUSERS database is left unmodified.
|
2021-07-05 00:07:17 +02:00
|
|
|
"""
|
|
|
|
utils.import_scodoc7_user_db()
|
2021-07-29 10:30:13 +02:00
|
|
|
|
|
|
|
|
|
|
|
@app.cli.command()
|
|
|
|
@with_appcontext
|
|
|
|
def clear_cache(): # clear-cache
|
|
|
|
"""Clear ScoDoc cache
|
|
|
|
This cache (currently Redis) is persistent between invocation
|
|
|
|
and it may be necessary to clear it during developement or tests.
|
|
|
|
"""
|
|
|
|
# attaque directement redis, court-circuite ScoDoc:
|
|
|
|
import redis
|
|
|
|
|
|
|
|
r = redis.Redis()
|
|
|
|
r.flushall()
|
|
|
|
click.echo("Redis caches flushed.")
|