2021-03-24 10:05:36 +00:00
|
|
|
import logging
|
2020-10-23 08:07:14 +00:00
|
|
|
import os
|
2021-05-24 08:15:54 +00:00
|
|
|
import re
|
2021-02-19 18:03:01 +00:00
|
|
|
import configparser
|
2020-10-23 08:07:14 +00:00
|
|
|
from pathlib import Path
|
2021-05-05 12:26:26 +00:00
|
|
|
from werkzeug.security import check_password_hash
|
2020-10-23 08:07:14 +00:00
|
|
|
|
2021-08-22 17:07:19 +00:00
|
|
|
from flask import Flask, render_template, request, redirect, flash, safe_join, send_file, jsonify, url_for
|
2020-10-23 08:07:14 +00:00
|
|
|
from flask_dropzone import Dropzone
|
2021-03-24 10:05:36 +00:00
|
|
|
from flask_migrate import Migrate, MigrateCommand
|
|
|
|
from flask_script import Manager
|
2021-06-08 06:00:18 +00:00
|
|
|
from flask_login import LoginManager, login_required, login_user, current_user, logout_user
|
2021-05-05 12:26:26 +00:00
|
|
|
from portal.model import db, RegisteredUser
|
2020-10-23 08:07:14 +00:00
|
|
|
|
2021-03-10 17:55:24 +00:00
|
|
|
import portal.base
|
2021-05-05 12:26:26 +00:00
|
|
|
import portal.solar
|
2021-05-17 12:33:53 +00:00
|
|
|
import portal.regular
|
2021-02-19 18:03:01 +00:00
|
|
|
|
|
|
|
|
2021-05-05 12:26:26 +00:00
|
|
|
# TODO: Implement user registration.
|
|
|
|
# TODO: Integrate Shibboleth login.
|
|
|
|
|
2021-02-19 18:03:01 +00:00
|
|
|
|
2021-03-24 10:05:36 +00:00
|
|
|
|
|
|
|
# TODO: make logging level configurable
|
|
|
|
logging.basicConfig(level=logging.DEBUG, format='[APP LOGGER] %(asctime)s %(levelname)s: %(message)s')
|
|
|
|
|
2021-02-19 18:03:01 +00:00
|
|
|
######################
|
|
|
|
# Load configuration #
|
|
|
|
######################
|
|
|
|
config = configparser.ConfigParser()
|
|
|
|
config.read('config.ini')
|
|
|
|
config = config['DEFAULT']
|
|
|
|
|
|
|
|
MAIL_HOST = config['MAIL_HOST']
|
|
|
|
MAIL_LOGIN = config['MAIL_LOGIN']
|
|
|
|
MAIL_PASS = config['MAIL_PASS']
|
2021-05-05 12:26:26 +00:00
|
|
|
APP_SECRET_KEY = bytes.fromhex(config['APP_SECRET_KEY'])
|
2021-02-19 18:03:01 +00:00
|
|
|
SMTP_PORT = int(config['SMTP_PORT'])
|
|
|
|
IMAP_PORT = int(config['IMAP_PORT'])
|
|
|
|
MAX_UPLOAD_SIZE = int(config['MAX_UPLOAD_SIZE']) # Bytes
|
2021-03-24 10:05:36 +00:00
|
|
|
MAX_FILES_PER_UPLOAD = int(config['MAX_FILES_PER_UPLOAD'])
|
2021-02-19 18:03:01 +00:00
|
|
|
CONTRACT_CLIENT_CONTACT = config['CONTRACT_CLIENT_CONTACT']
|
2021-03-10 17:55:24 +00:00
|
|
|
MAIL_SUBJECT = config['MAIL_SUBJECT']
|
|
|
|
MAIL_BODY = config['MAIL_BODY']
|
2021-03-24 10:05:36 +00:00
|
|
|
SQL_CONN_STR = config['SQL_CONN_STR']
|
|
|
|
DESC_PREVODI = config['DESC_PREVODI']
|
|
|
|
DESC_GIGAFIDA = config['DESC_GIGAFIDA']
|
2021-03-10 17:55:24 +00:00
|
|
|
|
|
|
|
if 'UPLOADS_DIR' in config:
|
|
|
|
UPLOADS_DIR = Path(config['UPLOADS_DIR'])
|
|
|
|
else:
|
|
|
|
UPLOADS_DIR = Path(__file__).resolve().parent / 'uploads'
|
|
|
|
if not UPLOADS_DIR.exists:
|
|
|
|
UPLOADS_DIR.mkdir(parents=True)
|
|
|
|
|
2021-02-19 18:03:01 +00:00
|
|
|
# Override configs with environment variables, if set
|
|
|
|
if 'PORTALDS4DS1_MAIL_HOST' in os.environ:
|
2021-02-20 19:07:21 +00:00
|
|
|
MAIL_HOST = os.environ['PORTALDS4DS1_MAIL_HOST']
|
2021-02-19 18:03:01 +00:00
|
|
|
if 'PORTALDS4DS1_MAIL_LOGIN' in os.environ:
|
2021-02-20 19:07:21 +00:00
|
|
|
MAIL_LOGIN = os.environ['PORTALDS4DS1_MAIL_LOGIN']
|
2021-02-19 18:03:01 +00:00
|
|
|
if 'PORTALDS4DS1_MAIL_PASS' in os.environ:
|
2021-02-20 19:07:21 +00:00
|
|
|
MAIL_PASS = os.environ['PORTALDS4DS1_MAIL_PASS']
|
2021-05-05 12:26:26 +00:00
|
|
|
if 'PORTALDS4DS1_APP_SECRET_KEY' in os.environ:
|
|
|
|
APP_SECRET_KEY = bytes.fromhex(os.environ['PORTALDS4DS1_APP_SECRET_KEY'])
|
2021-02-19 18:03:01 +00:00
|
|
|
if 'PORTALDS4DS1_SMTP_PORT' in os.environ:
|
2021-02-20 19:07:21 +00:00
|
|
|
SMTP_PORT = int(os.environ['PORTALDS4DS1_SMTP_PORT'])
|
2021-02-19 18:03:01 +00:00
|
|
|
if 'PORTALDS4DS1_IMAP_PORT' in os.environ:
|
2021-02-20 19:07:21 +00:00
|
|
|
IMAP_PORT = int(os.environ['PORTALDS4DS1_IMAP_PORT'])
|
|
|
|
if 'PORTALDS4DS1_MAX_UPLOAD_SIZE' in os.environ:
|
|
|
|
MAX_UPLOAD_SIZE = int(os.environ['PORTALDS4DS1_MAX_UPLOAD_SIZE'])
|
2021-03-24 10:05:36 +00:00
|
|
|
if 'PORTALDS4DS1_MAX_FILES_PER_UPLOAD' in os.environ:
|
|
|
|
MAX_FILES_PER_UPLOAD = int(os.environ['PORTALDS4DS1_MAX_FILES_PER_UPLOAD'])
|
2021-02-20 19:07:21 +00:00
|
|
|
if 'PORTALDS4DS1_CONTRACT_CLIENT_CONTACT' in os.environ:
|
|
|
|
CONTRACT_CLIENT_CONTACT = os.environ['PORTALDS4DS1_CONTRACT_CLIENT_CONTACT']
|
2021-03-10 17:55:24 +00:00
|
|
|
if 'PORTALDS4DS1_UPLOADS_DIR' in os.environ:
|
|
|
|
UPLOADS_DIR = os.environ['PORTALDS4DS1_UPLOADS_DIR']
|
|
|
|
if 'PORTALDS4DS1_MAIL_SUBJECT' in os.environ:
|
|
|
|
MAIL_SUBJECT = os.environ['PORTALDS4DS1_MAIL_SUBJECT']
|
|
|
|
if 'PORTALDS4DS1_MAIL_BODY' in os.environ:
|
|
|
|
MAIL_BODY = os.environ['PORTALDS4DS1_MAIL_BODY']
|
2021-03-24 10:05:36 +00:00
|
|
|
if 'PORTALDS4DS1_SQL_CONN_STR' in os.environ:
|
|
|
|
SQL_CONN_STR = os.environ['PORTALDS4DS1_SQL_CONN_STR']
|
|
|
|
if 'PORTALDS4DS1_DESC_PREVODI' in os.environ:
|
|
|
|
DESC_PREVODI = os.environ['PORTALDS4DS1_DESC_PREVODI']
|
|
|
|
if 'PORTALDS4DS1_DESC_GIGAFIDA' in os.environ:
|
|
|
|
DESC_GIGAFIDA = os.environ['PORTALDS4DS1_DESC_GIGAFIDA']
|
2021-03-10 17:55:24 +00:00
|
|
|
|
2021-08-22 17:07:19 +00:00
|
|
|
ENABLED_CORPUSES = ['prevodi', 'gigafida', 'solar']
|
2021-05-17 12:33:53 +00:00
|
|
|
CORPUSES_LOGIN_REQUIRED = ['solar']
|
2021-02-19 18:03:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
######################
|
2020-10-23 08:07:14 +00:00
|
|
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
|
|
|
app.config.update(
|
2021-05-05 12:26:26 +00:00
|
|
|
SECRET_KEY = APP_SECRET_KEY,
|
2021-03-10 17:55:24 +00:00
|
|
|
UPLOADED_PATH = UPLOADS_DIR,
|
2021-02-19 18:03:01 +00:00
|
|
|
MAX_CONTENT_LENGTH = MAX_UPLOAD_SIZE,
|
2021-03-24 10:05:36 +00:00
|
|
|
TEMPLATES_AUTO_RELOAD = True,
|
|
|
|
SQLALCHEMY_DATABASE_URI = SQL_CONN_STR,
|
|
|
|
SQLALCHEMY_ECHO = True
|
2020-10-23 08:07:14 +00:00
|
|
|
)
|
2021-05-24 08:15:54 +00:00
|
|
|
app.url_map.strict_slashes = False
|
2020-10-23 08:07:14 +00:00
|
|
|
|
2021-03-24 10:05:36 +00:00
|
|
|
# Run "python app.py db -?" to see more info about DB migrations.
|
|
|
|
manager = Manager(app)
|
|
|
|
db.init_app(app)
|
|
|
|
migrate = Migrate(app, db)
|
|
|
|
manager.add_command('db', MigrateCommand)
|
|
|
|
|
|
|
|
# Set up dropzone.js to serve all the stuff for "file dropping" on the web interface.
|
2020-10-23 08:07:14 +00:00
|
|
|
dropzone = Dropzone(app)
|
|
|
|
|
2021-05-17 12:33:53 +00:00
|
|
|
upload_handler_regular = portal.regular.UploadHandlerRegular(
|
|
|
|
UPLOADS_DIR=UPLOADS_DIR,
|
|
|
|
MAIL_HOST=MAIL_HOST,
|
|
|
|
MAIL_LOGIN=MAIL_LOGIN,
|
|
|
|
MAIL_PASS=MAIL_PASS,
|
|
|
|
SMTP_PORT=SMTP_PORT,
|
|
|
|
IMAP_PORT=IMAP_PORT,
|
|
|
|
MAIL_SUBJECT=MAIL_SUBJECT,
|
|
|
|
MAIL_BODY=MAIL_BODY,
|
|
|
|
CONTRACT_CLIENT_CONTACT=CONTRACT_CLIENT_CONTACT,
|
|
|
|
MAX_FILES_PER_UPLOAD=MAX_FILES_PER_UPLOAD
|
|
|
|
)
|
|
|
|
|
|
|
|
upload_handler_solar = portal.solar.UploadHandlerSolar(
|
|
|
|
UPLOADS_DIR=UPLOADS_DIR,
|
|
|
|
MAIL_HOST=MAIL_HOST,
|
|
|
|
MAIL_LOGIN=MAIL_LOGIN,
|
|
|
|
MAIL_PASS=MAIL_PASS,
|
|
|
|
SMTP_PORT=SMTP_PORT,
|
|
|
|
IMAP_PORT=IMAP_PORT,
|
|
|
|
MAIL_SUBJECT=MAIL_SUBJECT,
|
|
|
|
MAIL_BODY=MAIL_BODY,
|
|
|
|
CONTRACT_CLIENT_CONTACT=CONTRACT_CLIENT_CONTACT,
|
|
|
|
MAX_FILES_PER_UPLOAD=MAX_FILES_PER_UPLOAD
|
|
|
|
)
|
|
|
|
|
2021-05-05 12:26:26 +00:00
|
|
|
|
|
|
|
# Use flask-login to manage user sessions where they are required.
|
|
|
|
login_manager = LoginManager(app)
|
|
|
|
login_manager.init_app(app)
|
|
|
|
|
|
|
|
|
2021-08-22 17:07:19 +00:00
|
|
|
def redirect_url(default='/'):
|
|
|
|
return request.args.get('next') or \
|
|
|
|
request.referrer or \
|
|
|
|
url_for(default)
|
|
|
|
|
|
|
|
|
2021-03-10 19:01:21 +00:00
|
|
|
@app.route('/')
|
2020-10-23 08:07:14 +00:00
|
|
|
def index():
|
|
|
|
return render_template('index.html')
|
|
|
|
|
|
|
|
|
2021-03-10 17:55:24 +00:00
|
|
|
@app.route('/<corpus_name>')
|
|
|
|
def index_corpus(corpus_name):
|
2021-05-17 12:33:53 +00:00
|
|
|
if corpus_name not in ENABLED_CORPUSES:
|
2021-03-10 17:55:24 +00:00
|
|
|
return 'Korpus "{}" ne obstaja.'.format(corpus_name), 404
|
2021-03-24 10:05:36 +00:00
|
|
|
|
2021-03-10 17:55:24 +00:00
|
|
|
if corpus_name == 'prevodi':
|
2021-03-24 10:05:36 +00:00
|
|
|
description = DESC_PREVODI
|
2021-03-10 17:55:24 +00:00
|
|
|
elif corpus_name == 'gigafida':
|
2021-03-24 10:05:36 +00:00
|
|
|
description = DESC_GIGAFIDA
|
|
|
|
elif corpus_name == 'solar':
|
2021-05-05 12:26:26 +00:00
|
|
|
if current_user.is_authenticated:
|
|
|
|
return redirect('/solar/oddaja')
|
|
|
|
return redirect('/solar/login')
|
2021-03-24 10:05:36 +00:00
|
|
|
|
|
|
|
return render_template('basic.html',
|
|
|
|
corpus_name=corpus_name, description=description, max_files=MAX_FILES_PER_UPLOAD)
|
|
|
|
|
|
|
|
|
2021-05-05 12:26:26 +00:00
|
|
|
@login_manager.user_loader
|
|
|
|
def load_user(user_id):
|
2021-06-08 06:00:18 +00:00
|
|
|
user = RegisteredUser.query.get(int(user_id))
|
|
|
|
return user
|
2021-03-24 10:05:36 +00:00
|
|
|
|
|
|
|
|
2021-05-24 08:15:54 +00:00
|
|
|
@app.route('/solar/login')
|
2021-08-22 17:07:19 +00:00
|
|
|
def solar_login_get():
|
|
|
|
return render_template('solar-login.html')
|
2021-03-10 17:55:24 +00:00
|
|
|
|
2021-03-24 10:05:36 +00:00
|
|
|
|
2021-08-22 17:07:19 +00:00
|
|
|
@app.route('/solar/register')
|
|
|
|
def solar_register_get():
|
|
|
|
return render_template('solar-register.html')
|
2021-05-17 12:33:53 +00:00
|
|
|
|
2021-08-22 17:07:19 +00:00
|
|
|
|
|
|
|
@app.route('/solar/login', methods=['POST'])
|
|
|
|
def solar_login_post():
|
2021-05-05 12:26:26 +00:00
|
|
|
email = request.form.get('email')
|
|
|
|
password = request.form.get('password')
|
|
|
|
remember = True if request.form.get('remember') else False
|
2020-10-23 08:07:14 +00:00
|
|
|
|
2021-05-05 12:26:26 +00:00
|
|
|
user = RegisteredUser.query.filter_by(email=email).first()
|
2020-10-23 08:07:14 +00:00
|
|
|
|
2021-05-05 12:26:26 +00:00
|
|
|
if not user or not check_password_hash(user.pass_hash, password):
|
|
|
|
flash('Napačni podatki za prijavo. Poskusite ponovno.')
|
2021-08-22 17:07:19 +00:00
|
|
|
return redirect('/solar/login')
|
2021-03-24 10:05:36 +00:00
|
|
|
|
2021-05-05 12:26:26 +00:00
|
|
|
if not user.active:
|
|
|
|
flash('Vaš uporabniški račun še ni bil aktiviran.')
|
2021-08-22 17:07:19 +00:00
|
|
|
return redirect('/solar/login')
|
2021-05-24 08:15:54 +00:00
|
|
|
|
2021-06-08 06:00:18 +00:00
|
|
|
#portal.base.add_user_session(user.id)
|
2021-05-05 12:26:26 +00:00
|
|
|
login_user(user, remember=remember)
|
2021-03-24 10:05:36 +00:00
|
|
|
|
2021-08-22 17:07:19 +00:00
|
|
|
return redirect('/solar/oddaja')
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/solar/register', methods=['POST'])
|
|
|
|
def solar_register_post():
|
|
|
|
name = request.form.get('name')
|
|
|
|
email = request.form.get('email')
|
|
|
|
password = request.form.get('password')
|
|
|
|
|
|
|
|
user = RegisteredUser.query.filter_by(email=email).first()
|
|
|
|
|
|
|
|
if user:
|
|
|
|
flash('Uporabniški račun s tem emailom je že registriran.')
|
|
|
|
return redirect('/solar/register')
|
|
|
|
|
|
|
|
if not name:
|
|
|
|
flash('Prazno polje za ime.')
|
|
|
|
return redirect('/solar/register')
|
|
|
|
if len(name) > 100:
|
|
|
|
flash('Predolgo ime.')
|
|
|
|
return redirect('/solar/register')
|
|
|
|
|
|
|
|
if not email:
|
|
|
|
flash('Prazno polje za elektronsko pošto.')
|
|
|
|
return redirect('/solar/register')
|
|
|
|
if len(email) > 100:
|
|
|
|
flash('Predolgi email naslov')
|
|
|
|
return redirect('/solar/register')
|
|
|
|
elif not re.search(portal.base.REGEX_EMAIL, email):
|
|
|
|
flash('Email napačnega formata.')
|
|
|
|
return redirect('/solar/register')
|
|
|
|
|
|
|
|
if not password:
|
|
|
|
flash('Prazno polje za geslo.')
|
|
|
|
return redirect('/solar/register')
|
|
|
|
if len(password) > 100:
|
|
|
|
flash('Predolgo geslo.')
|
|
|
|
return redirect('/solar/register')
|
|
|
|
|
|
|
|
portal.base.register_new_user(name, email, password, active=False)
|
|
|
|
|
|
|
|
flash('Uspešna registracija.')
|
|
|
|
return redirect('/solar/login')
|
|
|
|
|
2021-03-24 10:05:36 +00:00
|
|
|
|
|
|
|
|
2021-05-05 12:26:26 +00:00
|
|
|
# TODO: Move solar stuff to seperate file using Flask blueprints.
|
2021-05-24 08:15:54 +00:00
|
|
|
# TODO: Better routing logic.
|
2021-06-08 06:00:18 +00:00
|
|
|
|
|
|
|
@app.route('/solar/logout')
|
|
|
|
@login_required
|
|
|
|
def logout():
|
|
|
|
logout_user()
|
|
|
|
return redirect('/solar/login')
|
|
|
|
|
|
|
|
|
2021-05-24 08:15:54 +00:00
|
|
|
@app.route('/solar/<path:text>')
|
2021-05-17 12:33:53 +00:00
|
|
|
@login_required
|
2021-05-24 08:15:54 +00:00
|
|
|
def solar(text):
|
2021-08-22 17:07:19 +00:00
|
|
|
is_admin = current_user.role == 'admin'
|
|
|
|
current_user_institution = portal.base.get_user_institution(current_user.id)
|
|
|
|
if current_user_institution:
|
|
|
|
current_user_institution_moderator = portal.base.is_institution_moderator(current_user.id, current_user_institution.id)
|
|
|
|
else:
|
|
|
|
current_user_institution_moderator = False
|
|
|
|
|
2021-05-24 08:15:54 +00:00
|
|
|
if text.startswith('oddaja/') or text == 'oddaja':
|
2021-08-22 17:07:19 +00:00
|
|
|
return render_template('solar-oddaja.html', is_admin=is_admin, is_institution_moderator=current_user_institution_moderator)
|
2021-05-24 08:15:54 +00:00
|
|
|
elif text.startswith('zgodovina/') or text == 'zgodovina':
|
|
|
|
upload_items = portal.solar.get_upload_history(current_user.id)
|
|
|
|
uploader_names = []
|
|
|
|
institution_names = []
|
|
|
|
for item in upload_items:
|
|
|
|
uploader_names.append(portal.base.get_user_obj(current_user.id).name)
|
|
|
|
institution = portal.base.get_institution_obj(item.institution)
|
|
|
|
if not institution:
|
|
|
|
institution_names.append(None)
|
|
|
|
else:
|
|
|
|
institution_names.append(institution.name)
|
|
|
|
return render_template('solar-zgodovina.html', upload_history=upload_items, uploader_names=uploader_names,
|
2021-08-22 17:07:19 +00:00
|
|
|
institution_names=institution_names, is_admin=is_admin, is_institution_moderator=current_user_institution_moderator)
|
2021-05-24 08:15:54 +00:00
|
|
|
elif text.startswith('pogodbe/') or text == 'pogodbe':
|
|
|
|
# Check for ownload contract request.
|
2021-06-08 06:00:18 +00:00
|
|
|
match = re.match('^pogodbe/([a-z0-9_]+\.pdf)$', text)
|
2021-05-24 08:15:54 +00:00
|
|
|
if match:
|
|
|
|
filename = match.group(1)
|
2021-06-08 06:00:18 +00:00
|
|
|
if len(filename) < 10:
|
|
|
|
return '', 404
|
|
|
|
prefix = filename[:2]
|
|
|
|
suffix = filename[2:]
|
|
|
|
|
|
|
|
safe_path = safe_join(str(upload_handler_solar.get_uploads_subdir('contracts')), prefix, suffix)
|
2021-05-24 08:15:54 +00:00
|
|
|
try:
|
|
|
|
return send_file(safe_path, as_attachment=True)
|
|
|
|
except FileNotFoundError:
|
2021-06-08 06:00:18 +00:00
|
|
|
return '', 404
|
2021-05-24 08:15:54 +00:00
|
|
|
|
|
|
|
user_obj = portal.base.get_user_obj(current_user.get_id())
|
2021-08-22 17:07:19 +00:00
|
|
|
institution = portal.base.get_user_institution(user_obj.id)
|
2021-05-24 08:15:54 +00:00
|
|
|
contracts_students = []
|
2021-06-08 06:00:18 +00:00
|
|
|
contract_school = []
|
|
|
|
enable_upload_school_contract = False
|
|
|
|
show_upload_form = False
|
2021-08-22 17:07:19 +00:00
|
|
|
collaborators = []
|
|
|
|
if institution:
|
|
|
|
collaborators = portal.base.get_all_active_institution_users(institution.id)
|
2021-06-08 06:00:18 +00:00
|
|
|
show_upload_form = True
|
|
|
|
contract_school = portal.solar.get_institution_contract(institution.id)
|
|
|
|
if portal.base.is_institution_moderator(user_obj.id, institution.id):
|
2021-08-22 17:07:19 +00:00
|
|
|
contracts_students = portal.solar.get_institution_student_contracts(institution.id)
|
2021-06-08 06:00:18 +00:00
|
|
|
enable_upload_school_contract = True
|
2021-08-22 17:07:19 +00:00
|
|
|
else:
|
|
|
|
contracts_students = portal.solar.get_institution_student_contracts(institution.id, user_obj.id)
|
2021-05-24 08:15:54 +00:00
|
|
|
|
|
|
|
return render_template('solar-pogodbe.html', contracts_students=contracts_students,
|
2021-06-08 06:00:18 +00:00
|
|
|
contract_school=contract_school,
|
|
|
|
enable_upload_school_contract=enable_upload_school_contract,
|
2021-08-22 17:07:19 +00:00
|
|
|
show_upload_form=show_upload_form,
|
|
|
|
collaborators=collaborators,
|
|
|
|
is_admin=is_admin, is_institution_moderator=current_user_institution_moderator)
|
2021-05-24 08:15:54 +00:00
|
|
|
elif text.startswith('admin/') or text == 'admin':
|
2021-08-22 17:07:19 +00:00
|
|
|
users = portal.base.get_all_active_users_join_institutions()
|
|
|
|
inactive_users = portal.base.get_all_inactive_users()
|
2021-06-08 06:00:18 +00:00
|
|
|
solar_institutions = portal.solar.get_all_institutions()
|
2021-08-22 17:07:19 +00:00
|
|
|
if is_admin:
|
|
|
|
return render_template('solar-admin.html', users=users,
|
|
|
|
institutions=solar_institutions, inactive_users=inactive_users)
|
|
|
|
elif text.startswith('manage-institution/') or text == 'manage-institution':
|
|
|
|
institution = portal.base.get_user_institution(current_user.id)
|
|
|
|
if portal.base.is_institution_moderator(current_user.id, institution.id):
|
|
|
|
solar_users = portal.base.get_all_active_users()
|
|
|
|
institution_users = portal.base.get_all_active_institution_users(institution.id)
|
|
|
|
return render_template('solar-manage-institution.html', users=solar_users,
|
|
|
|
institution_users=institution_users)
|
2021-06-08 06:00:18 +00:00
|
|
|
return '', 404
|
2021-05-17 12:33:53 +00:00
|
|
|
|
2021-05-24 08:15:54 +00:00
|
|
|
@app.route('/solar/pogodbe', methods=['POST'])
|
2021-05-17 12:33:53 +00:00
|
|
|
@login_required
|
2021-05-24 08:15:54 +00:00
|
|
|
def solar_upload_contract():
|
|
|
|
return upload_handler_solar.handle_contract_upload(request, current_user.get_id())
|
2021-05-17 12:33:53 +00:00
|
|
|
|
2021-06-08 06:00:18 +00:00
|
|
|
|
2021-08-22 17:07:19 +00:00
|
|
|
@app.route('/solar/adduser', methods=['POST'])
|
2021-06-08 06:00:18 +00:00
|
|
|
@login_required
|
2021-08-22 17:07:19 +00:00
|
|
|
def solar_add_user():
|
|
|
|
|
2021-06-08 06:00:18 +00:00
|
|
|
if not portal.base.is_admin(current_user.id):
|
|
|
|
return '', 404
|
|
|
|
|
2021-08-22 17:07:19 +00:00
|
|
|
name = request.form.get('name')
|
|
|
|
email = request.form.get('email')
|
|
|
|
password = request.form.get('password')
|
2021-06-08 06:00:18 +00:00
|
|
|
|
|
|
|
if not name:
|
2021-08-22 17:07:19 +00:00
|
|
|
flash('Prazno polje za ime.')
|
|
|
|
return redirect(redirect_url())
|
2021-06-08 06:00:18 +00:00
|
|
|
if len(name) > 100:
|
2021-08-22 17:07:19 +00:00
|
|
|
flash('Predolgo ime.')
|
|
|
|
return redirect(redirect_url())
|
2021-06-08 06:00:18 +00:00
|
|
|
|
|
|
|
if not email:
|
2021-08-22 17:07:19 +00:00
|
|
|
flash('Prazno polje za elektronsko pošto.')
|
|
|
|
return redirect(redirect_url())
|
2021-06-08 06:00:18 +00:00
|
|
|
if len(email) > 100:
|
2021-08-22 17:07:19 +00:00
|
|
|
flash('Predolg email naslov.')
|
|
|
|
return redirect(redirect_url())
|
2021-06-08 06:00:18 +00:00
|
|
|
elif not re.search(portal.base.REGEX_EMAIL, email):
|
2021-08-22 17:07:19 +00:00
|
|
|
flash('Email napačnega formata.')
|
|
|
|
return redirect(redirect_url())
|
2021-06-08 06:00:18 +00:00
|
|
|
|
|
|
|
if not password:
|
2021-08-22 17:07:19 +00:00
|
|
|
flash('Prazno polje za geslo.')
|
|
|
|
return redirect(redirect_url())
|
2021-06-08 06:00:18 +00:00
|
|
|
if len(password) > 100:
|
2021-08-22 17:07:19 +00:00
|
|
|
flash('Predolgo geslo.')
|
|
|
|
return redirect(redirect_url())
|
2021-06-08 06:00:18 +00:00
|
|
|
|
|
|
|
portal.base.register_new_user(name, email, password)
|
|
|
|
|
2021-08-22 17:07:19 +00:00
|
|
|
flash('Uporabnik je bil uspešno dodan.')
|
|
|
|
return redirect(redirect_url())
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/solar/activateuser', methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
def solar_activate_user():
|
|
|
|
if not portal.base.is_admin(current_user.id):
|
|
|
|
return '', 404
|
|
|
|
|
|
|
|
user_id = request.form.get('id')
|
|
|
|
if not user_id:
|
|
|
|
flash('Prazno polje za ID uporabnika.')
|
|
|
|
return redirect(redirect_url())
|
|
|
|
|
|
|
|
rowcount = portal.base.activate_user(user_id)
|
|
|
|
if rowcount == 0:
|
|
|
|
return '', 404
|
|
|
|
|
|
|
|
flash('Uporabnik je bil aktiviran.')
|
|
|
|
return redirect(redirect_url())
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/solar/forgotpass')
|
|
|
|
def solar_forgotpass():
|
|
|
|
return render_template('solar-forgotpass.html')
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/solar/sendresetpass', methods=['POST'])
|
|
|
|
def solar_sendresetpass():
|
|
|
|
email = request.form.get('email')
|
|
|
|
|
|
|
|
portal.base.send_resetpass_mail(email, upload_handler_regular.config)
|
|
|
|
|
|
|
|
flash('Povezava za ponastavitev gesla je bila poslana na vpisan email naslov.')
|
|
|
|
return redirect(redirect_url())
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/solar/resetpass/<token>')
|
|
|
|
def solar_resetpass(token):
|
|
|
|
user = portal.base.verify_reset_token(token)
|
|
|
|
|
|
|
|
if not user:
|
|
|
|
return '', 404
|
|
|
|
|
|
|
|
return render_template('solar-resetpass.html', user=user, token=token)
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/solar/resetpass/<token>', methods=['POST'])
|
|
|
|
def solar_resetpass_post(token):
|
|
|
|
new_password = request.form.get('new_password')
|
|
|
|
user = portal.base.verify_reset_token(token)
|
|
|
|
|
|
|
|
if not user:
|
|
|
|
return '', 404
|
|
|
|
|
|
|
|
rowcount = portal.base.update_user_password(user.id, new_password)
|
|
|
|
if rowcount == 0:
|
|
|
|
return '', 404
|
|
|
|
|
|
|
|
return 'Ponastavitev gesla uspešna.'
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/solar/topuploads')
|
|
|
|
@login_required
|
|
|
|
def solar_topuploads_srednje():
|
|
|
|
return jsonify(portal.solar.get_top_uploading_institutions())
|
2021-06-08 06:00:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@app.route('/solar/deluser', methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
def solar_del_user():
|
|
|
|
# TODO: check if user is institution moderator for the added users institution or is an admin
|
|
|
|
# TODO: delete from "user", "user_institution_mapping", update "institution_contract" set user to NULL
|
|
|
|
return '', 404
|
|
|
|
|
|
|
|
@app.route('/<corpus_name>/addinstitution', methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
def add_institution(corpus_name):
|
|
|
|
if not portal.base.is_admin(current_user.id):
|
|
|
|
return '', 404
|
|
|
|
if not corpus_name in ENABLED_CORPUSES:
|
|
|
|
return '', 404
|
|
|
|
|
2021-08-22 17:07:19 +00:00
|
|
|
name = request.form.get('name')
|
|
|
|
region = request.form.get('region')
|
2021-06-08 06:00:18 +00:00
|
|
|
|
|
|
|
if not name:
|
2021-08-22 17:07:19 +00:00
|
|
|
flash('Prazno polje za ime.')
|
|
|
|
return redirect(redirect_url())
|
2021-06-08 06:00:18 +00:00
|
|
|
if len(name) > 100:
|
2021-08-22 17:07:19 +00:00
|
|
|
flash('Predolgo ime.')
|
|
|
|
return redirect(redirect_url())
|
2021-06-08 06:00:18 +00:00
|
|
|
|
|
|
|
if not region:
|
2021-08-22 17:07:19 +00:00
|
|
|
flash('Prazno polje za regijo.')
|
|
|
|
return redirect(redirect_url())
|
2021-06-08 06:00:18 +00:00
|
|
|
if len(region) > 100:
|
2021-08-22 17:07:19 +00:00
|
|
|
flash('Predolgi niz za regijo.')
|
|
|
|
return redirect(redirect_url())
|
2021-06-08 06:00:18 +00:00
|
|
|
|
|
|
|
institution_id = portal.base.add_institution(name, region)
|
|
|
|
portal.base.grant_institution_corpus_access(institution_id, corpus_name)
|
2021-08-22 17:07:19 +00:00
|
|
|
flash('Institucija je bila dodana.')
|
|
|
|
return redirect(redirect_url())
|
2021-06-08 06:00:18 +00:00
|
|
|
|
|
|
|
@app.route('/<corpus_name>/addusertoinstitution', methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
def add_user_institution_mapping(corpus_name):
|
|
|
|
if not corpus_name in ENABLED_CORPUSES:
|
|
|
|
return '', 404
|
|
|
|
|
2021-08-22 17:07:19 +00:00
|
|
|
institution_id = request.form.get('institution_id')
|
|
|
|
if not institution_id:
|
|
|
|
institution = portal.base.get_user_institution(current_user.id)
|
|
|
|
if institution:
|
|
|
|
institution_id = institution.id
|
|
|
|
|
|
|
|
if not (portal.base.is_admin(current_user.id) or portal.base.is_institution_moderator(current_user.id, institution_id)):
|
|
|
|
return '', 404
|
|
|
|
|
2021-06-08 06:00:18 +00:00
|
|
|
user_id = request.form['user_id']
|
|
|
|
role = request.form['role']
|
|
|
|
if role not in ['moderator', 'user']:
|
|
|
|
return '', 404
|
|
|
|
|
2021-08-22 17:07:19 +00:00
|
|
|
if portal.base.get_user_institution(user_id):
|
|
|
|
flash('Uporabnik je že dodeljen instituciji. Dodeljevanje večim institucijam '\
|
|
|
|
'zaenkrat ni implementirano.')
|
|
|
|
return redirect(redirect_url())
|
2021-06-08 06:00:18 +00:00
|
|
|
|
|
|
|
portal.base.add_user_to_institution(user_id, institution_id, role)
|
2021-08-22 17:07:19 +00:00
|
|
|
flash('Uporabnik je bil dodeljen instituciji.')
|
|
|
|
return redirect(redirect_url())
|
|
|
|
|
|
|
|
@app.route('/<corpus_name>/deluserfrominstitution', methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
def del_user_institution_mapping(corpus_name):
|
|
|
|
institution = portal.base.get_user_institution(current_user.id)
|
|
|
|
if not portal.base.is_admin(current_user.id) \
|
|
|
|
and not portal.base.is_institution_moderator(current_user.id, institution.id):
|
|
|
|
return '', 404
|
|
|
|
if not corpus_name in ENABLED_CORPUSES:
|
|
|
|
return '', 404
|
|
|
|
|
|
|
|
user_id = request.form['user_id']
|
|
|
|
|
|
|
|
if not portal.base.is_institution_member(user_id, institution.id):
|
|
|
|
flash('Uporabnik ni član vaše institucije.')
|
|
|
|
return redirect(redirect_url())
|
|
|
|
|
|
|
|
portal.base.del_user_from_institution(user_id, institution.id)
|
|
|
|
flash('Uporabnik je bil odstranjen iz institucije.')
|
|
|
|
return redirect(redirect_url())
|
2021-06-08 06:00:18 +00:00
|
|
|
|
|
|
|
@app.route('/<corpus_name>/delinstitution', methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
def del_institution(corpus_name):
|
|
|
|
# TODO: check if valid corpus_name
|
|
|
|
# TODO: check if user is admin
|
|
|
|
# TODO: delete cascade - institution, user_institution_mapping, corpus_access, institution_contract
|
|
|
|
return '', 404
|
|
|
|
|
|
|
|
|
2021-05-05 12:26:26 +00:00
|
|
|
@app.route('/<corpus_name>/upload', methods=['POST'])
|
|
|
|
def handle_upload(corpus_name):
|
2021-05-17 12:33:53 +00:00
|
|
|
if corpus_name not in ENABLED_CORPUSES:
|
2021-06-08 06:00:18 +00:00
|
|
|
return '', 404
|
2021-05-05 12:26:26 +00:00
|
|
|
|
|
|
|
if corpus_name == 'solar':
|
2021-05-24 08:15:54 +00:00
|
|
|
if not current_user.is_authenticated:
|
2021-06-08 06:00:18 +00:00
|
|
|
return '', 404
|
2021-08-22 17:07:19 +00:00
|
|
|
#if not portal.base.has_user_corpus_access(current_user.id, corpus_name):
|
|
|
|
# return '', 404
|
2021-05-24 08:15:54 +00:00
|
|
|
return upload_handler_solar.handle_upload(request, current_user.get_id())
|
2021-05-05 12:26:26 +00:00
|
|
|
else:
|
2021-05-17 12:33:53 +00:00
|
|
|
return upload_handler_regular.handle_upload(request, corpus_name)
|
2021-03-24 10:05:36 +00:00
|
|
|
|
|
|
|
|
2020-10-23 08:07:14 +00:00
|
|
|
if __name__ == '__main__':
|
|
|
|
app.run(debug=True)
|