diff --git a/.circleci/config.yml b/.circleci/config.yml index a724e2b..9ed16d6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,17 +9,27 @@ jobs: # specify the version you desire here # use `-browsers` prefix for selenium tests, e.g. `3.6.1-browsers` - image: circleci/python:2.7 + environment: + POSTGRES_PASSWORD: totallyHacked1337 + POSTGRES_USER: imagehost + POSTGRES_DB: imagehost_db + POSTGRES_HOST: localhost # Specify service dependencies here if necessary # CircleCI maintains a library of pre-built images # documented at https://circleci.com/docs/2.0/circleci-images/ - - image: circleci/postgres:9.4 + #- image: circleci/postgres:9.4 working_directory: ~/repo steps: - checkout + # Set up Test DB + - run: sudo apt install postgresql-client-9.4 postgresql-9.4 + - run: sudo /etc/init.d/postgresql start + - run: sudo ${HOME}/repo/newdb.sh + # Download and cache dependencies - restore_cache: keys: @@ -39,6 +49,14 @@ jobs: - ./venv key: v1-dependencies-{{ checksum "requirements.txt" }} + + # Migrate our database (if needed) + - run: + name: run migration + command: | + . venv/bin/activate + python manage.py migrate + # run tests! # this example uses Django's built-in test-runner # other common Python testing frameworks include pytest and nose diff --git a/docker-compose.yaml b/docker-compose.yaml index 1aaa81e..7cc5359 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -16,6 +16,10 @@ services: build: . environment: PORTAL_DEBUG: 'true' + POSTGRES_PASSWORD: totallyHacked1337 + POSTGRES_USER: imagehost + POSTGRES_DB: imagehost_db + POSTGRES_HOST: postgres volumes: - .:/portal ports: diff --git a/gallery/gzip.py b/gallery/gzip.py new file mode 100644 index 0000000..fe9cd7c --- /dev/null +++ b/gallery/gzip.py @@ -0,0 +1,27 @@ +import logging +from StringIO import StringIO +import zlib +class UnzipRequestMiddleware(object): + """A middleware that unzips POSTed data. + + For this middleware to kick in, the client must provide a value + for the ``Content-Encoding`` header. The only accepted value is + ``gzip``. Any other value is ignored. + """ + + def __init__(self, app): + self.app = app + + def __call__(self, environ, start_response): + encoding = environ.get('HTTP_CONTENT_ENCODING') + if encoding == 'gzip': + data = environ['wsgi.input'].read() + try: + uncompressed = zlib.decompress(data, 31) + environ['wsgi.input'] = StringIO(uncompressed) + environ['CONTENT_LENGTH'] = len(uncompressed) + except zlib.error: + logging.warning(u"Could not decompress request data.", exc_info=True) + environ['wsgi.input'] = StringIO(data) + return self.app(environ, start_response) + diff --git a/gallery/settings.py b/gallery/settings.py index db66ae3..a0a7627 100644 --- a/gallery/settings.py +++ b/gallery/settings.py @@ -15,7 +15,6 @@ import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ @@ -23,10 +22,21 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) SECRET_KEY = '^2)m5jqumpm6-1io$18tjwo@dnukf=r-kl#8&q1#qf!&(&y_6h' # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True +DEBUG = os.environ.get('PORTAL_DEBUG', 'false').lower() == 'true' -ALLOWED_HOSTS = [] +ALLOWED_HOSTS = ['*'] +if DEBUG: + INTERNAL_IPS = ('localhost',) + +# SMTP server/relay to send error emails (to ADMINS) from +ADMINS = [('c0de', 'c0de@c0defox.es')] +SERVER_EMAIL = 'portal@imagehost' +EMAIL_HOST = '' +EMAIL_USE_TLS = True +EMAIL_PORT = 587 +EMAIL_HOST_USER = '' +EMAIL_HOST_PASSWORD = '' # Application definition @@ -37,9 +47,21 @@ INSTALLED_APPS = [ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'rest_framework', + 'inline_actions', ] +if DEBUG: + INSTALLED_APPS += [ + 'debug_panel' + ] + +REST_FRAMEWORK = { + 'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAuthenticated',), + 'PAGE_SIZE': 10 +} MIDDLEWARE = [ + 'django.middleware.gzip.GZipMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', @@ -48,6 +70,9 @@ MIDDLEWARE = [ 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] +if DEBUG: + MIDDLEWARE[2:0] = [ + 'debug_panel.middleware.DebugPanelMiddleware'] ROOT_URLCONF = 'gallery.urls' @@ -75,8 +100,12 @@ WSGI_APPLICATION = 'gallery.wsgi.application' DATABASES = { 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': os.environ.get('POSTGRES_DB', ''), + 'USER': os.environ.get('POSTGRES_USER', 'root'), + 'PASSWORD': os.environ.get('POSTGRES_PASSWORD', ''), + 'HOST': os.environ.get('POSTGRES_HOST', 'postgres').lower(), + 'PORT': '', } } diff --git a/gallery/utility.py b/gallery/utility.py new file mode 100644 index 0000000..caf583a --- /dev/null +++ b/gallery/utility.py @@ -0,0 +1,29 @@ +from django.http import HttpResponse +from django.template import loader +from django.contrib import auth + +# Usage: +# template - relative path to the template you wish to render +# request - The request object for the user +# message - An optional message to me shown to the user, set to None or '' +# context - A dictionary of arbitrary key-value combos for use in the App +def _ResponseTemplate(template, request, message='', context=None): + if isinstance(context, dict) and \ + not (context.get('message', False)): + context['message'] = str(message) + elif isinstance(context, dict) and \ + (context.get('message', False)): + context['message'] += ' -- ' + str(message) + else: + context = { + 'message': str(message) + } + + template = loader.get_template(str(template)) + return HttpResponse(template.render(context, request)) + +# Logs out a user, sending them to the login screen with an optional message and context +# Same arguments as _ResponseTemplate, except for the template +def _ForceLogout(request, message='', context=None): + auth.logout(request) + return _ResponseTemplate('account/login.html', request, message, context) diff --git a/newdb.sh b/newdb.sh new file mode 100755 index 0000000..bb03c66 --- /dev/null +++ b/newdb.sh @@ -0,0 +1,2 @@ +#!/bin/bash +su postgres -c "psql < newdb.sql" \ No newline at end of file diff --git a/newdb.sql b/newdb.sql new file mode 100644 index 0000000..92baa98 --- /dev/null +++ b/newdb.sql @@ -0,0 +1,2 @@ +CREATE USER imagehost WITH SUPERUSER CREATEDB LOGIN PASSWORD 'totallyHacked1337'; +CREATE DATABASE imagehost_db OWNER imagehost;