messing up

This commit is contained in:
deflax 2017-03-09 02:55:12 +02:00
parent ce26a04e8e
commit 9dca58eb80
24 changed files with 132 additions and 99 deletions

View file

@ -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()

View file

@ -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/<token>', 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)

View file

@ -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)

View file

@ -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])

View file

@ -13,7 +13,7 @@
Моля напуснете тази страница :)
</p>
<p>
<a href="{{ url_for('proxadmin.index') }}">Натиснете тук за изход</a>
<a href="{{ url_for('vmanager.index') }}">Натиснете тук за изход</a>
</p>
</div>

View file

@ -9,9 +9,9 @@
<span class="icon-bar"></span>
</button>
{% if not current_user.is_authenticated %}
<a class="navbar-brand" href="{{ url_for('proxadmin.index') }}" rel="home"><span><img style="max-width:100px; margin-top: -7px;" src="../static/images/hex24.png"></span> proxmaster</a>
<a class="navbar-brand" href="{{ url_for('vmanager.index') }}" rel="home"><span><img style="max-width:100px; margin-top: -7px;" src="../static/images/hex24.png"></span> proxmaster</a>
{% else %}
<a class="navbar-brand" href="{{ url_for('proxadmin.index') }}" rel="home"><span><img style="max-width:100px; margin-top: -7px;" src="../static/images/hex24.png"></span> proxmaster</a>
<a class="navbar-brand" href="{{ url_for('vmanager.index') }}" rel="home"><span><img style="max-width:100px; margin-top: -7px;" src="../static/images/hex24.png"></span> proxmaster</a>
{% endif %}
</div>
@ -23,16 +23,16 @@
<li class="dropdown">
<a href="#" class="dropdown-togle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Solution Market<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="{{ url_for('proxadmin.market') }}">Applications</a></li>
<li><a href="{{ url_for('proxadmin.market') }}">Schemas</a></li>
<li><a href="{{ url_for('vmanager.market') }}">Applications</a></li>
<li><a href="{{ url_for('vmanager.market') }}">Schemas</a></li>
</ul>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Community<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="{{ url_for('proxadmin.dashboard') }}">Groups</a></li>
<li><a href="{{ url_for('proxadmin.dashboard') }}">Blog</a></li>
<li><a href="{{ url_for('vmanager.dashboard') }}">Groups</a></li>
<li><a href="{{ url_for('vmanager.dashboard') }}">Blog</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">r5</a></li>
</ul>
@ -50,14 +50,14 @@
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><img class="avatar" src="{{ current_user.gravatar(20) }}"> {{ current_user.email }} <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="{{ url_for('proxadmin.dashboard') }}"><span class="glyphicon glyphicon-eye-open"></span> Dashboard</a></li>
<li><a href="{{ url_for('proxadmin.profile') }}"><span class="glyphicon glyphicon-flag"></span> Policy</a></li>
<li><a href="{{ url_for('proxadmin.profile') }}"><span class="glyphicon glyphicon-list"></span> Drafts</a></li>
<li><a href="{{ url_for('vmanager.dashboard') }}"><span class="glyphicon glyphicon-eye-open"></span> Dashboard</a></li>
<li><a href="{{ url_for('vmanager.profile') }}"><span class="glyphicon glyphicon-flag"></span> Policy</a></li>
<li><a href="{{ url_for('vmanager.profile') }}"><span class="glyphicon glyphicon-list"></span> Drafts</a></li>
<li role="separator" class="divider"></li>
<li><a href="{{ url_for('proxadmin.profile') }}"><span class="glyphicon glyphicon-user"></span> Profile</a></li>
<li><a href="{{ url_for('proxadmin.profile') }}"><span class="glyphicon glyphicon-question-sign"></span> Help</a></li>
<li><a href="{{ url_for('proxadmin.profile') }}"><span class="glyphicon glyphicon-cog"></span> Settings</a></li>
<li><a href="{{ url_for('vmanager.profile') }}"><span class="glyphicon glyphicon-user"></span> Profile</a></li>
<li><a href="{{ url_for('vmanager.profile') }}"><span class="glyphicon glyphicon-question-sign"></span> Help</a></li>
<li><a href="{{ url_for('vmanager.profile') }}"><span class="glyphicon glyphicon-cog"></span> Settings</a></li>
<li><a href="{{ url_for('auth.logout') }}"><span class="glyphicon glyphicon-off"></span> Logout</a></li>
</ul>
</li>

View file

