| @@ -11,6 +11,7 @@ WORKDIR /app | |||
| ENV PYTHONPATH=/app | |||
| # Install python dependencies | |||
| RUN pip install --upgrade pip | |||
| RUN pip install --no-cache-dir -r requirements.txt | |||
| # Move the base entrypoint to reuse it | |||
| @@ -133,6 +133,10 @@ def get_user_permissions(userid, projectid): | |||
| return [0, 0, 0] | |||
| def is_owner(userid, projectid): | |||
| return projectid in get_projects_by_owner(userid) | |||
| def get_projects_by_status_and_category(categoryid, project_status): | |||
| """ | |||
| Retrieve all projects from a category with a specific status | |||
| @@ -21,6 +21,9 @@ except: | |||
| # Example use of the smtp server, insert username | |||
| # web.sendmail("beelance@ntnu.no", "<username>@stud.ntnu.no", "Hello", "Grz, the beelance app is running") | |||
| # Disable the debug error page | |||
| web.config.debug = False | |||
| # Define application routes | |||
| urls = ( | |||
| '/', 'Index', | |||
| @@ -8,8 +8,8 @@ import models.user | |||
| # Get html templates | |||
| render = web.template.render('templates/') | |||
| class New_project: | |||
| class New_project: | |||
| def GET(self): | |||
| """ | |||
| Get the project registration form | |||
| @@ -60,7 +60,6 @@ class New_project: | |||
| # Post the form data and save the project in the database | |||
| if data.create_project: | |||
| project_form = self.compose_form(data, None) | |||
| if not project_form.validates(): | |||
| return render.new_project(nav, project_form, project_buttons, "") | |||
| @@ -89,28 +88,28 @@ class New_project: | |||
| # Save the users in the database given that the input field is not empty | |||
| for i in range(0, user_count): | |||
| if len(data["user_name_"+str(i)]): | |||
| userid = models.user.get_user_id_by_name(data["user_name_"+str(i)]) | |||
| read, write, modify = "FALSE", "FALSE", "FALSE" | |||
| try: | |||
| data["read_permission_"+str(i)] | |||
| read = "TRUE" | |||
| except Exception as e: | |||
| read = "FALSE" | |||
| pass | |||
| try: | |||
| data["write_permission_"+str(i)] | |||
| write = "TRUE" | |||
| except Exception as e: | |||
| write = "FALSE" | |||
| pass | |||
| try: | |||
| data["modify_permission_"+str(i)] | |||
| modify = "TRUE" | |||
| except Exception as e: | |||
| modify = "FALSE" | |||
| pass | |||
| models.project.set_projects_user(str(projectid), str(userid), read, write, modify) | |||
| if len(data["user_name_"+str(i)]): | |||
| userid = models.user.get_user_id_by_name(data["user_name_"+str(i)]) | |||
| read, write, modify = "FALSE", "FALSE", "FALSE" | |||
| try: | |||
| data["read_permission_"+str(i)] | |||
| read = "TRUE" | |||
| except Exception as e: | |||
| read = "FALSE" | |||
| pass | |||
| try: | |||
| data["write_permission_"+str(i)] | |||
| write = "TRUE" | |||
| except Exception as e: | |||
| write = "FALSE" | |||
| pass | |||
| try: | |||
| data["modify_permission_"+str(i)] | |||
| modify = "TRUE" | |||
| except Exception as e: | |||
| modify = "FALSE" | |||
| pass | |||
| models.project.set_projects_user(str(projectid), str(userid), read, write, modify) | |||
| raise web.seeother('/?projects=my') | |||
| def compose_form(self, data, operation): | |||
| @@ -5,17 +5,17 @@ from models.project import get_categories, get_projects_by_status_and_category | |||
| # Get html templates | |||
| render = web.template.render('templates/') | |||
| class Open_projects: | |||
| def GET(self): | |||
| """ | |||
| Get all open projects | |||
| Get all open projects | |||
| :return: A page containing all open projects | |||
| """ | |||
| session = web.ctx.session | |||
| data = web.input(categoryid=0) | |||
| open_projects=[] | |||
| open_projects = [] | |||
| if data.categoryid != 0: | |||
| open_projects = get_projects_by_status_and_category(data.categoryid, "open") | |||
| nav = get_nav_bar(session) | |||
| @@ -28,7 +28,7 @@ class Project: | |||
| try: | |||
| permissions = models.project.get_user_permissions(str(session.userid), data.projectid) | |||
| except: | |||
| permissions = [0,0,0] | |||
| permissions = [0, 0, 0] | |||
| categories = models.project.get_categories() | |||
| @@ -48,15 +48,16 @@ class Project: | |||
| data = web.input(myfile={}, deliver=None, accepted=None, declined=None, projectid=0) | |||
| fileitem = data['myfile'] | |||
| permissions = models.project.get_user_permissions(str(session.userid), data.projectid) | |||
| read_permission, write_permission, modify_permission = models.project.get_user_permissions(str(session.userid), data.projectid) | |||
| categories = models.project.get_categories() | |||
| tasks = models.project.get_tasks_by_project_id(data.projectid) | |||
| is_owner = models.project.is_owner(session.userid, data.projectid) | |||
| # Upload file (if present) | |||
| try: | |||
| if fileitem.filename: | |||
| # Check if user has write permission | |||
| if not permissions[1]: | |||
| if not write_permission: | |||
| raise web.seeother(('/project?projectid=' + data.projectid)) | |||
| fn = fileitem.filename | |||
| @@ -89,11 +90,11 @@ class Project: | |||
| task_delivered = True | |||
| # Deliver task | |||
| if data.deliver and not task_delivered: | |||
| if data.deliver and not task_delivered and modify_permission: | |||
| models.project.update_task_status(data.taskid, "delivered") | |||
| # Accept task delivery | |||
| elif data.accepted: | |||
| elif data.accepted and is_owner: | |||
| models.project.update_task_status(data.taskid, "accepted") | |||
| # If all tasks are accepted then update project status to finished | |||
| @@ -106,7 +107,7 @@ class Project: | |||
| models.project.update_project_status(str(data.projectid), "finished") | |||
| # Decline task delivery | |||
| elif data.declined: | |||
| elif data.declined and is_owner: | |||
| models.project.update_task_status(data.taskid, "declined") | |||
| raise web.seeother(('/project?projectid=' + data.projectid)) | |||
| @@ -15,6 +15,8 @@ USE_LISTEN_PORT=${LISTEN_PORT:-8080} | |||
| #else | |||
| content_server='server {\n' | |||
| content_server=$content_server" listen ${USE_LISTEN_PORT};\n" | |||
| content_server=$content_server' add_header X-Frame-Options deny always;\n' | |||
| content_server=$content_server' add_header X-Content-Type-Options nosniff always;\n' | |||
| content_server=$content_server' location / {\n' | |||
| content_server=$content_server' include uwsgi_params;\n' | |||
| content_server=$content_server' uwsgi_pass unix:///tmp/uwsgi.sock;\n' | |||
| @@ -29,6 +31,8 @@ content_server=$content_server'}\n' | |||
| # https://nginx.org/en/docs/http/configuring_https_servers.html | |||
| content_server=$content_server'server {\n' | |||
| content_server=$content_server" listen 443 ssl http2;\n" | |||
| content_server=$content_server' add_header X-Frame-Options deny always;\n' | |||
| content_server=$content_server' add_header X-Content-Type-Options nosniff always;\n' | |||
| content_server=$content_server' ssl_certificate /app/selfsigned.crt;\n' | |||
| content_server=$content_server' ssl_certificate_key /app/selfsigned.key;\n' | |||
| content_server=$content_server' ssl_protocols TLSv1 TLSv1.1 TLSv1.2;\n' | |||