diff --git a/proxadmin/__init__.py b/proxadmin/__init__.py index b0b351e..5c7d728 100644 --- a/proxadmin/__init__.py +++ b/proxadmin/__init__.py @@ -4,52 +4,36 @@ from flask_mail import Mail from flask_sqlalchemy import SQLAlchemy from flask_login import LoginManager from flask_wtf.csrf import CSRFProtect, CSRFError -from flask_babel import Babel +from flask_babel import Babel, lazy_gettext from werkzeug.contrib.fixers import ProxyFix -from proxadmin import configure_app +from .config import basedir, MAIL_SERVER, MAIL_PORT, MAIL_USERNAME, MAIL_PASSWORD app = Flask(__name__) - -configure_app(app) - -app.wsgi_app = ProxyFix(app.wsgi_app) #trusting headers behind proxy +app.config.from_object('config') +app.wsgi_app = ProxyFix(app.wsgi_app) db = SQLAlchemy(session_options = { "autoflush": False }) +db.init_app(app) lm = LoginManager() +lm.init_app(app) lm.login_view = 'auth.login' lm.login_message = 'Login Required.' lm.session_protection = 'strong' #lm.session_protection = 'basic' -mail = Mail() -bootstrap = Bootstrap() -#csrf = CSRFProtect() -babel = Babel() +mail = Mail(app) +bootstrap = Bootstrap(app) +#csrf = CSRFProtect(app) +babel = Babel(app) -app = Flask(__name__) -app.config.from_object('config') - -#if app.debug: -# pass -# #toolbar = DebugToolbarExtension(app) -#else: -# import logging -# from logging.handlers import RotatingFileHandler -# file_handler = RotatingFileHandler('app/log/proxadmin.log', 'a', 1 * 1024 * 1024, 10) -# file_handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]')) -# app.logger.setLevel(logging.INFO) -# file_handler.setLevel(logging.INFO) -# app.logger.addHandler(file_handler) -# app.logger.info('Proxadmin started.') - -bootstrap.init_app(app) -mail.init_app(app) -db.init_app(app) -lm.init_app(app) -babel.init_app(app) +#bootstrap.init_app(app) +#mail.init_app(app) +#db.init_app(app) +#lm.init_app(app) +#babel.init_app(app) #csrf.init_app(app) -from .proxadmin import proxadmin as proxadmin_blueprint -app.register_blueprint(proxadmin_blueprint) +from .vmanager import vmanager as vmanager_blueprint +app.register_blueprint(vmanager_blueprint) from .auth import auth as auth_blueprint app.register_blueprint(auth_blueprint, url_prefix='/auth') @@ -57,6 +41,30 @@ app.register_blueprint(auth_blueprint, url_prefix='/auth') from .uinvoice import uinvoice as uinvoice_blueprint app.register_blueprint(uinvoice_blueprint, url_prefix='/uinvoice') +class CustomJSONEncoder(JSONEncoder): + """This class adds support for lazy translation texts to Flask's + JSON encoder. This is necessary when flashing translated texts.""" + def default(self, obj): + from speaklater import is_lazy_string + if is_lazy_string(obj): + try: + return unicode(obj) # python 2 + except NameError: + return str(obj) # python 3 + return super(CustomJSONEncoder, self).default(obj) + +app.json_encoder = CustomJSONEncoder + +if not app.debug: + import logging + from logging.handlers import RotatingFileHandler + file_handler = RotatingFileHandler('log/proxadmin.log', 'a', 1 * 1024 * 1024, 10) + file_handler.setLevel(logging.INFO) + file_handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]')) + app.logger.addHandler(file_handler) + app.logger.setLevel(logging.INFO) + app.logger.info('Proxadmin started.') + @app.errorhandler(403) def forbidden(e): if request.accept_mimetypes.accept_json and \ @@ -98,6 +106,26 @@ def get_locale(): # g.request_time = lambda: '%.5fs' % (time.time() - g.request_start_time) # g.pjax = 'X-PJAX' in request.headers +if not app.debug and MAIL_SERVER != '': + import logging + from logging.handlers import SMTPHandler + credentials = None + secure = None + if MAIL_USERNAME or MAIL_PASSWORD: + credentials = (MAIL_USERNAME, MAIL_PASSWORD) + if MAIL_USE_TLS is None: + secure = () + mail_handler = SMTPHandler( + mailhost=(MAIL_SERVER, MAIL_PORT), + fromaddr=MAIL_SENDER, + toaddrs=[MAIL_ADMIN], + subject=MAIL_SUBJECT_PREFIX + ' Application Error', + credentials=credentials, + secure=secure) + mail_handler.setLevel(logging.ERROR) + app.logger.addHandler(mail_handler) + + if __name__ == '__main__': app.run() diff --git a/proxadmin/auth/routes.py b/proxadmin/auth/routes.py index b0f9f13..118d50b 100644 --- a/proxadmin/auth/routes.py +++ b/proxadmin/auth/routes.py @@ -24,7 +24,7 @@ def before_request(): @auth.route('/unconfirmed') def unconfirmed(): if current_user.is_anonymous or current_user.confirmed: - return redirect(url_for('proxadmin.index')) + return redirect(url_for('vmanager.index')) return render_template('auth/unconfirmed.html') @@ -51,7 +51,7 @@ def login(): db.session.add(user) db.session.commit() #send_email(current_app.config['MAIL_USERNAME'], user.email + ' logged in.', 'auth/email/adm_loginnotify', user=user, ipaddr=lastip ) - return redirect(request.args.get('next') or url_for('proxadmin.dashboard')) + return redirect(request.args.get('next') or url_for('vmanager.dashboard')) flash('Invalid username or password.') return render_template('auth/login.html', page=page, form=form) @@ -84,7 +84,7 @@ def twofactor(): db.session.add(user) db.session.commit() #send_email(current_app.config['MAIL_USERNAME'], user.email + ' logged in.', 'auth/email/adm_loginnotify', user=user, ipaddr=lastip ) - return redirect(request.args.get('next') or url_for('proxadmin.dashboard')) + return redirect(request.args.get('next') or url_for('vmanager.dashboard')) return render_template('auth/2fa.html', page=page, form=form) @@ -117,7 +117,7 @@ def qrcode(): def logout(): logout_user() flash('You have logged out') - return redirect(url_for('proxadmin.index')) + return redirect(url_for('vmanager.index')) @auth.route('/register', methods=['GET', 'POST']) @@ -148,12 +148,12 @@ def register(): @login_required def confirm(token): if current_user.confirmed: - return redirect(url_for('proxadmin.index')) + return redirect(url_for('vmanager.index')) if current_user.confirm(token): flash('Вашият акаунт е потвърден. Благодаря!') else: flash('Времето за потвърждение на вашият код изтече.') - return redirect(url_for('proxadmin.index')) + return redirect(url_for('vmanager.index')) @auth.route('/confirm') @@ -163,7 +163,7 @@ def resend_confirmation(): send_email(current_user.email, 'Потвърдете_вашият_акаунт', 'auth/email/confirm', user=current_user, token=token) flash('Изпратен е нов код за потвърждение..') - return redirect(url_for('proxadmin.index')) + return redirect(url_for('vmanager.index')) @auth.route('/change-password', methods=['GET', 'POST']) @@ -176,7 +176,7 @@ def change_password(): db.session.add(current_user) db.session.commit() flash('Вашата парола беше променена.') - return redirect(url_for('proxadmin.index')) + return redirect(url_for('vmanager.index')) else: flash('Грешна парола.') return render_template("auth/change_password.html", form=form) @@ -185,7 +185,7 @@ def change_password(): @auth.route('/reset', methods=['GET', 'POST']) def password_reset_request(): if not current_user.is_anonymous: - return redirect(url_for('proxadmin.index')) + return redirect(url_for('vmanager.index')) form = PasswordResetRequestForm() if form.validate_on_submit(): user = User.query.filter_by(email=form.email.data).first() @@ -204,17 +204,17 @@ def password_reset_request(): @auth.route('/reset/', methods=['GET', 'POST']) def password_reset(token): if not current_user.is_anonymous: - return redirect(url_for('proxadmin.index')) + return redirect(url_for('vmanager.index')) form = PasswordResetForm() if form.validate_on_submit(): user = User.query.filter_by(email=form.email.data).first() if user is None: - return redirect(url_for('proxadmin.index')) + return redirect(url_for('vmanager.index')) if user.reset_password(token, form.password.data): flash('Your password has been updated.') return redirect(url_for('auth.login')) else: - return redirect(url_for('proxadmin.index')) + return redirect(url_for('vmanager.index')) return render_template('auth/reset_password.html', form=form) diff --git a/proxadmin/decorators.py b/proxadmin/decorators.py index 73ea9c5..c3217c1 100644 --- a/proxadmin/decorators.py +++ b/proxadmin/decorators.py @@ -2,7 +2,13 @@ from functools import wraps from flask import abort from flask_login import current_user from .models import Permission +from threading import Thread +def async(f): + def wrapper(*args, **kwargs): + thr = Thread(target=f, args=args, kwargs=kwargs) + thr.start() + return wrapper def permission_required(permission): def decorator(f): @@ -14,7 +20,6 @@ def permission_required(permission): return decorated_function return decorator - def admin_required(f): return permission_required(Permission.ADMINISTER)(f) diff --git a/proxadmin/email.py b/proxadmin/email.py index 3d13e6e..14b8774 100644 --- a/proxadmin/email.py +++ b/proxadmin/email.py @@ -1,14 +1,14 @@ from threading import Thread from flask import current_app, render_template from flask_mail import Message -from . import mail - +from . import app, mail +from .decorators import async +@async def send_async_email(app, msg): with app.app_context(): mail.send(msg) - def send_email(to, subject, template, **kwargs): app = current_app._get_current_object() msg = Message(app.config['MAIL_SUBJECT_PREFIX'] + ' ' + subject, sender=app.config['MAIL_SENDER'], recipients=[to]) diff --git a/proxadmin/templates/auth/already_confirmed.html b/proxadmin/templates/auth/already_confirmed.html index 6a18e79..8703963 100644 --- a/proxadmin/templates/auth/already_confirmed.html +++ b/proxadmin/templates/auth/already_confirmed.html @@ -13,7 +13,7 @@ Моля напуснете тази страница :)

- Натиснете тук за изход + Натиснете тук за изход

diff --git a/proxadmin/templates/nav-full.html b/proxadmin/templates/nav-full.html index 461cacf..1830d41 100644 --- a/proxadmin/templates/nav-full.html +++ b/proxadmin/templates/nav-full.html @@ -9,9 +9,9 @@ {% if not current_user.is_authenticated %} - proxmaster + proxmaster {% else %} - proxmaster + proxmaster {% endif %} @@ -23,16 +23,16 @@ diff --git a/proxadmin/templates/nav.html b/proxadmin/templates/nav.html index a95964e..b47d56a 100644 --- a/proxadmin/templates/nav.html +++ b/proxadmin/templates/nav.html @@ -9,9 +9,9 @@ {% if not current_user.is_authenticated %} - + {% else %} - + {% endif %} @@ -32,7 +32,7 @@ {% endif %} -
  • Live Chat
  • +
  • Live Chat
  • @@ -44,7 +44,7 @@