@ -9,9 +9,9 @@
<span class="icon-bar"></span>
</button>
{% if not current_user.is_authenticated %}
<a class="navbar-brand" href="{{ url_for('proxadmin.index') }}" rel="home"></a>
<a class="navbar-brand" href="{{ url_for('vmanager.index') }}" rel="home"></a>
{% else %}
<a class="navbar-brand" href="{{ url_for('proxadmin.dashboard') }}" rel="home"></a>
<a class="navbar-brand" href="{{ url_for('vmanager.dashboard') }}" rel="home"></a>
{% endif %}
</div>
@ -32,7 +32,7 @@
</ul>
{% endif %}
<li><a href="{{ url_for('proxadmin.chat') }}" target="_blank"><span class="glyphicon glyphicon-question-sign"></span> Live Chat</a></li>
<li><a href="{{ url_for('vmanager.chat') }}" target="_blank"><span class="glyphicon glyphicon-question-sign"></span> Live Chat</a></li>
</ul>
@ -44,7 +44,7 @@
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><img class="avatar" src="{{ current_user.gravatar(20) }}"> {{ current_user.email }} <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="{{ url_for('proxadmin.dashboard') }}"><span class="glyphicon glyphicon-eye-open"></span> Dashboard</a></li>
<li><a href="{{ url_for('vmanager.dashboard') }}"><span class="glyphicon glyphicon-eye-open"></span> Dashboard</a></li>
<li><a href="{{ url_for('uinvoice.documents') }}"><span class="glyphicon glyphicon-list-alt"></span> Orders</a></li>
<li role="separator" class="divider"></li>
<li><a href="{{ url_for('uinvoice.profile') }}"><span class="glyphicon glyphicon-user"></span> Profile</a></li>

View file

@ -47,7 +47,7 @@
<div class="panel panel-default">
<div class="panel-heading">Настройки</div>
<div class="panel-body">
<form method="POST" action="{{ url_for('proxadmin.deploy', product_id=product_id) }}">
<form method="POST" action="{{ url_for('vmanager.deploy', product_id=product_id) }}">
<p>
{{ form.servername.label }}<br />{{ form.servername(size=42) }}<br />
{% for error in form.servername.errors %}

View file

@ -1,3 +1,3 @@
from flask import Blueprint
proxadmin = Blueprint('proxadmin', __name__)
vmanager = Blueprint('vmanager', __name__)
from . import routes

View file

@ -1,8 +1,8 @@
from flask import render_template, request, jsonify
from . import proxadmin
from . import vmanager
@proxadmin.app_errorhandler(403)
@vmanager.app_errorhandler(403)
def forbidden(e):
if request.accept_mimetypes.accept_json and \
not request.accept_mimetypes.accept_html:
@ -12,7 +12,7 @@ def forbidden(e):
return render_template('403.html'), 403
@proxadmin.app_errorhandler(404)
@vmanager.app_errorhandler(404)
def page_not_found(e):
if request.accept_mimetypes.accept_json and \
not request.accept_mimetypes.accept_html:
@ -22,7 +22,7 @@ def page_not_found(e):
return render_template('404.html'), 404
@proxadmin.app_errorhandler(500)
@vmanager.app_errorhandler(500)
def internal_server_error(e):
if request.accept_mimetypes.accept_json and \
not request.accept_mimetypes.accept_html:

View file

