diff --git a/.gitignore b/.gitignore index 6ecb113..b66682b 100755 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ __pycache__ src/app/sessions/ +logs/ diff --git a/docker-compose.yml b/docker-compose.yml index 890921f..990a9d0 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,5 @@ version: "2" services: - db: build: context: ./mysql @@ -11,11 +10,12 @@ services: app: env_file: - - .env - build: - context: ./src - dockerfile: Dockerfile - + - .env + build: + context: ./src + dockerfile: Dockerfile + volumes: + - ./logs/:/logs/:rw ports: - "80${groupid}:8080" - "4${groupid}:443" @@ -26,10 +26,8 @@ services: ipv4_address: 10.${groupid}.0.6 networks: - backend: driver: bridge ipam: - config: - - subnet: 10.${groupid}.0.0/18 - + config: + - subnet: 10.${groupid}.0.0/18 diff --git a/src/app/main.py b/src/app/main.py index 9fbf7fa..f172d44 100755 --- a/src/app/main.py +++ b/src/app/main.py @@ -1,6 +1,11 @@ from views.app import app +import logging +logging.basicConfig( + filename='/logs/beelance.log', + filemode='a', + level=logging.INFO, +) if __name__ == "__main__": app.run() - diff --git a/src/app/models/project.py b/src/app/models/project.py index 0378bb4..9fbd8c1 100755 --- a/src/app/models/project.py +++ b/src/app/models/project.py @@ -1,6 +1,10 @@ from models.database import db +import logging import mysql.connector +logger = logging.getLogger(__name__) + + def get_categories(): """ Get all categories @@ -14,7 +18,7 @@ def get_categories(): cursor.execute(query) categories = cursor.fetchall() except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) categories = [] cursor.fetchall() exit(1) @@ -23,6 +27,7 @@ def get_categories(): db.close() return categories + def set_project(categoryid, userid, project_title, project_description, project_status): """ Store a project in the database @@ -48,7 +53,7 @@ def set_project(categoryid, userid, project_title, project_description, project_ users_projects = get_projects_by_owner(userid) projectid = users_projects[-1][0] except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) projectid = None cursor.fetchall() exit(1) @@ -57,6 +62,7 @@ def set_project(categoryid, userid, project_title, project_description, project_ db.close() return projectid + def get_project_by_id(projectid): """ Retrieve a project by its id @@ -72,7 +78,7 @@ def get_project_by_id(projectid): cursor.execute(query, (projectid,)) project = cursor.fetchall() except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) project = [] cursor.fetchall() exit(1) @@ -81,6 +87,7 @@ def get_project_by_id(projectid): db.close() return project[0] + def update_project_status(projectid, status): """ Change the status of a selected project @@ -96,13 +103,14 @@ def update_project_status(projectid, status): cursor.execute(query, (status, projectid)) db.commit() except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) cursor.fetchall() exit(1) finally: cursor.close() db.close() + def get_user_permissions(userid, projectid): """ Get permissions for a selected users in a specific project @@ -120,7 +128,7 @@ def get_user_permissions(userid, projectid): cursor.execute(query, (projectid, userid)) permissions = cursor.fetchall() except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) cursor.fetchall() exit(1) finally: @@ -154,7 +162,7 @@ def get_projects_by_status_and_category(categoryid, project_status): cursor.execute(query, (project_status, categoryid)) projects = cursor.fetchall() except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) projects = [] cursor.fetchall() exit(1) @@ -178,7 +186,7 @@ def get_projects_by_owner(userid): cursor.execute(query, (userid,)) projects = cursor.fetchall() except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) projects = [] cursor.fetchall() exit(1) @@ -206,7 +214,7 @@ def get_projects_by_status_and_owner(userid, project_status): cursor.execute(query, (project_status, userid)) projects = cursor.fetchall() except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) projects = [] cursor.fetchall() exit(1) @@ -230,12 +238,11 @@ def get_projects_by_participant_and_status(userid, project_status): cursor = db.cursor() query = ("SELECT * FROM projects, projects_users WHERE projects.project_status = %s AND " + "projects_users.userid = %s AND projects_users.projectid = projects.projectid") - db.connect() try: cursor.execute(query, (project_status, userid)) projects = cursor.fetchall() except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) projects = [] cursor.fetchall() exit(1) @@ -266,7 +273,7 @@ def set_task(projectid, task_title, task_description, budget): cursor.execute(query, (projectid, task_title, task_description, budget)) db.commit() except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) cursor.fetchall() exit(1) finally: @@ -282,7 +289,7 @@ def update_task_status(taskid, status): cursor.execute(query, (status, taskid)) db.commit() except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) cursor.fetchall() exit(1) finally: @@ -305,7 +312,7 @@ def get_tasks_by_project_id(projectid): cursor.execute(query, (projectid,)) tasks = cursor.fetchall() except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) tasks = [] cursor.fetchall() exit(1) @@ -331,7 +338,7 @@ def set_task_file(taskid, filename): cursor.execute(query, (taskid, filename)) db.commit() except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) cursor.fetchall() exit(1) finally: @@ -353,7 +360,7 @@ def get_task_files(taskid): cursor.execute(query, (str(taskid),)) filenames = cursor.fetchall() except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) filenames = [] cursor.fetchall() exit(1) @@ -384,7 +391,7 @@ def set_projects_user(projectid, userid, read_permission="TRUE", cursor.execute(query, (projectid, userid, read_permission, write_permission, modify_permission)) db.commit() except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) cursor.fetchall() exit(1) finally: diff --git a/src/app/models/register.py b/src/app/models/register.py index d416c0b..2be8e1f 100755 --- a/src/app/models/register.py +++ b/src/app/models/register.py @@ -1,6 +1,10 @@ from models.database import db +import logging import mysql.connector +logger = logging.getLogger(__name__) + + def set_user(username, password, full_name, company, email, street_address, city, state, postal_code, country): """ @@ -34,7 +38,7 @@ def set_user(username, password, full_name, company, email, city, state, postal_code, country)) db.commit() except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) cursor.fetchall() exit(1) finally: diff --git a/src/app/models/session.py b/src/app/models/session.py index eb65e25..a92b8a8 100644 --- a/src/app/models/session.py +++ b/src/app/models/session.py @@ -1,6 +1,9 @@ from models.database import db +import logging import mysql.connector +logger = logging.getLogger(__name__) + def set_cookie(userid, token, expiry): """ @@ -16,7 +19,7 @@ def set_cookie(userid, token, expiry): cursor.execute(query, (userid, token, expiry)) db.commit() except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) cursor.fetchall() exit(1) finally: @@ -42,7 +45,7 @@ def get_cookie(token): userid = users[0][0] expiry = users[0][1] except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) cursor.fetchall() exit(1) finally: @@ -65,7 +68,7 @@ def delete_cookie(token): cursor.execute(query, (token,)) db.commit() except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) cursor.fetchall() exit(1) finally: diff --git a/src/app/models/user.py b/src/app/models/user.py index 01a7c98..24dd567 100755 --- a/src/app/models/user.py +++ b/src/app/models/user.py @@ -1,6 +1,9 @@ from models.database import db +import logging import mysql.connector +logger = logging.getLogger(__name__) + def get_user(username): """ @@ -20,7 +23,7 @@ def get_user(username): if len(users): user = users[0] except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) cursor.fetchall() exit(1) finally: @@ -41,7 +44,7 @@ def get_users(): cursor.execute(query) users = cursor.fetchall() except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) users = [] cursor.fetchall() exit(1) @@ -62,7 +65,7 @@ def set_login_attempts(userid, num, timestamp): cursor.execute(query, (num, timestamp, userid)) db.commit() except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) cursor.fetchall() exit(1) finally: @@ -87,7 +90,7 @@ def get_user_id_by_name(username): if(len(users)): userid = users[0][0] except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) cursor.fetchall() exit(1) finally: @@ -112,7 +115,7 @@ def get_user_name_by_id(userid): if len(users): username = users[0][0] except mysql.connector.Error as err: - print("Failed executing query: {}".format(err)) + logger.error("Failed executing query: %s", err) cursor.fetchall() exit(1) finally: diff --git a/src/app/uwsgi.ini b/src/app/uwsgi.ini index 4e79fbd..d4e7c9d 100755 --- a/src/app/uwsgi.ini +++ b/src/app/uwsgi.ini @@ -1,3 +1,4 @@ [uwsgi] module = main -callable = app \ No newline at end of file +callable = app +logto = /logs/uwsgi.log diff --git a/src/app/views/login.py b/src/app/views/login.py index 1c0df3e..bf431c7 100755 --- a/src/app/views/login.py +++ b/src/app/views/login.py @@ -3,11 +3,14 @@ from views.forms import login_form from views.utils import get_nav_bar, csrf_protected import models.session import models.user +import logging import random import string import bcrypt import time +logger = logging.getLogger(__name__) + # Get html templates render = web.template.render('templates/') @@ -60,10 +63,14 @@ class Login(): return render.login(nav, login_form, "- There have been too many incorrect login attempts for your account. You have to wait a minute before you can log in.") if bcrypt.checkpw(data.password.encode('UTF-8'), password_hash.encode('UTF-8')): + if login_attempts > login_attempts_threshold: + logger.info("User %s logged in succesfully after %s attempts", username, login_attempts) + models.user.set_login_attempts(userid, 0, time.time()) self.login(username, userid, data.remember) raise web.seeother("/") else: + logger.warning("Incorrect login attempt on user %s by IP %s", username, web.ctx.ip) models.user.set_login_attempts(userid, login_attempts+1, time.time()) if login_attempts == login_attempts_threshold: return render.login(nav, login_form, "- Too many incorrect login attempts. You have to wait a minute before trying again.") diff --git a/src/app/views/register.py b/src/app/views/register.py index 2853052..c4108a0 100755 --- a/src/app/views/register.py +++ b/src/app/views/register.py @@ -3,9 +3,12 @@ from views.forms import register_form from views.utils import get_nav_bar, csrf_protected, password_weakness import models.register import models.user +import logging import bcrypt import re +logger = logging.getLogger(__name__) + # Get html templates render = web.template.render('templates/') @@ -52,4 +55,5 @@ class Register: data.email, data.street_address, data.city, data.state, data.postal_code, data.country) + logger.info("User %s registered", data.username) return render.register(nav, register_form, "User registered!") diff --git a/src/entrypoint.sh b/src/entrypoint.sh index 33c032d..d5b7259 100755 --- a/src/entrypoint.sh +++ b/src/entrypoint.sh @@ -24,6 +24,8 @@ content_server=$content_server' }\n' content_server=$content_server" location $USE_STATIC_URL {\n" content_server=$content_server" alias $USE_STATIC_PATH;\n" content_server=$content_server' }\n' +content_server=$content_server" error_log /logs/error_log_http.log warn;\n" +content_server=$content_server" access_log /logs/access_log_http.log;\n" content_server=$content_server'}\n' @@ -44,6 +46,8 @@ content_server=$content_server' }\n' content_server=$content_server" location $USE_STATIC_URL {\n" content_server=$content_server" alias $USE_STATIC_PATH;\n" content_server=$content_server' }\n' +content_server=$content_server" error_log /logs/error_log_https.log warn;\n" +content_server=$content_server" access_log /logs/access_log_https.log;\n" content_server=$content_server'}\n'