diff --git a/Config.py b/Config.py index 2db09b6..bdd30e6 100644 --- a/Config.py +++ b/Config.py @@ -6,3 +6,4 @@ MINFIELDLEN = 3 INFO = 1 DONOTSETFILTER = 'DoNotSetFilterinCookie' ACCESSFILE = '/tmp/wsgi_flower_accessfile' +URLPREFIX = '/flowers' diff --git a/README.md b/README.md index ab242b9..6551ac8 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,30 @@ -to install the dev env: +FLowers +------- + +The current code base is designed to run undert a waitress server as a backend to apache +The app should be called as http:// ... /flowers (so as a subfolder of the domain) + +to install the env: +python3 -m venv venv +source venv/bin/activate +pip install flask waitress fernet pymysql pytz -sudo pip3 install virtualenv -virtualenv p3env -source p3env/bin/activate -pip install uwsgi flask fernet pymysql +install apache and activate proxy: +a2enmod proxy +a2enmod proxy_http +and put the following in the site...conf file: + ProxyPass "/flowers" "http://127.0.0.1:5012/flowers" + ProxyPassReverse "/flowers" "http://127.0.0.1:5012/flowers" -to install kivi in the venv: -pip install Cython==0.23 -sudo apt-get install libgl1-mesa-dev -pip install kivy -pip install pygame -vi ~/.kivy/config.ini - change: multisamples = 0 # as root in mysql create database Flowers; grant create,select,update,insert,grant option on Flowers.* to flower@localhost identified by '608f0b988db4a96066af7dd8870de96c'; grant create user,reload on *.* to flower@localhost; -flush privileges; \ No newline at end of file +flush privileges; + +start waitress: +waitress-serve --threads=6 --host=127.0.0.1 --port=5012 --call flowers:create_app \ No newline at end of file diff --git a/__pycache__/AccessControl.cpython-313.pyc b/__pycache__/AccessControl.cpython-313.pyc new file mode 100644 index 0000000..b4c14bf Binary files /dev/null and b/__pycache__/AccessControl.cpython-313.pyc differ diff --git a/__pycache__/Config.cpython-313.pyc b/__pycache__/Config.cpython-313.pyc new file mode 100644 index 0000000..26e3018 Binary files /dev/null and b/__pycache__/Config.cpython-313.pyc differ diff --git a/__pycache__/FlowerServices.cpython-313.pyc b/__pycache__/FlowerServices.cpython-313.pyc new file mode 100644 index 0000000..d9e7a2b Binary files /dev/null and b/__pycache__/FlowerServices.cpython-313.pyc differ diff --git a/__pycache__/Log.cpython-313.pyc b/__pycache__/Log.cpython-313.pyc new file mode 100644 index 0000000..cd1d186 Binary files /dev/null and b/__pycache__/Log.cpython-313.pyc differ diff --git a/__pycache__/flower_vase.cpython-313.pyc b/__pycache__/flower_vase.cpython-313.pyc new file mode 100644 index 0000000..7e135f3 Binary files /dev/null and b/__pycache__/flower_vase.cpython-313.pyc differ diff --git a/__pycache__/flowers.cpython-313.pyc b/__pycache__/flowers.cpython-313.pyc new file mode 100644 index 0000000..818c1c3 Binary files /dev/null and b/__pycache__/flowers.cpython-313.pyc differ diff --git a/flower_vase.py b/flower_vase.py new file mode 100644 index 0000000..40c3a7b --- /dev/null +++ b/flower_vase.py @@ -0,0 +1,202 @@ +from flask import Flask, Blueprint, send_from_directory +from Config import * +import sys +import datetime +import pytz +from FlowerServices import Flower,SuperFlower +from AccessControl import Access +import json +from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash, json, make_response +from werkzeug.exceptions import HTTPException + +# configuration +# DEBUG = False +# SECRET_KEY = 'development key' +flower_bp = Blueprint("flower_vase", __name__, url_prefix=URLPREFIX) + + +# app = Flask(__name__) +# app.config.from_object(__name__) + +@flower_bp.route('/static/') +def statix(filename): + return send_from_directory('static', filename) + +@flower_bp.route('/') +def index(): + print(request.remote_addr) + return render_template('index.html', name_suggestion="Hello", pwd_suggestion="Want to try your luck?") + +@flower_bp.route('/browser' , methods=['POST', 'GET']) +def application(): + now = datetime.datetime.now(pytz.timezone('Europe/Amsterdam')) + + if request.method == 'GET': + return render_template('index.html', name_suggestion="Faded out", pwd_suggestion="Want to retry your luck?") + + access_ctrl = Access() + if not access_ctrl.granted(request.remote_addr): + return render_template('index.html', name_suggestion="Sorry", pwd_suggestion="Access denied") + + action=request.form['action'] + filter='' + if 'filter' in session: + filter = session['filter'] + + if action == 'logout': + session['filter'] = request.form['filter'] + session['timeout'] = now - datetime.timedelta(minutes=999) + return render_template('index.html', name_suggestion="Bye", pwd_suggestion="Come back any time") + + + if action == 'login': + user=request.form['name'] + pwd=request.form['password'] + F = Flower(user, pwd) + if F.numberOfEntries()>=0: + session['dbuser'] = user + session['dbpwd'] = pwd + session['timeout'] = now + session['filter'] = filter + return render_template('list.html', flowers=F.all(), filter=filter) + #login failure + access_ctrl.deny(request.remote_addr) + print("Flowers - authorization failed for {}".format(user)) + return render_template('index.html', name_suggestion="Sorry", pwd_suggestion="Better next time") + + if 'timeout' in session and session['timeout']+datetime.timedelta(minutes=10)>now: + session['timeout'] = now + + if 'filter' in request.form.keys() and len(request.form['filter'])>1 and request.form['filter'] != DONOTSETFILTER: + session['filter']=request.form['filter'] + filter = request.form['filter'] + + F = Flower(session['dbuser'], session['dbpwd']) + if F.numberOfEntries()>=0: + + if action == 'list': + return render_template('list.html', flowers=F.all(), filter=filter) + + if action == 'show': + return render_template('show.html', flower=F.one(request.form['organization'], request.form['datetime'])) + + if action == 'edit': + return render_template('edit.html', flower=F.one(request.form['organization'], request.form['datetime'])) + + if action == 'new': + return render_template('edit.html', flower=F.empty()) + + if action == 'save': + flower = F.add(request.form['organization'],request.form['myname'],request.form['myid'],request.form['secret']) + session['filter']=request.form['organization'] + return render_template('show.html', flower=flower) + + if action == 'deactivate': + flower = F.deactivate(request.form['organization'],request.form['datetime']) + session['filter']='' + return render_template('show.html', flower=flower) + + if action == 'rehush': + return render_template('rehush.html', flower=F.empty()) + + + else: + return render_template('new.html', flower=F.empty()) + + + return render_template('index.html', name_suggestion="Sorry", pwd_suggestion="Better next time") + +@flower_bp.route('/create' , methods=['POST','GET']) +def create(): + access_ctrl = Access() + if not access_ctrl.granted(request.remote_addr): + return render_template('index.html', name_suggestion="Sorry", pwd_suggestion="Access denied") + + if 'name' not in request.form: + return render_template('create.html') + newuser = request.form['name'] + newhush = request.form['password'] + + # login db with generic user + f = SuperFlower(newuser, newhush) + if f.createNewTable(): + # login as new user + u = Flower(newuser, newhush) + # add one line + u.add('Demo organisation', 'Demo name', 'Demo login', 'Demo hush') + + # return to the login page + return render_template('index.html', name_suggestion="Now login", pwd_suggestion="for your very first time") + + return render_template('create.html', message="Sorry - System error - check log files") + + +@flower_bp.route('/update_pwd', methods=['POST','GET']) +def update_pwd(): + if 'name' not in request.form: + return render_template('rehush.html') + user = request.form['name'] + oldhush = request.form['old_password'] + newhush = request.form['new_password'] + + # login db with generic user + f = Flower(user, oldhush) + message = f.update_pwd(newhush) + + f = SuperFlower(user, oldhush) + f.flush_privs() + + return render_template('index.html', name_suggestion=message, pwd_suggestion="...") + + +# @app.route('/migrate', methods=['POST','GET']) +# def migrate(): +# user = 'ignace' +# hush = 'black' +# +# f = SuperFlower(user, hush) +# f.migrate(user) +# +# return render_template('index.html', name_suggestion='login again', pwd_suggestion="...") + +@flower_bp.route('/app' , methods=['POST']) +def web_service(): + # same thing as 'aplication, but returns go in json + result = json.dumps({'result': -1, 'message': 'Invalid entry'}) + + try: + access_ctrl = Access() + if not access_ctrl.granted(request.remote_addr): + result = json.dumps({'result': -1, 'message': 'Access denied'}) + + else: + #no session variables here - the client will take care of fileter and timeout + action = request.form['action'] + user = request.form['name'] + pwd = request.form['password'] + F = Flower(user, pwd) + if F.numberOfEntries() == -1: + #login failure + access_ctrl.deny(request.remote_addr) + result = json.dumps({'result': 0, 'message': 'Invalid username or password'}) + + elif action == 'login': + result = json.dumps({'result': 1, 'message': 'Access granted'}) + + elif action == 'list': + result = json.dumps({'result': 1, 'message': 'Ok', 'list': json.dumps(F.all())}) + + elif action == 'one': + result = json.dumps({'result': 1, 'message': 'Ok', 'flower': json.dumps( F.one(request.form['organization'], request.form['dateCreated']) )}) + + elif action == 'save': + result = json.dumps({'result': 1, 'message': 'Ok', 'flower': json.dumps(F.add(request.form['organization'],request.form['myname'],request.form['myid'],request.form['secret']) )}) + + elif action == 'deactivate': + result = json.dumps({'result': 1, 'message': 'Ok', 'flower': json.dumps(F.deactivate(request.form['organization'], request.form['dateCreated']))}) + + except: + pass + return result + + diff --git a/flowers.py b/flowers.py index fb286a7..27b7940 100644 --- a/flowers.py +++ b/flowers.py @@ -1,200 +1,16 @@ from flask import Flask -from Config import * -import sys -import datetime -import pytz -from FlowerServices import Flower,SuperFlower -from AccessControl import Access -import json -from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash, json, make_response -from werkzeug.exceptions import HTTPException - -# configuration -DEBUG = False -SECRET_KEY = 'development key' +from flower_vase import flower_bp -app = Flask(__name__) -app.config.from_object(__name__) - -@app.route('/') -def index(): - print(request.remote_addr) - return render_template('index.html', name_suggestion="Hello", pwd_suggestion="Want to try your luck?") - -@app.route('/browser' , methods=['POST', 'GET']) -def application(): - now = datetime.datetime.now(pytz.timezone('Europe/Amsterdam')) - - if request.method == 'GET': - return render_template('index.html', name_suggestion="Faded out", pwd_suggestion="Want to retry your luck?") - - access_ctrl = Access() - if not access_ctrl.granted(request.remote_addr): - return render_template('index.html', name_suggestion="Sorry", pwd_suggestion="Access denied") - - action=request.form['action'] - filter='' - if 'filter' in session: - filter = session['filter'] - - if action == 'logout': - session['filter'] = request.form['filter'] - session['timeout'] = now - datetime.timedelta(minutes=999) - return render_template('index.html', name_suggestion="Bye", pwd_suggestion="Come back any time") - - - if action == 'login': - user=request.form['name'] - pwd=request.form['password'] - F = Flower(user, pwd) - if F.numberOfEntries()>=0: - session['dbuser'] = user - session['dbpwd'] = pwd - session['timeout'] = now - session['filter'] = filter - return render_template('list.html', flowers=F.all(), filter=filter) - #login failure - access_ctrl.deny(request.remote_addr) - print("Flowers - authorization failed for {}".format(user)) - return render_template('index.html', name_suggestion="Sorry", pwd_suggestion="Better next time") - - if 'timeout' in session and session['timeout']+datetime.timedelta(minutes=10)>now: - session['timeout'] = now - - if 'filter' in request.form.keys() and len(request.form['filter'])>1 and request.form['filter'] != DONOTSETFILTER: - session['filter']=request.form['filter'] - filter = request.form['filter'] - - F = Flower(session['dbuser'], session['dbpwd']) - if F.numberOfEntries()>=0: - - if action == 'list': - return render_template('list.html', flowers=F.all(), filter=filter) - - if action == 'show': - return render_template('show.html', flower=F.one(request.form['organization'], request.form['datetime'])) - - if action == 'edit': - return render_template('edit.html', flower=F.one(request.form['organization'], request.form['datetime'])) - - if action == 'new': - return render_template('edit.html', flower=F.empty()) - - if action == 'save': - flower = F.add(request.form['organization'],request.form['myname'],request.form['myid'],request.form['secret']) - session['filter']=request.form['organization'] - return render_template('show.html', flower=flower) - - if action == 'deactivate': - flower = F.deactivate(request.form['organization'],request.form['datetime']) - session['filter']='' - return render_template('show.html', flower=flower) - - if action == 'rehush': - return render_template('rehush.html', flower=F.empty()) - - - else: - return render_template('new.html', flower=F.empty()) - - - return render_template('index.html', name_suggestion="Sorry", pwd_suggestion="Better next time") - -@app.route('/create' , methods=['POST','GET']) -def create(): - access_ctrl = Access() - if not access_ctrl.granted(request.remote_addr): - return render_template('index.html', name_suggestion="Sorry", pwd_suggestion="Access denied") - - if 'name' not in request.form: - return render_template('create.html') - newuser = request.form['name'] - newhush = request.form['password'] - - # login db with generic user - f = SuperFlower(newuser, newhush) - if f.createNewTable(): - # login as new user - u = Flower(newuser, newhush) - # add one line - u.add('Demo organisation', 'Demo name', 'Demo login', 'Demo hush') - - # return to the login page - return render_template('index.html', name_suggestion="Now login", pwd_suggestion="for your very first time") - - return render_template('create.html', message="Sorry - System error - check log files") - - -@app.route('/update_pwd', methods=['POST','GET']) -def update_pwd(): - if 'name' not in request.form: - return render_template('rehush.html') - user = request.form['name'] - oldhush = request.form['old_password'] - newhush = request.form['new_password'] - - # login db with generic user - f = Flower(user, oldhush) - message = f.update_pwd(newhush) - - f = SuperFlower(user, oldhush) - f.flush_privs() - - return render_template('index.html', name_suggestion=message, pwd_suggestion="...") - - -# @app.route('/migrate', methods=['POST','GET']) -# def migrate(): -# user = 'ignace' -# hush = 'black' -# -# f = SuperFlower(user, hush) -# f.migrate(user) -# -# return render_template('index.html', name_suggestion='login again', pwd_suggestion="...") - -@app.route('/app' , methods=['POST']) -def web_service(): - # same thing as 'aplication, but returns go in json - result = json.dumps({'result': -1, 'message': 'Invalid entry'}) - - try: - access_ctrl = Access() - if not access_ctrl.granted(request.remote_addr): - result = json.dumps({'result': -1, 'message': 'Access denied'}) - - else: - #no session variables here - the client will take care of fileter and timeout - action = request.form['action'] - user = request.form['name'] - pwd = request.form['password'] - F = Flower(user, pwd) - if F.numberOfEntries() == -1: - #login failure - access_ctrl.deny(request.remote_addr) - result = json.dumps({'result': 0, 'message': 'Invalid username or password'}) - - elif action == 'login': - result = json.dumps({'result': 1, 'message': 'Access granted'}) - - elif action == 'list': - result = json.dumps({'result': 1, 'message': 'Ok', 'list': json.dumps(F.all())}) - - elif action == 'one': - result = json.dumps({'result': 1, 'message': 'Ok', 'flower': json.dumps( F.one(request.form['organization'], request.form['dateCreated']) )}) - - elif action == 'save': - result = json.dumps({'result': 1, 'message': 'Ok', 'flower': json.dumps(F.add(request.form['organization'],request.form['myname'],request.form['myid'],request.form['secret']) )}) - - elif action == 'deactivate': - result = json.dumps({'result': 1, 'message': 'Ok', 'flower': json.dumps(F.deactivate(request.form['organization'], request.form['dateCreated']))}) - - except: - pass - return result +def create_app(): + app = Flask(__name__) + app.config["SECRET_KEY"] = 'adhf adsh 8347y92347rupqo;wjf cowuyergc9b24387ryx1 -923pqr pqwejf qy7i34' + app.register_blueprint(flower_bp) + return app if __name__ == '__main__': - app.secret_key = 'adhf adsh 8347y92347rupqo;wjf cowuyergc9b24387ryx1 -923pqr pqwejf qy7i34' - app.run(host='0.0.0.0', port=8080) + my_app = create_app() + # if needed - initialize data + my_app.run(debug=True, host='127.0.0.1', port=5012) + diff --git a/templates/common.html b/templates/common.html index 15dd417..1c7faef 100644 --- a/templates/common.html +++ b/templates/common.html @@ -9,12 +9,12 @@ {% block title %}Flowers{% endblock %} - - - - - - + + + + + + @@ -42,7 +42,7 @@ {% block content %} {% endblock %} -
+ diff --git a/templates/create.html b/templates/create.html index c80f180..8909a7d 100644 --- a/templates/create.html +++ b/templates/create.html @@ -12,7 +12,7 @@ {% block content %}
- +
diff --git a/templates/edit.html b/templates/edit.html index 73ff705..5db0c19 100644 --- a/templates/edit.html +++ b/templates/edit.html @@ -10,7 +10,7 @@ {% block content %}
- +
diff --git a/templates/index.html b/templates/index.html index 570a9f6..6da3a49 100644 --- a/templates/index.html +++ b/templates/index.html @@ -12,7 +12,7 @@ {% block content %}
- +
diff --git a/templates/rehush.html b/templates/rehush.html index 1a19d2c..aff6838 100644 --- a/templates/rehush.html +++ b/templates/rehush.html @@ -12,7 +12,7 @@ {% block content %}
- +