@ -3,7 +3,7 @@ from flask import render_template, abort, redirect, url_for, abort, flash, reque
from flask_login import login_required, login_user, logout_user, current_user
from flask_sqlalchemy import get_debug_queries
from . import proxadmin
from . import vmanager
from .forms import DeployForm
from .. import db
from ..email import send_email
@ -18,12 +18,12 @@ from datetime import datetime, timedelta, date, time
def randstr(n):
return ''.join(random.SystemRandom().choice(string.ascii_lowercase + string.digits) for _ in range(n))
#@proxadmin.before_app_request
#@vmanager.before_app_request
#def before_request():
# g.user = current_user
# print('current_user: %s, g.user: %s, leaving bef_req' % (current_user, g.user))
@proxadmin.after_app_request
@vmanager.after_app_request
def after_request(response):
for query in get_debug_queries():
if query.duration >= current_app.config['SLOW_DB_QUERY_TIME']:
@ -31,25 +31,25 @@ def after_request(response):
return response
#STATIC PAGES
@proxadmin.route("/", methods=['GET'])
@vmanager.route("/", methods=['GET'])
def index():
return render_template('proxadmin/index.html')
return render_template('vmanager/index.html')
@proxadmin.route("/chat", methods=['GET'])
@vmanager.route("/chat", methods=['GET'])
def chat():
return render_template('proxadmin/livechat.html')
return render_template('vmanager/livechat.html')
@proxadmin.route("/aboutus", methods=['GET'])
@vmanager.route("/aboutus", methods=['GET'])
def about():
return render_template('proxadmin/aboutus.html')
return render_template('vmanager/aboutus.html')
@proxadmin.route("/terms", methods=['GET'])
@vmanager.route("/terms", methods=['GET'])
def terms():
return render_template('proxadmin/terms.html')
return render_template('vmanager/terms.html')
#APP STORE
@proxadmin.route('/market/<int:group_id>', methods=['GET'])
@vmanager.route('/market/<int:group_id>', methods=['GET'])
@login_required
def market(group_id=0):
page = { 'title': 'Market' }
@ -57,7 +57,7 @@ def market(group_id=0):
allgroups = current_app.config['GROUPS']
if group_id == 0:
return render_template('proxadmin/market.html', groups=allgroups, products=allproducts)
return render_template('vmanager/market.html', groups=allgroups, products=allproducts)
filtered_products = {}
for key, value in allproducts.items():
@ -66,10 +66,10 @@ def market(group_id=0):
if filtered_products == {}:
abort(404)
return render_template('proxadmin/marketgroup.html', groupname=allgroups[group_id], products=filtered_products)
return render_template('vmanager/marketgroup.html', groupname=allgroups[group_id], products=filtered_products)
@proxadmin.route('/deploy/<int:product_id>', methods=['GET', 'POST'])
@vmanager.route('/deploy/<int:product_id>', methods=['GET', 'POST'])
@login_required
def deploy(product_id=None):
#if current_user.wallet < 20:
@ -120,7 +120,7 @@ def deploy(product_id=None):
query = contact_proxmaster(data, 'vmcreate')
except:
flash('Region unreachable! Please try again later...')
return redirect(url_for('proxadmin.index'))
return redirect(url_for('vmanager.index'))
if query is not None:
cubeid = query['cube']
@ -132,13 +132,13 @@ def deploy(product_id=None):
else:
flash('Deploy cancelled! Please try again later...')
return redirect(url_for('proxadmin.index'))
return redirect(url_for('vmanager.index'))
return render_template('proxadmin/deploy.html', page=page, form=form, product_id=product_id, product_pic=product_pic, product_name=product_name, product_description=product_description, product_recipe=product_recipe)
return render_template('vmanager/deploy.html', page=page, form=form, product_id=product_id, product_pic=product_pic, product_name=product_name, product_description=product_description, product_recipe=product_recipe)
#COMMAND AND CONTROL
@proxadmin.route("/dashboard", methods=['GET', 'POST'])
@vmanager.route("/dashboard", methods=['GET', 'POST'])
@login_required
def dashboard():
#if request.method == 'GET':
@ -149,7 +149,7 @@ def dashboard():
if invcls.enabled == True:
inv_deployments.extend([invcls.machine_id])
#if not inv_deployments:
# return render_template('proxadmin/empty_dashboard.html')
# return render_template('vmanager/empty_dashboard.html')
rrd = {}
statuses = {}
@ -160,7 +160,7 @@ def dashboard():
except:
flash('Deploy #{} unreachable. Support is notified'.format(str(cubeid)))
send_email(current_app.config['MAIL_USERNAME'], 'Cube {} is unreachable'.format(cubeid),
'proxadmin/email/adm_unreachable', user=current_user, cubeid=cubeid)
'vmanager/email/adm_unreachable', user=current_user, cubeid=cubeid)
graphs_list = ['net', 'cpu', 'mem', 'hdd']
try:
@ -173,7 +173,7 @@ def dashboard():
print(e)
flash('Deploy #{} unreachable. Support is notified'.format(str(cubeid)))
send_email(current_app.config['MAIL_USERNAME'], 'Cube {} is unreachable'.format(cubeid),
'proxadmin/email/adm_unreachable', user=current_user, cubeid=cubeid )
'vmanager/email/adm_unreachable', user=current_user, cubeid=cubeid )
contracts = current_user.inv_contracts.order_by(Contract.date_created.desc()).all()
#inv_contracts = []
@ -189,9 +189,9 @@ def dashboard():
#print(statuses)
return render_template('proxadmin/dashboard.html', rrd=rrd, status=statuses, inv_deployments=deployments, inv_contracts=contracts, inv_domains=domains)
return render_template('vmanager/dashboard.html', rrd=rrd, status=statuses, inv_deployments=deployments, inv_contracts=contracts, inv_domains=domains)
@proxadmin.route('/vmvnc/<int:vmid>')
@vmanager.route('/vmvnc/<int:vmid>')
@login_required
def vnc(vmid=0):
result = current_user.inv_deployments.order_by(Deployment.date_created.desc()).all()
@ -207,14 +207,14 @@ def vnc(vmid=0):
else:
data = {}
db_result = contact_proxmaster(data, 'vmvnc', vmid)
#return render_template('proxadmin/vnc.html', url=db_result['url'])
#return render_template('vmanager/vnc.html', url=db_result['url'])
return redirect(db_result['url'])
abort(404)
valid_commands = ['vmstatus', 'vmstart', 'vmshutdown', 'vmstop']
@proxadmin.route('/<cmd>/<int:vmid>')
@vmanager.route('/<cmd>/<int:vmid>')
@login_required
def command(cmd=None, vmid=0):
#checks whether this is a valid command

2
run.py
View file

@ -1,4 +1,4 @@
from app import app
from proxadmin import app
if __name__ == '__main__':
app.run()