From 6073a944a27f1ba58a7ea79da8cf24d74d96260f Mon Sep 17 00:00:00 2001 From: Zebula Sampedro Date: Tue, 22 May 2018 15:54:42 -0600 Subject: [PATCH 01/49] Issues/300 (#312) * Starting to containerize and compose infrastructure. * Got dev stack working under Compose. * Added PhantomJS and prerequisites for test env. * Added prod config to compose stack. * Working prod config. * Separated out test backends for layering on dev and staging deployments. * Moved media uploads directory to a volume, toggle media dev endpoint. * Added gosu entrypoint to properly set permissions on shared volumes. * Toggle entire test suite with debug, closes #302. * Store logs in docker volumes. * Restructured dev config for CI. * Don't require SSH for submodule * Always log to volume. * Added Travis config. * Disabled build notifications for now, updated docker-compose in Travis CI environment. * Override script and install tags. * Added encrypted notifier token to Travis build config. * Updated token. * Revert "Updated token." This reverts commit 66e14e14cceea4d7abcb11d141eba5af020bf1c2. * Updated Slack config. * Refactored environment variables. --- .gitignore | 6 + .gitmodules | 3 + .travis.yml | 25 +++ LICENSE | 2 +- README.md | 43 ++-- docker-compose.dev.yml | 19 ++ docker-compose.prod.yml | 39 ++++ docker-compose.test-backends.yml | 14 ++ docker-compose.yml | 21 ++ nginx/nginx.conf | 64 ++++++ nginx/uwsgi_params | 13 ++ rcamp/Dockerfile | 58 ++++++ rcamp/Dockerfile.test | 18 ++ rcamp/docker-entrypoint.sh | 13 ++ rcamp/ldapdb | 1 + rcamp/{ => rcamp}/accounts/__init__.py | 0 rcamp/{ => rcamp}/accounts/admin.py | 0 rcamp/{ => rcamp}/accounts/forms.py | 0 .../accounts/management/__init__.py | 0 .../accounts/management/commands/__init__.py | 0 .../management/commands/givesuperuser.py | 18 +- .../management/commands/syncldapusers.py | 0 .../management/commands/transformdatadump.py | 0 .../accounts/migrations/0001_initial.py | 0 .../migrations/0002_auto_20171213_1604.py | 0 .../migrations/0003_auto_20180228_1158.py | 0 .../accounts/migrations/__init__.py | 0 rcamp/{ => rcamp}/accounts/models.py | 0 .../templates/account-request-intent.html | 0 .../templates/account-request-org-select.html | 0 .../templates/account-request-review.html | 0 .../templates/account-request-verify-csu.html | 0 .../templates/account-request-verify-ucb.html | 0 rcamp/{ => rcamp}/accounts/urls.py | 0 rcamp/{ => rcamp}/accounts/views.py | 0 rcamp/rcamp/dev_settings.py | 106 ---------- rcamp/{ => rcamp}/endpoints/__init__.py | 0 rcamp/{ => rcamp}/endpoints/filters.py | 0 rcamp/{ => rcamp}/endpoints/serializers.py | 0 rcamp/{ => rcamp}/endpoints/urls.py | 0 rcamp/{ => rcamp}/endpoints/viewsets.py | 0 rcamp/{ => rcamp}/lib/__init__.py | 0 rcamp/{ => rcamp}/lib/fields.py | 0 rcamp/{ => rcamp}/lib/ldap_utils.py | 0 rcamp/{ => rcamp}/lib/pam_backend.py | 0 rcamp/{ => rcamp}/lib/router.py | 0 rcamp/{ => rcamp}/lib/views.py | 0 rcamp/{lib/test => rcamp/mailer}/__init__.py | 0 rcamp/{ => rcamp}/mailer/admin.py | 0 .../mailer/migrations/0001_initial.py | 0 .../mailer/migrations}/__init__.py | 0 rcamp/{ => rcamp}/mailer/models.py | 0 rcamp/{ => rcamp}/mailer/receivers.py | 0 rcamp/{ => rcamp}/mailer/signals.py | 0 rcamp/{ => rcamp}/manage.py | 0 .../migrations => rcamp/projects}/__init__.py | 0 rcamp/{ => rcamp}/projects/admin.py | 0 rcamp/{ => rcamp}/projects/forms.py | 0 .../projects/management}/__init__.py | 0 .../projects/management/commands}/__init__.py | 0 .../projects/migrations/0001_initial.py | 0 .../migrations/0002_auto_20180326_1507.py | 0 .../migrations/0003_auto_20180326_1508.py | 0 .../migrations/0004_auto_20180326_1529.py | 0 .../projects/migrations}/__init__.py | 0 rcamp/{ => rcamp}/projects/models.py | 0 rcamp/{ => rcamp}/projects/receivers.py | 0 .../templates/allocation-request-create.html | 0 .../templates/allocation-request-detail.html | 0 .../projects/templates/project-create.html | 0 .../projects/templates/project-detail.html | 0 .../projects/templates/project-edit.html | 0 .../projects/templates/project-list.html | 0 .../projects/templates/reference-create.html | 0 .../projects/templates/reference-detail.html | 0 .../projects/templates/reference-edit.html | 0 rcamp/{ => rcamp}/projects/urls.py | 0 rcamp/{ => rcamp}/projects/views.py | 0 rcamp/rcamp/{ => rcamp}/.bowerrc | 0 .../migrations => rcamp/rcamp}/__init__.py | 0 rcamp/rcamp/{ => rcamp}/bower.json | 0 rcamp/rcamp/rcamp/settings/__init__.py | 5 + rcamp/rcamp/rcamp/settings/auth.py | 13 ++ rcamp/rcamp/rcamp/settings/databases.py | 96 +++++++++ rcamp/rcamp/rcamp/settings/logging.py | 42 ++++ rcamp/rcamp/rcamp/settings/main.py | 110 +++++++++++ rcamp/rcamp/rcamp/settings/organizations.py | 31 +++ rcamp/rcamp/rcamp/settings/toggles.py | 3 + .../static/css/account-request.css | 0 .../{ => rcamp}/static/css/jumbotron.css | 0 rcamp/rcamp/{ => rcamp}/static/css/login.css | 0 .../{ => rcamp}/static/css/project-create.css | 0 .../rcamp/{ => rcamp}/static/css/projects.css | 0 rcamp/rcamp/{ => rcamp}/static/css/rcamp.css | 0 .../rcamp/{ => rcamp}/static/css/selector.css | 0 rcamp/rcamp/{ => rcamp}/static/img/._logo.png | Bin .../static/img/coolaisle-blue-cmp.jpg | Bin rcamp/rcamp/{ => rcamp}/static/img/logo.png | Bin .../static/img/memory-heatmap-cmp.jpg | Bin .../{ => rcamp}/static/img/molecule-cmp.jpg | Bin .../{ => rcamp}/static/js/SelectFilter2.js | 0 rcamp/rcamp/{ => rcamp}/static/js/jsi18n.js | 0 rcamp/rcamp/{ => rcamp}/templates/404.html | 0 rcamp/rcamp/{ => rcamp}/templates/500.html | 0 rcamp/rcamp/{ => rcamp}/templates/base.html | 0 rcamp/rcamp/{ => rcamp}/templates/index.html | 0 rcamp/rcamp/{ => rcamp}/templates/login.html | 0 rcamp/rcamp/{ => rcamp}/templates/logout.html | 0 .../templates/terms-and-conditions.html | 0 rcamp/rcamp/{ => rcamp}/urls.py | 5 + rcamp/rcamp/{ => rcamp}/wsgi.py | 0 .../rcamp/requirements.txt | 2 +- rcamp/rcamp/settings.py | 183 ------------------ rcamp/rcamp/{ => tests}/__init__.py | 0 .../tests/test_accounts_commands.py} | 4 +- .../tests/test_accounts_forms.py} | 2 +- .../tests/test_accounts_functional.py} | 4 +- .../tests/test_accounts_models.py} | 4 +- .../tests/test_accounts_views.py} | 4 +- .../tests/test_endpoints.py} | 2 +- .../tests/test_lib_auth.py} | 2 +- .../tests/test_lib_ldap_utils.py} | 2 +- .../tests.py => rcamp/tests/test_mailer.py} | 0 .../tests/test_projects_functional.py} | 4 +- .../tests/test_projects_models.py} | 2 +- .../tests/test_projects_receivers.py} | 4 +- .../tests/test_projects_views.py} | 2 +- rcamp/rcamp/tests/utilities/__init__.py | 0 .../tests/utilities}/functional.py | 2 +- .../test => rcamp/tests/utilities}/ldap.py | 2 +- .../test => rcamp/tests/utilities}/utils.py | 13 +- rcamp/uwsgi.ini | 12 ++ 132 files changed, 678 insertions(+), 340 deletions(-) create mode 100644 .gitmodules create mode 100644 .travis.yml create mode 100644 docker-compose.dev.yml create mode 100644 docker-compose.prod.yml create mode 100644 docker-compose.test-backends.yml create mode 100644 docker-compose.yml create mode 100644 nginx/nginx.conf create mode 100644 nginx/uwsgi_params create mode 100644 rcamp/Dockerfile create mode 100644 rcamp/Dockerfile.test create mode 100644 rcamp/docker-entrypoint.sh create mode 160000 rcamp/ldapdb rename rcamp/{ => rcamp}/accounts/__init__.py (100%) rename rcamp/{ => rcamp}/accounts/admin.py (100%) rename rcamp/{ => rcamp}/accounts/forms.py (100%) rename rcamp/{ => rcamp}/accounts/management/__init__.py (100%) rename rcamp/{ => rcamp}/accounts/management/commands/__init__.py (100%) rename rcamp/{ => rcamp}/accounts/management/commands/givesuperuser.py (82%) rename rcamp/{ => rcamp}/accounts/management/commands/syncldapusers.py (100%) rename rcamp/{ => rcamp}/accounts/management/commands/transformdatadump.py (100%) rename rcamp/{ => rcamp}/accounts/migrations/0001_initial.py (100%) rename rcamp/{ => rcamp}/accounts/migrations/0002_auto_20171213_1604.py (100%) rename rcamp/{ => rcamp}/accounts/migrations/0003_auto_20180228_1158.py (100%) rename rcamp/{ => rcamp}/accounts/migrations/__init__.py (100%) rename rcamp/{ => rcamp}/accounts/models.py (100%) rename rcamp/{ => rcamp}/accounts/templates/account-request-intent.html (100%) rename rcamp/{ => rcamp}/accounts/templates/account-request-org-select.html (100%) rename rcamp/{ => rcamp}/accounts/templates/account-request-review.html (100%) rename rcamp/{ => rcamp}/accounts/templates/account-request-verify-csu.html (100%) rename rcamp/{ => rcamp}/accounts/templates/account-request-verify-ucb.html (100%) rename rcamp/{ => rcamp}/accounts/urls.py (100%) rename rcamp/{ => rcamp}/accounts/views.py (100%) delete mode 100644 rcamp/rcamp/dev_settings.py rename rcamp/{ => rcamp}/endpoints/__init__.py (100%) rename rcamp/{ => rcamp}/endpoints/filters.py (100%) rename rcamp/{ => rcamp}/endpoints/serializers.py (100%) rename rcamp/{ => rcamp}/endpoints/urls.py (100%) rename rcamp/{ => rcamp}/endpoints/viewsets.py (100%) rename rcamp/{ => rcamp}/lib/__init__.py (100%) rename rcamp/{ => rcamp}/lib/fields.py (100%) rename rcamp/{ => rcamp}/lib/ldap_utils.py (100%) rename rcamp/{ => rcamp}/lib/pam_backend.py (100%) rename rcamp/{ => rcamp}/lib/router.py (100%) rename rcamp/{ => rcamp}/lib/views.py (100%) rename rcamp/{lib/test => rcamp/mailer}/__init__.py (100%) rename rcamp/{ => rcamp}/mailer/admin.py (100%) rename rcamp/{ => rcamp}/mailer/migrations/0001_initial.py (100%) rename rcamp/{mailer => rcamp/mailer/migrations}/__init__.py (100%) rename rcamp/{ => rcamp}/mailer/models.py (100%) rename rcamp/{ => rcamp}/mailer/receivers.py (100%) rename rcamp/{ => rcamp}/mailer/signals.py (100%) rename rcamp/{ => rcamp}/manage.py (100%) rename rcamp/{mailer/migrations => rcamp/projects}/__init__.py (100%) rename rcamp/{ => rcamp}/projects/admin.py (100%) rename rcamp/{ => rcamp}/projects/forms.py (100%) rename rcamp/{projects => rcamp/projects/management}/__init__.py (100%) rename rcamp/{projects/management => rcamp/projects/management/commands}/__init__.py (100%) rename rcamp/{ => rcamp}/projects/migrations/0001_initial.py (100%) rename rcamp/{ => rcamp}/projects/migrations/0002_auto_20180326_1507.py (100%) rename rcamp/{ => rcamp}/projects/migrations/0003_auto_20180326_1508.py (100%) rename rcamp/{ => rcamp}/projects/migrations/0004_auto_20180326_1529.py (100%) rename rcamp/{projects/management/commands => rcamp/projects/migrations}/__init__.py (100%) rename rcamp/{ => rcamp}/projects/models.py (100%) rename rcamp/{ => rcamp}/projects/receivers.py (100%) rename rcamp/{ => rcamp}/projects/templates/allocation-request-create.html (100%) rename rcamp/{ => rcamp}/projects/templates/allocation-request-detail.html (100%) rename rcamp/{ => rcamp}/projects/templates/project-create.html (100%) rename rcamp/{ => rcamp}/projects/templates/project-detail.html (100%) rename rcamp/{ => rcamp}/projects/templates/project-edit.html (100%) rename rcamp/{ => rcamp}/projects/templates/project-list.html (100%) rename rcamp/{ => rcamp}/projects/templates/reference-create.html (100%) rename rcamp/{ => rcamp}/projects/templates/reference-detail.html (100%) rename rcamp/{ => rcamp}/projects/templates/reference-edit.html (100%) rename rcamp/{ => rcamp}/projects/urls.py (100%) rename rcamp/{ => rcamp}/projects/views.py (100%) rename rcamp/rcamp/{ => rcamp}/.bowerrc (100%) rename rcamp/{projects/migrations => rcamp/rcamp}/__init__.py (100%) rename rcamp/rcamp/{ => rcamp}/bower.json (100%) create mode 100644 rcamp/rcamp/rcamp/settings/__init__.py create mode 100644 rcamp/rcamp/rcamp/settings/auth.py create mode 100644 rcamp/rcamp/rcamp/settings/databases.py create mode 100644 rcamp/rcamp/rcamp/settings/logging.py create mode 100644 rcamp/rcamp/rcamp/settings/main.py create mode 100644 rcamp/rcamp/rcamp/settings/organizations.py create mode 100644 rcamp/rcamp/rcamp/settings/toggles.py rename rcamp/rcamp/{ => rcamp}/static/css/account-request.css (100%) rename rcamp/rcamp/{ => rcamp}/static/css/jumbotron.css (100%) rename rcamp/rcamp/{ => rcamp}/static/css/login.css (100%) rename rcamp/rcamp/{ => rcamp}/static/css/project-create.css (100%) rename rcamp/rcamp/{ => rcamp}/static/css/projects.css (100%) rename rcamp/rcamp/{ => rcamp}/static/css/rcamp.css (100%) rename rcamp/rcamp/{ => rcamp}/static/css/selector.css (100%) rename rcamp/rcamp/{ => rcamp}/static/img/._logo.png (100%) rename rcamp/rcamp/{ => rcamp}/static/img/coolaisle-blue-cmp.jpg (100%) rename rcamp/rcamp/{ => rcamp}/static/img/logo.png (100%) rename rcamp/rcamp/{ => rcamp}/static/img/memory-heatmap-cmp.jpg (100%) rename rcamp/rcamp/{ => rcamp}/static/img/molecule-cmp.jpg (100%) rename rcamp/rcamp/{ => rcamp}/static/js/SelectFilter2.js (100%) rename rcamp/rcamp/{ => rcamp}/static/js/jsi18n.js (100%) rename rcamp/rcamp/{ => rcamp}/templates/404.html (100%) rename rcamp/rcamp/{ => rcamp}/templates/500.html (100%) rename rcamp/rcamp/{ => rcamp}/templates/base.html (100%) rename rcamp/rcamp/{ => rcamp}/templates/index.html (100%) rename rcamp/rcamp/{ => rcamp}/templates/login.html (100%) rename rcamp/rcamp/{ => rcamp}/templates/logout.html (100%) rename rcamp/rcamp/{ => rcamp}/templates/terms-and-conditions.html (100%) rename rcamp/rcamp/{ => rcamp}/urls.py (89%) rename rcamp/rcamp/{ => rcamp}/wsgi.py (100%) rename requirements.txt => rcamp/rcamp/requirements.txt (84%) delete mode 100644 rcamp/rcamp/settings.py rename rcamp/rcamp/{ => tests}/__init__.py (100%) rename rcamp/{accounts/test_commands.py => rcamp/tests/test_accounts_commands.py} (86%) rename rcamp/{accounts/test_forms.py => rcamp/tests/test_accounts_forms.py} (99%) rename rcamp/{accounts/test_functional.py => rcamp/tests/test_accounts_functional.py} (99%) rename rcamp/{accounts/test_models.py => rcamp/tests/test_accounts_models.py} (99%) rename rcamp/{accounts/test_views.py => rcamp/tests/test_accounts_views.py} (99%) rename rcamp/{endpoints/tests.py => rcamp/tests/test_endpoints.py} (99%) rename rcamp/{lib/test_auth.py => rcamp/tests/test_lib_auth.py} (98%) rename rcamp/{lib/test_ldap_utils.py => rcamp/tests/test_lib_ldap_utils.py} (98%) rename rcamp/{mailer/tests.py => rcamp/tests/test_mailer.py} (100%) rename rcamp/{projects/test_functional.py => rcamp/tests/test_projects_functional.py} (98%) rename rcamp/{projects/test_models.py => rcamp/tests/test_projects_models.py} (99%) rename rcamp/{projects/test_receivers.py => rcamp/tests/test_projects_receivers.py} (97%) rename rcamp/{projects/test_views.py => rcamp/tests/test_projects_views.py} (99%) create mode 100644 rcamp/rcamp/tests/utilities/__init__.py rename rcamp/{lib/test => rcamp/tests/utilities}/functional.py (99%) rename rcamp/{lib/test => rcamp/tests/utilities}/ldap.py (98%) rename rcamp/{lib/test => rcamp/tests/utilities}/utils.py (88%) create mode 100644 rcamp/uwsgi.ini diff --git a/.gitignore b/.gitignore index bf8f2ad..4cba4d3 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,9 @@ docs/_build/ # PyBuilder target/ + +# Docker stuff: +.env +certs/ +db/ +media/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..b2304bd --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "rcamp/ldapdb"] + path = rcamp/ldapdb + url = https://github.com/ResearchComputing/django-ldapdb.git diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..e8a0ac3 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,25 @@ +sudo: required + +language: python + +services: + - docker + +before_install: +- pip install --upgrade docker-compose +- cd rcamp +- docker build -t dev/rcamp --build-arg UWSGI_UID=$(id -u) --build-arg UWSGI_GID=$(id -u) . +- cd .. +- export RCAMP_PORT=9000 +- docker-compose -f docker-compose.yml -f docker-compose.test-backends.yml -f docker-compose.dev.yml build +- docker-compose -f docker-compose.yml -f docker-compose.test-backends.yml -f docker-compose.dev.yml run --rm --service-ports rcamp-uwsgi bash -c 'sleep 30s && python manage.py migrate' +- docker-compose -f docker-compose.yml -f docker-compose.test-backends.yml -f docker-compose.dev.yml run --rm --service-ports rcamp-uwsgi bash -c 'python manage.py test' + +install: true +script: true + +notifications: + email: false + slack: + rooms: + secure: sEWHI86XLXXuVAQd15UbDMPpDKop/bTDn/XynrLKqp+GF+28h8BtewVZXCMHHir3ZCFdb2oRqG1qJ+g3kr8AY5xCadt8xu7BYZTAbGJdlv4tqTuGCNdUTr60wkafmvqYx2UZuawTLLAfy31bgzfGcpq068ni0MxYIn4PNJq0lqcUZoFvhlTT5lXrBWhu7q4JCTvfCBni/shjWKW8zmP5QP1GXSpPeHI9AZmBr2luczc2izVJbyTPEipNk1a57l8D5MeAGz+LE8AkXgbd3yl3KWgU+ZgUd8Jga09B9oARBBqG/1sVb1pCAkQQ2qDd+nByNfkPbcOn0LXhT6LM8sX/HVi7NZD1byB/u6qiycmDvf2rb+7Xz7Z2/eN4Rycf5+3JBuKCg2eFbX0Beo3RLJgmn+dYbWqD3YRAupv8nwZci2Km6AS3cWJi3HhQK85r6xGrmWdW5yqMxbaxiz2PAjtwb2aIdaMb+kgYsuDiYBLprNLWRl8sp3feyxWNCeudtQBxrbDX6gGjri2m8IQlDJv+LRwFaFgGF2xkAy/JMpVdDncqLAQrkjVaQbap1uZYVQyafWDPdLQbMdlt+bR92/bqoD9oZLRVsmOiVfLwxki20jm0cQfOQJL3nRIccdrFSLejMmxc+u6aE8EWSHHswoERmU6H4mDSIotV9jhQSNW3qEU= diff --git a/LICENSE b/LICENSE index 137ab56..85e0f2d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ The MIT License (MIT) -Copyright (c) 2016 Zebula Sampedro +Copyright (c) 2018 Zebula Sampedro Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/README.md b/README.md index 75d9f09..dc3a3ad 100644 --- a/README.md +++ b/README.md @@ -15,40 +15,37 @@ Research Computing Administrative & Management Portal **rcamp** - The rcamp directory contains site code and, most importantly, settings. -## Installation +## Setting up your dev environment +You will need Docker 18.03+ and Compose 1.21+ before you begin. Documentation for Docker can be found here: https://docs.docker.com/install/. -Clone RCAMP +Start by cloning RCAMP. ``` -git clone https://github.com/ResearchComputing/RCAMP +$ git clone https://github.com/ResearchComputing/RCAMP +$ git submodule update --init +$ cd RCAMP ``` -Install the RC fork of django-ldapdb +Then build the RCAMP base image, making sure to pass your local account UID/GID as build args _(this is necessary for bind-mounting your code later)_. ``` -git clone https://github.com/ResearchComputing/django-ldapdb -cd django-ldapdb -python setup.py install +$ cd rcamp +$ docker build -t dev/rcamp --build-arg UWSGI_UID=$(id -u) --build-arg UWSGI_GID=$(id -g) . +$ cd .. ``` -Install remaining project dependencies +Build your dev environment and then start it using Compose. ``` -cd ../RCAMP -pip install -r requirements.txt +$ export RCAMP_PORT=9000 +$ docker-compose -f docker-compose.yml -f docker-compose.test-backends.yml -f docker-compose.dev.yml build +$ docker-compose -f docker-compose.yml -f docker-compose.test-backends.yml -f docker-compose.dev.yml run --rm --service-ports rcamp-uwsgi bash -c 'sleep 30s && python manage.py migrate' +$ docker-compose -f docker-compose.yml -f docker-compose.test-backends.yml -f docker-compose.dev.yml up -d ``` -Configure local settings. Configuration in `local_settings.py` will override configuration in `settings.py`. +Finish by migrating the DB and adding a superuser to the RCAMP app. You'll need to attach to the running RCAMP service to do this: ``` -cd rcamp/rcamp -touch local_settings.py -# Configure fields in local_settings as needed. -``` -Collect static files -``` -python manage.py collectstatic -``` - -Set up the database (SQLite3 preferred for dev/testing). -``` -python manage.py migrate +$ docker exec -it rcamp_rcamp-uwsgi_1 /bin/bash +~rcamp-uwsgi$ python manage.py migrate +~rcamp-uwsgi$ python manage.py createsuperuser +... ``` ## Writing and Running Tests diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..820f818 --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,19 @@ +version: "3.6" + +services: + rcamp-uwsgi: + build: + context: rcamp + cache_from: + - dev/rcamp + dockerfile: Dockerfile.test + environment: + - RCAMP_DEBUG=True + volumes: + - ./rcamp/rcamp:/home/uwsgi/rcamp + - ./rcamp/ldapdb:/home/uwsgi/ldapdb + ports: + - "${RCAMP_PORT}:9000" + depends_on: + - test-mysql + - test-ldap diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..578aea0 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,39 @@ +version: "3.6" + +services: + rcamp-uwsgi: + environment: + # Jenkins will load these values from Vault and then export them to the environment + # during deployment. + - RCAMP_DEBUG=False + - RCAMP_SECRET_KEY=${RCAMP_SECRET_KEY} + - RCAMP_ALLOWEDHOSTS=${RCAMP_ALLOWEDHOSTS} + - RCAMP_DB_HOST=${RCAMP_DB_HOST} + - RCAMP_DB_USER=${RCAMP_DB_USER} + - RCAMP_DB_PASSWORD=${RCAMP_DB_PASSWORD} + - RCAMP_RC_LDAP_URI=${RCAMP_RC_LDAP_URI} + - RCAMP_RC_LDAP_USER=${RCAMP_RC_LDAP_USER} + - RCAMP_RC_LDAP_PASSWORD=${RCAMP_RC_LDAP_PASSWORD} + volumes: + - /var/lib/sss/pipes:/var/lib/sss/pipes:rw + - /etc/nsswitch.conf:/etc/nsswitch.conf + - /etc/pam.d:/etc/pam.d + + nginx: + hostname: ${HOSTNAME} + image: nginx:stable + volumes: + - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro + - ./nginx/uwsgi_params:/etc/nginx/uwsgi_params:ro + - ./certs:/etc/nginx/certs:ro + - static-content:/var/www/static:ro + - media-uploads:/var/www/media:ro + - nginx-logs:/var/logs/nginx + ports: + - "80:80" + - "443:443" + depends_on: + - rcamp-uwsgi + +volumes: + nginx-logs: diff --git a/docker-compose.test-backends.yml b/docker-compose.test-backends.yml new file mode 100644 index 0000000..d1b7398 --- /dev/null +++ b/docker-compose.test-backends.yml @@ -0,0 +1,14 @@ +version: "3.6" + +services: + test-mysql: + image: mysql:5.7 + environment: + - MYSQL_ROOT_PASSWORD=password + - MYSQL_DATABASE=rcamp1712 + volumes: + - ./db:/var/lib/mysql + + test-ldap: + image: researchcomputing/rc-test-ldap + # build: ldap diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..0378983 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,21 @@ +version: "3.6" + +services: + rcamp-uwsgi: + build: rcamp + environment: + - RCAMP_UCB_LDAP_URI=${RCAMP_UCB_LDAP_URI} + - RCAMP_UCB_LDAP_USER=${RCAMP_UCB_LDAP_USER} + - RCAMP_UCB_LDAP_PASSWORD=${RCAMP_UCB_LDAP_PASSWORD} + - RCAMP_CSU_LDAP_URI=${RCAMP_CSU_LDAP_URI} + - RCAMP_CSU_LDAP_USER=${RCAMP_CSU_LDAP_USER} + - RCAMP_CSU_LDAP_PASSWORD=${RCAMP_CSU_LDAP_PASSWORD} + volumes: + - static-content:/home/uwsgi/rcamp/static + - media-uploads:/home/uwsgi/rcamp/media + - rcamp-logs:/home/uwsgi/rcamp/logs + +volumes: + static-content: + media-uploads: + rcamp-logs: diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 0000000..7cf0d0d --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,64 @@ +server { + listen *:80; + server_name localhost; + + client_max_body_size 8000M; + client_body_buffer_size 8000M; + client_body_timeout 120; + + if ($ssl_protocol = "") { + return 301 https://$host$request_uri; + } + + location /images { + alias /var/www/images; + } + + location / { + include /etc/nginx/uwsgi_params; + uwsgi_pass rcamp-uwsgi:8000; + } + + location /static { + allow all; + alias /var/www/static; + } + + location /media { + allow all; + alias /var/www/media; + } +} + +server { + listen *:443 ssl; + server_name localhost; + + ssl on; + + ssl_certificate /etc/nginx/certs/rcamp.crt; + ssl_certificate_key /etc/nginx/certs/rcamp.key; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 5m; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA; + ssl_prefer_server_ciphers on; + + access_log /var/log/nginx/rcamp.access.log combined; + error_log /var/log/nginx/rcamp.error.log; + + location / { + include /etc/nginx/uwsgi_params; + uwsgi_pass rcamp-uwsgi:8000; + } + + location /static { + allow all; + alias /var/www/static; + } + + location /media { + allow all; + alias /var/www/media; + } +} diff --git a/nginx/uwsgi_params b/nginx/uwsgi_params new file mode 100644 index 0000000..c7727cd --- /dev/null +++ b/nginx/uwsgi_params @@ -0,0 +1,13 @@ +uwsgi_param QUERY_STRING $query_string; +uwsgi_param REQUEST_METHOD $request_method; +uwsgi_param CONTENT_TYPE $content_type; +uwsgi_param CONTENT_LENGTH $content_length; +uwsgi_param REQUEST_URI $request_uri; +uwsgi_param PATH_INFO $document_uri; +uwsgi_param DOCUMENT_ROOT $document_root; +uwsgi_param SERVER_PROTOCOL $server_protocol; +uwsgi_param REMOTE_ADDR $remote_addr; +uwsgi_param REMOTE_PORT $remote_port; +uwsgi_param SERVER_ADDR $server_addr; +uwsgi_param SERVER_PORT $server_port; +uwsgi_param SERVER_NAME $server_name; diff --git a/rcamp/Dockerfile b/rcamp/Dockerfile new file mode 100644 index 0000000..4b04b0f --- /dev/null +++ b/rcamp/Dockerfile @@ -0,0 +1,58 @@ +FROM centos:7 +MAINTAINER Zebula Sampedro + +# Install gosu to drop user and chown shared volumes at runtime +RUN export GOSU_VERSION=1.10 && \ + yum -y install epel-release && \ + yum -y install wget dpkg && \ + dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')" && \ + wget -O /usr/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch" && \ + wget -O /tmp/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc" && \ + export GNUPGHOME="$(mktemp -d)" && \ + gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 && \ + gpg --batch --verify /tmp/gosu.asc /usr/bin/gosu && \ + rm -r "$GNUPGHOME" /tmp/gosu.asc && \ + chmod +x /usr/bin/gosu; \ + gosu nobody true && \ + yum -y remove wget dpkg && \ + yum clean all && \ + unset GOSU_VERSION + +# Add uwsgi user to the image +ARG UWSGI_UID=1000 +ARG UWSGI_GID=1000 +# Set env vars from these args, as there is no utility in forcing the user to set them twice in dev. +ENV UID=${UWSGI_UID} +ENV GID=${UWSGI_GID} + +RUN groupadd -g $GID uwsgi && \ + useradd -d "/home/uwsgi" -u "$UID" -g "$GID" -m -s /bin/bash "uwsgi" + +WORKDIR /home/uwsgi + +# Install core dependencies +RUN yum -y update && \ + yum makecache fast && \ + yum -y groupinstall "Development Tools" && \ + yum -y install epel-release curl which wget && \ + yum -y install sssd pam-devel openssl-devel && \ + yum -y install python-devel python2-pip && \ + yum -y install openldap-devel MySQL-python + +# Add uwsgi conf +COPY --chown=uwsgi:uwsgi uwsgi.ini /home/uwsgi/uwsgi.ini + +# Add codebase to container and install +COPY --chown=uwsgi:uwsgi ldapdb /home/uwsgi/ldapdb +COPY --chown=uwsgi:uwsgi rcamp /home/uwsgi/rcamp + +WORKDIR /home/uwsgi/ldapdb +RUN pip install -e . + +WORKDIR /home/uwsgi/rcamp +RUN pip2 install -r requirements.txt + +# Set gosu entrypoint and default command +COPY docker-entrypoint.sh /usr/local/bin/ +ENTRYPOINT ["sh","/usr/local/bin/docker-entrypoint.sh"] +CMD ["/usr/bin/uwsgi","/home/uwsgi/uwsgi.ini"] diff --git a/rcamp/Dockerfile.test b/rcamp/Dockerfile.test new file mode 100644 index 0000000..f91db7c --- /dev/null +++ b/rcamp/Dockerfile.test @@ -0,0 +1,18 @@ +FROM dev/rcamp +MAINTAINER Zebula Sampedro + +ENV RCAMP_DEBUG=True + +# Install dev dependencies +RUN yum -y install nodejs npm && \ + yum -y install openssl pamtester fontconfig freetype freetype-devel fontconfig-devel libstdc++ && \ + npm install -g phantomjs-prebuilt && \ + pip install selenium==3.7.0 + +# Add test users for PAM auth +RUN useradd -M -p $(echo password | openssl passwd -1 -stdin) testuser1 && \ + useradd -M -p $(echo password | openssl passwd -1 -stdin) testuser2 + +WORKDIR /home/uwsgi/rcamp + +CMD ["python","manage.py","runserver","0.0.0.0:9000"] diff --git a/rcamp/docker-entrypoint.sh b/rcamp/docker-entrypoint.sh new file mode 100644 index 0000000..cde22ad --- /dev/null +++ b/rcamp/docker-entrypoint.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +STATIC_DIR=/home/uwsgi/rcamp/static +MEDIA_DIR=/home/uwsgi/rcamp/media +LOG_DIR=/home/uwsgi/rcamp/logs + +# Collect static, and set permissions of shared volumes. +RCAMP_DEBUG=True bash -c 'python manage.py collectstatic --noinput' +chown -R uwsgi:uwsgi $STATIC_DIR +chown -R uwsgi:uwsgi $MEDIA_DIR +chown -R uwsgi:uwsgi $LOG_DIR + +exec gosu uwsgi "$@" diff --git a/rcamp/ldapdb b/rcamp/ldapdb new file mode 160000 index 0000000..e0450e5 --- /dev/null +++ b/rcamp/ldapdb @@ -0,0 +1 @@ +Subproject commit e0450e59475a983e14a5835451a5716623022743 diff --git a/rcamp/accounts/__init__.py b/rcamp/rcamp/accounts/__init__.py similarity index 100% rename from rcamp/accounts/__init__.py rename to rcamp/rcamp/accounts/__init__.py diff --git a/rcamp/accounts/admin.py b/rcamp/rcamp/accounts/admin.py similarity index 100% rename from rcamp/accounts/admin.py rename to rcamp/rcamp/accounts/admin.py diff --git a/rcamp/accounts/forms.py b/rcamp/rcamp/accounts/forms.py similarity index 100% rename from rcamp/accounts/forms.py rename to rcamp/rcamp/accounts/forms.py diff --git a/rcamp/accounts/management/__init__.py b/rcamp/rcamp/accounts/management/__init__.py similarity index 100% rename from rcamp/accounts/management/__init__.py rename to rcamp/rcamp/accounts/management/__init__.py diff --git a/rcamp/accounts/management/commands/__init__.py b/rcamp/rcamp/accounts/management/commands/__init__.py similarity index 100% rename from rcamp/accounts/management/commands/__init__.py rename to rcamp/rcamp/accounts/management/commands/__init__.py diff --git a/rcamp/accounts/management/commands/givesuperuser.py b/rcamp/rcamp/accounts/management/commands/givesuperuser.py similarity index 82% rename from rcamp/accounts/management/commands/givesuperuser.py rename to rcamp/rcamp/accounts/management/commands/givesuperuser.py index 2a01f19..db50cce 100644 --- a/rcamp/accounts/management/commands/givesuperuser.py +++ b/rcamp/rcamp/accounts/management/commands/givesuperuser.py @@ -3,7 +3,6 @@ import datetime import sys -from lib.test.ldap import get_ldap_user_defaults from lib.ldap_utils import get_ldap_username_and_org from accounts.models import ( User, @@ -11,6 +10,23 @@ ) +def get_ldap_user_defaults(): + """Return a dictionary of reasonable defaults for creating RcLdapUser objects via the ORM.""" + ldap_user_defaults = dict( + username = 'testuser', + first_name = 'Test', + last_name = 'User', + full_name = 'User, Test', + email = 'testuser@colorado.edu', + modified_date=datetime.datetime(2015,11,06,03,43,24), + uid = 1010, + gid = 1010, + gecos='Test User,,,', + home_directory='/home/testuser' + ) + return ldap_user_defaults + + class Command(BaseCommand): help = 'Gives superuser status to the specified user.' diff --git a/rcamp/accounts/management/commands/syncldapusers.py b/rcamp/rcamp/accounts/management/commands/syncldapusers.py similarity index 100% rename from rcamp/accounts/management/commands/syncldapusers.py rename to rcamp/rcamp/accounts/management/commands/syncldapusers.py diff --git a/rcamp/accounts/management/commands/transformdatadump.py b/rcamp/rcamp/accounts/management/commands/transformdatadump.py similarity index 100% rename from rcamp/accounts/management/commands/transformdatadump.py rename to rcamp/rcamp/accounts/management/commands/transformdatadump.py diff --git a/rcamp/accounts/migrations/0001_initial.py b/rcamp/rcamp/accounts/migrations/0001_initial.py similarity index 100% rename from rcamp/accounts/migrations/0001_initial.py rename to rcamp/rcamp/accounts/migrations/0001_initial.py diff --git a/rcamp/accounts/migrations/0002_auto_20171213_1604.py b/rcamp/rcamp/accounts/migrations/0002_auto_20171213_1604.py similarity index 100% rename from rcamp/accounts/migrations/0002_auto_20171213_1604.py rename to rcamp/rcamp/accounts/migrations/0002_auto_20171213_1604.py diff --git a/rcamp/accounts/migrations/0003_auto_20180228_1158.py b/rcamp/rcamp/accounts/migrations/0003_auto_20180228_1158.py similarity index 100% rename from rcamp/accounts/migrations/0003_auto_20180228_1158.py rename to rcamp/rcamp/accounts/migrations/0003_auto_20180228_1158.py diff --git a/rcamp/accounts/migrations/__init__.py b/rcamp/rcamp/accounts/migrations/__init__.py similarity index 100% rename from rcamp/accounts/migrations/__init__.py rename to rcamp/rcamp/accounts/migrations/__init__.py diff --git a/rcamp/accounts/models.py b/rcamp/rcamp/accounts/models.py similarity index 100% rename from rcamp/accounts/models.py rename to rcamp/rcamp/accounts/models.py diff --git a/rcamp/accounts/templates/account-request-intent.html b/rcamp/rcamp/accounts/templates/account-request-intent.html similarity index 100% rename from rcamp/accounts/templates/account-request-intent.html rename to rcamp/rcamp/accounts/templates/account-request-intent.html diff --git a/rcamp/accounts/templates/account-request-org-select.html b/rcamp/rcamp/accounts/templates/account-request-org-select.html similarity index 100% rename from rcamp/accounts/templates/account-request-org-select.html rename to rcamp/rcamp/accounts/templates/account-request-org-select.html diff --git a/rcamp/accounts/templates/account-request-review.html b/rcamp/rcamp/accounts/templates/account-request-review.html similarity index 100% rename from rcamp/accounts/templates/account-request-review.html rename to rcamp/rcamp/accounts/templates/account-request-review.html diff --git a/rcamp/accounts/templates/account-request-verify-csu.html b/rcamp/rcamp/accounts/templates/account-request-verify-csu.html similarity index 100% rename from rcamp/accounts/templates/account-request-verify-csu.html rename to rcamp/rcamp/accounts/templates/account-request-verify-csu.html diff --git a/rcamp/accounts/templates/account-request-verify-ucb.html b/rcamp/rcamp/accounts/templates/account-request-verify-ucb.html similarity index 100% rename from rcamp/accounts/templates/account-request-verify-ucb.html rename to rcamp/rcamp/accounts/templates/account-request-verify-ucb.html diff --git a/rcamp/accounts/urls.py b/rcamp/rcamp/accounts/urls.py similarity index 100% rename from rcamp/accounts/urls.py rename to rcamp/rcamp/accounts/urls.py diff --git a/rcamp/accounts/views.py b/rcamp/rcamp/accounts/views.py similarity index 100% rename from rcamp/accounts/views.py rename to rcamp/rcamp/accounts/views.py diff --git a/rcamp/rcamp/dev_settings.py b/rcamp/rcamp/dev_settings.py deleted file mode 100644 index 47fa405..0000000 --- a/rcamp/rcamp/dev_settings.py +++ /dev/null @@ -1,106 +0,0 @@ -import ldap -import os - -BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - -ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) -ldap.set_option(ldap.OPT_X_KEEPALIVE_IDLE,30) -ldap.set_option(ldap.OPT_X_KEEPALIVE_PROBES,2) -ldap.set_option(ldap.OPT_X_KEEPALIVE_INTERVAL,2) - -# MEDIA_URL = 'http://localhost:9000/media/' - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': 'rcamp.sqlite', - }, - 'rcldap': { - 'ENGINE': 'ldapdb.backends.ldap', - 'NAME': 'ldap://localhost:10389', - 'USER': 'cn=Directory Manager', - 'PASSWORD': 'password', - }, - 'culdap': { - 'ENGINE': 'ldapdb.backends.ldap', - 'NAME': 'ldap://localhost:10389', - 'USER': 'cn=Directory Manager', - 'PASSWORD': 'password', - }, - 'csuldap': { - 'ENGINE': 'ldapdb.backends.ldap', - 'NAME': 'ldap://localhost:10389', - 'USER': 'cn=Directory Manager', - 'PASSWORD': 'password', - }, -} - -LDAPCONFS = { - 'rcldap': { - 'server': DATABASES['rcldap']['NAME'], - 'bind_dn': DATABASES['rcldap']['USER'], - 'bind_pw': DATABASES['rcldap']['PASSWORD'], - 'base_dn': 'dc=rc,dc=int,dc=colorado,dc=edu', - 'people_dn': 'ou=people,dc=rc,dc=int,dc=colorado,dc=edu', - 'ucb_dn': 'ou=ucb,ou=people,dc=rc,dc=int,dc=colorado,dc=edu', - 'csu_dn': 'ou=csu,ou=people,dc=rc,dc=int,dc=colorado,dc=edu', - 'xsede_dn': 'ou=xsede,ou=people,dc=rc,dc=int,dc=colorado,dc=edu', - 'internal_dn': 'ou=internal,ou=people,dc=rc,dc=int,dc=colorado,dc=edu', - 'group_dn': 'ou=groups,dc=rc,dc=int,dc=colorado,dc=edu', - }, - 'culdap': { - 'server': DATABASES['culdap']['NAME'], - 'bind_dn': DATABASES['culdap']['USER'], - 'bind_pw': DATABASES['culdap']['PASSWORD'], - 'base_dn': 'dc=colorado,dc=edu', - 'group_dn': 'ou=groups,dc=colorado,dc=edu', - 'people_dn': 'ou=users,dc=colorado,dc=edu', - }, - 'csuldap': { - 'server': DATABASES['csuldap']['NAME'], - 'bind_dn': DATABASES['csuldap']['USER'], - 'bind_pw': DATABASES['csuldap']['PASSWORD'], - 'base_dn': 'ou=eIdentityUsers,dc=ColoState,dc=edu', - 'group_dn': 'ou=eIdentityUsers,dc=ColoState,dc=edu', - 'people_dn': 'ou=eIdentityUsers,dc=ColoState,dc=edu', - }, -} - -TIME_ZONE = 'America/Denver' - -# DEBUG = False -EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' - -LOGGING = { - 'version': 1, - 'disable_existing_loggers': False, - 'handlers': { - 'file': { - 'level': 'WARN', - 'class': 'logging.FileHandler', - 'filename': 'rcamp.log', - }, - }, - 'loggers': { - 'django': { - 'handlers': ['file'], - 'level': 'DEBUG', - 'propagate': True, - }, - 'rcamp': { - 'handlers': ['file'], - 'level': 'DEBUG', - 'propagate': True, - }, - 'projects': { - 'handlers': ['file'], - 'level': 'DEBUG', - 'propagate': True, - }, - 'accounts': { - 'handlers': ['file'], - 'level': 'DEBUG', - 'propagate': True, - }, - }, -} diff --git a/rcamp/endpoints/__init__.py b/rcamp/rcamp/endpoints/__init__.py similarity index 100% rename from rcamp/endpoints/__init__.py rename to rcamp/rcamp/endpoints/__init__.py diff --git a/rcamp/endpoints/filters.py b/rcamp/rcamp/endpoints/filters.py similarity index 100% rename from rcamp/endpoints/filters.py rename to rcamp/rcamp/endpoints/filters.py diff --git a/rcamp/endpoints/serializers.py b/rcamp/rcamp/endpoints/serializers.py similarity index 100% rename from rcamp/endpoints/serializers.py rename to rcamp/rcamp/endpoints/serializers.py diff --git a/rcamp/endpoints/urls.py b/rcamp/rcamp/endpoints/urls.py similarity index 100% rename from rcamp/endpoints/urls.py rename to rcamp/rcamp/endpoints/urls.py diff --git a/rcamp/endpoints/viewsets.py b/rcamp/rcamp/endpoints/viewsets.py similarity index 100% rename from rcamp/endpoints/viewsets.py rename to rcamp/rcamp/endpoints/viewsets.py diff --git a/rcamp/lib/__init__.py b/rcamp/rcamp/lib/__init__.py similarity index 100% rename from rcamp/lib/__init__.py rename to rcamp/rcamp/lib/__init__.py diff --git a/rcamp/lib/fields.py b/rcamp/rcamp/lib/fields.py similarity index 100% rename from rcamp/lib/fields.py rename to rcamp/rcamp/lib/fields.py diff --git a/rcamp/lib/ldap_utils.py b/rcamp/rcamp/lib/ldap_utils.py similarity index 100% rename from rcamp/lib/ldap_utils.py rename to rcamp/rcamp/lib/ldap_utils.py diff --git a/rcamp/lib/pam_backend.py b/rcamp/rcamp/lib/pam_backend.py similarity index 100% rename from rcamp/lib/pam_backend.py rename to rcamp/rcamp/lib/pam_backend.py diff --git a/rcamp/lib/router.py b/rcamp/rcamp/lib/router.py similarity index 100% rename from rcamp/lib/router.py rename to rcamp/rcamp/lib/router.py diff --git a/rcamp/lib/views.py b/rcamp/rcamp/lib/views.py similarity index 100% rename from rcamp/lib/views.py rename to rcamp/rcamp/lib/views.py diff --git a/rcamp/lib/test/__init__.py b/rcamp/rcamp/mailer/__init__.py similarity index 100% rename from rcamp/lib/test/__init__.py rename to rcamp/rcamp/mailer/__init__.py diff --git a/rcamp/mailer/admin.py b/rcamp/rcamp/mailer/admin.py similarity index 100% rename from rcamp/mailer/admin.py rename to rcamp/rcamp/mailer/admin.py diff --git a/rcamp/mailer/migrations/0001_initial.py b/rcamp/rcamp/mailer/migrations/0001_initial.py similarity index 100% rename from rcamp/mailer/migrations/0001_initial.py rename to rcamp/rcamp/mailer/migrations/0001_initial.py diff --git a/rcamp/mailer/__init__.py b/rcamp/rcamp/mailer/migrations/__init__.py similarity index 100% rename from rcamp/mailer/__init__.py rename to rcamp/rcamp/mailer/migrations/__init__.py diff --git a/rcamp/mailer/models.py b/rcamp/rcamp/mailer/models.py similarity index 100% rename from rcamp/mailer/models.py rename to rcamp/rcamp/mailer/models.py diff --git a/rcamp/mailer/receivers.py b/rcamp/rcamp/mailer/receivers.py similarity index 100% rename from rcamp/mailer/receivers.py rename to rcamp/rcamp/mailer/receivers.py diff --git a/rcamp/mailer/signals.py b/rcamp/rcamp/mailer/signals.py similarity index 100% rename from rcamp/mailer/signals.py rename to rcamp/rcamp/mailer/signals.py diff --git a/rcamp/manage.py b/rcamp/rcamp/manage.py similarity index 100% rename from rcamp/manage.py rename to rcamp/rcamp/manage.py diff --git a/rcamp/mailer/migrations/__init__.py b/rcamp/rcamp/projects/__init__.py similarity index 100% rename from rcamp/mailer/migrations/__init__.py rename to rcamp/rcamp/projects/__init__.py diff --git a/rcamp/projects/admin.py b/rcamp/rcamp/projects/admin.py similarity index 100% rename from rcamp/projects/admin.py rename to rcamp/rcamp/projects/admin.py diff --git a/rcamp/projects/forms.py b/rcamp/rcamp/projects/forms.py similarity index 100% rename from rcamp/projects/forms.py rename to rcamp/rcamp/projects/forms.py diff --git a/rcamp/projects/__init__.py b/rcamp/rcamp/projects/management/__init__.py similarity index 100% rename from rcamp/projects/__init__.py rename to rcamp/rcamp/projects/management/__init__.py diff --git a/rcamp/projects/management/__init__.py b/rcamp/rcamp/projects/management/commands/__init__.py similarity index 100% rename from rcamp/projects/management/__init__.py rename to rcamp/rcamp/projects/management/commands/__init__.py diff --git a/rcamp/projects/migrations/0001_initial.py b/rcamp/rcamp/projects/migrations/0001_initial.py similarity index 100% rename from rcamp/projects/migrations/0001_initial.py rename to rcamp/rcamp/projects/migrations/0001_initial.py diff --git a/rcamp/projects/migrations/0002_auto_20180326_1507.py b/rcamp/rcamp/projects/migrations/0002_auto_20180326_1507.py similarity index 100% rename from rcamp/projects/migrations/0002_auto_20180326_1507.py rename to rcamp/rcamp/projects/migrations/0002_auto_20180326_1507.py diff --git a/rcamp/projects/migrations/0003_auto_20180326_1508.py b/rcamp/rcamp/projects/migrations/0003_auto_20180326_1508.py similarity index 100% rename from rcamp/projects/migrations/0003_auto_20180326_1508.py rename to rcamp/rcamp/projects/migrations/0003_auto_20180326_1508.py diff --git a/rcamp/projects/migrations/0004_auto_20180326_1529.py b/rcamp/rcamp/projects/migrations/0004_auto_20180326_1529.py similarity index 100% rename from rcamp/projects/migrations/0004_auto_20180326_1529.py rename to rcamp/rcamp/projects/migrations/0004_auto_20180326_1529.py diff --git a/rcamp/projects/management/commands/__init__.py b/rcamp/rcamp/projects/migrations/__init__.py similarity index 100% rename from rcamp/projects/management/commands/__init__.py rename to rcamp/rcamp/projects/migrations/__init__.py diff --git a/rcamp/projects/models.py b/rcamp/rcamp/projects/models.py similarity index 100% rename from rcamp/projects/models.py rename to rcamp/rcamp/projects/models.py diff --git a/rcamp/projects/receivers.py b/rcamp/rcamp/projects/receivers.py similarity index 100% rename from rcamp/projects/receivers.py rename to rcamp/rcamp/projects/receivers.py diff --git a/rcamp/projects/templates/allocation-request-create.html b/rcamp/rcamp/projects/templates/allocation-request-create.html similarity index 100% rename from rcamp/projects/templates/allocation-request-create.html rename to rcamp/rcamp/projects/templates/allocation-request-create.html diff --git a/rcamp/projects/templates/allocation-request-detail.html b/rcamp/rcamp/projects/templates/allocation-request-detail.html similarity index 100% rename from rcamp/projects/templates/allocation-request-detail.html rename to rcamp/rcamp/projects/templates/allocation-request-detail.html diff --git a/rcamp/projects/templates/project-create.html b/rcamp/rcamp/projects/templates/project-create.html similarity index 100% rename from rcamp/projects/templates/project-create.html rename to rcamp/rcamp/projects/templates/project-create.html diff --git a/rcamp/projects/templates/project-detail.html b/rcamp/rcamp/projects/templates/project-detail.html similarity index 100% rename from rcamp/projects/templates/project-detail.html rename to rcamp/rcamp/projects/templates/project-detail.html diff --git a/rcamp/projects/templates/project-edit.html b/rcamp/rcamp/projects/templates/project-edit.html similarity index 100% rename from rcamp/projects/templates/project-edit.html rename to rcamp/rcamp/projects/templates/project-edit.html diff --git a/rcamp/projects/templates/project-list.html b/rcamp/rcamp/projects/templates/project-list.html similarity index 100% rename from rcamp/projects/templates/project-list.html rename to rcamp/rcamp/projects/templates/project-list.html diff --git a/rcamp/projects/templates/reference-create.html b/rcamp/rcamp/projects/templates/reference-create.html similarity index 100% rename from rcamp/projects/templates/reference-create.html rename to rcamp/rcamp/projects/templates/reference-create.html diff --git a/rcamp/projects/templates/reference-detail.html b/rcamp/rcamp/projects/templates/reference-detail.html similarity index 100% rename from rcamp/projects/templates/reference-detail.html rename to rcamp/rcamp/projects/templates/reference-detail.html diff --git a/rcamp/projects/templates/reference-edit.html b/rcamp/rcamp/projects/templates/reference-edit.html similarity index 100% rename from rcamp/projects/templates/reference-edit.html rename to rcamp/rcamp/projects/templates/reference-edit.html diff --git a/rcamp/projects/urls.py b/rcamp/rcamp/projects/urls.py similarity index 100% rename from rcamp/projects/urls.py rename to rcamp/rcamp/projects/urls.py diff --git a/rcamp/projects/views.py b/rcamp/rcamp/projects/views.py similarity index 100% rename from rcamp/projects/views.py rename to rcamp/rcamp/projects/views.py diff --git a/rcamp/rcamp/.bowerrc b/rcamp/rcamp/rcamp/.bowerrc similarity index 100% rename from rcamp/rcamp/.bowerrc rename to rcamp/rcamp/rcamp/.bowerrc diff --git a/rcamp/projects/migrations/__init__.py b/rcamp/rcamp/rcamp/__init__.py similarity index 100% rename from rcamp/projects/migrations/__init__.py rename to rcamp/rcamp/rcamp/__init__.py diff --git a/rcamp/rcamp/bower.json b/rcamp/rcamp/rcamp/bower.json similarity index 100% rename from rcamp/rcamp/bower.json rename to rcamp/rcamp/rcamp/bower.json diff --git a/rcamp/rcamp/rcamp/settings/__init__.py b/rcamp/rcamp/rcamp/settings/__init__.py new file mode 100644 index 0000000..bfb6240 --- /dev/null +++ b/rcamp/rcamp/rcamp/settings/__init__.py @@ -0,0 +1,5 @@ +from .main import * +from .databases import * +from .organizations import * +from .auth import * +from .logging import * diff --git a/rcamp/rcamp/rcamp/settings/auth.py b/rcamp/rcamp/rcamp/settings/auth.py new file mode 100644 index 0000000..ee04f5a --- /dev/null +++ b/rcamp/rcamp/rcamp/settings/auth.py @@ -0,0 +1,13 @@ +AUTHENTICATION_BACKENDS = ( + 'django.contrib.auth.backends.ModelBackend', + 'lib.pam_backend.PamBackend', +) + +AUTH_USER_MODEL = 'accounts.User' + +LOGIN_URL = '/login' + +PAM_SERVICES = { + 'default': 'login', + 'csu': 'csu' +} diff --git a/rcamp/rcamp/rcamp/settings/databases.py b/rcamp/rcamp/rcamp/settings/databases.py new file mode 100644 index 0000000..8c7f11f --- /dev/null +++ b/rcamp/rcamp/rcamp/settings/databases.py @@ -0,0 +1,96 @@ +import os +from .toggles import * + +BASE_DIR = '/home/uwsgi/rcamp' + +if not DEBUG: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': 'rcamp1712', + 'USER': os.environ.get('RCAMP_DB_USER'), + 'PASSWORD': os.environ.get('RCAMP_DB_PASSWORD'), + 'HOST': os.environ.get('RCAMP_DB_HOST'), + }, + 'rcldap': { + 'ENGINE': 'ldapdb.backends.ldap', + 'NAME': os.environ.get('RCAMP_RC_LDAP_URI'), + 'USER': os.environ.get('RCAMP_RC_LDAP_USER'), + 'PASSWORD': os.environ.get('RCAMP_RC_LDAP_PASSWORD'), + }, + 'culdap': { + 'ENGINE': 'ldapdb.backends.ldap', + 'NAME': os.environ.get('RCAMP_UCB_LDAP_URI'), + 'USER': os.environ.get('RCAMP_UCB_LDAP_USER'), + 'PASSWORD': os.environ.get('RCAMP_UCB_LDAP_PASSWORD'), + }, + 'csuldap': { + 'ENGINE': 'ldapdb.backends.ldap', + 'NAME': os.environ.get('RCAMP_CSU_LDAP_URI'), + 'USER': os.environ.get('RCAMP_CSU_LDAP_USER'), + 'PASSWORD': os.environ.get('RCAMP_CSU_LDAP_PASSWORD'), + }, + } +else: + DATABASES = { + # `test-mysql` is the name of the rc-test-mysql service + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': 'rcamp1712', + 'USER': 'root', + 'PASSWORD': 'password', + 'HOST': 'test-mysql', + }, + # `test-ldap` is the name of the rc-test-ldap service + 'rcldap': { + 'ENGINE': 'ldapdb.backends.ldap', + 'NAME': 'ldap://test-ldap', + 'USER': 'cn=Directory Manager', + 'PASSWORD': 'password', + }, + 'culdap': { + 'ENGINE': 'ldapdb.backends.ldap', + 'NAME': os.environ.get('RCAMP_UCB_LDAP_URI','ldap://test-ldap'), + 'USER': os.environ.get('RCAMP_UCB_LDAP_USER','cn=Directory Manager'), + 'PASSWORD': os.environ.get('RCAMP_UCB_LDAP_PASSWORD','password'), + }, + 'csuldap': { + 'ENGINE': 'ldapdb.backends.ldap', + 'NAME': os.environ.get('RCAMP_CSU_LDAP_URI','ldap://test-ldap'), + 'USER': os.environ.get('RCAMP_CSU_LDAP_USER','cn=Directory Manager'), + 'PASSWORD': os.environ.get('RCAMP_CSU_LDAP_PASSWORD','password'), + }, + } + +LDAPCONFS = { + 'rcldap': { + 'server': DATABASES['rcldap']['NAME'], + 'bind_dn': DATABASES['rcldap']['USER'], + 'bind_pw': DATABASES['rcldap']['PASSWORD'], + 'base_dn': 'dc=rc,dc=int,dc=colorado,dc=edu', + 'people_dn': 'ou=people,dc=rc,dc=int,dc=colorado,dc=edu', + 'ucb_dn': 'ou=ucb,ou=people,dc=rc,dc=int,dc=colorado,dc=edu', + 'csu_dn': 'ou=csu,ou=people,dc=rc,dc=int,dc=colorado,dc=edu', + 'xsede_dn': 'ou=xsede,ou=people,dc=rc,dc=int,dc=colorado,dc=edu', + 'internal_dn': 'ou=internal,ou=people,dc=rc,dc=int,dc=colorado,dc=edu', + 'group_dn': 'ou=groups,dc=rc,dc=int,dc=colorado,dc=edu', + }, + 'culdap': { + 'server': DATABASES['culdap']['NAME'], + 'bind_dn': DATABASES['culdap']['USER'], + 'bind_pw': DATABASES['culdap']['PASSWORD'], + 'base_dn': 'dc=colorado,dc=edu', + 'group_dn': 'ou=groups,dc=colorado,dc=edu', + 'people_dn': 'ou=users,dc=colorado,dc=edu', + }, + 'csuldap': { + 'server': DATABASES['csuldap']['NAME'], + 'bind_dn': DATABASES['csuldap']['USER'], + 'bind_pw': DATABASES['csuldap']['PASSWORD'], + 'base_dn': 'ou=eIdentityUsers,dc=ColoState,dc=edu', + 'group_dn': 'ou=eIdentityUsers,dc=ColoState,dc=edu', + 'people_dn': 'ou=eIdentityUsers,dc=ColoState,dc=edu', + }, +} + +DATABASE_ROUTERS = ['lib.router.LdapRouter',] diff --git a/rcamp/rcamp/rcamp/settings/logging.py b/rcamp/rcamp/rcamp/settings/logging.py new file mode 100644 index 0000000..167486d --- /dev/null +++ b/rcamp/rcamp/rcamp/settings/logging.py @@ -0,0 +1,42 @@ +from .toggles import * + +if not DEBUG: + EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' + EMAIL_HOST = 'mail.rc.int.colorado.edu' + EMAIL_PORT = 25 +else: + EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' + +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'handlers': { + 'file': { + 'level': 'WARN', + 'class': 'logging.FileHandler', + 'filename': '/home/uwsgi/rcamp/logs/rcamp.log', + }, + }, + 'loggers': { + 'django': { + 'handlers': ['file'], + 'level': 'DEBUG', + 'propagate': True, + }, + 'rcamp': { + 'handlers': ['file'], + 'level': 'DEBUG', + 'propagate': True, + }, + 'projects': { + 'handlers': ['file'], + 'level': 'DEBUG', + 'propagate': True, + }, + 'accounts': { + 'handlers': ['file'], + 'level': 'DEBUG', + 'propagate': True, + }, + }, +} diff --git a/rcamp/rcamp/rcamp/settings/main.py b/rcamp/rcamp/rcamp/settings/main.py new file mode 100644 index 0000000..3537828 --- /dev/null +++ b/rcamp/rcamp/rcamp/settings/main.py @@ -0,0 +1,110 @@ +import os +from .toggles import * + +BASE_DIR = '/home/uwsgi/rcamp' + + +if not DEBUG: + SECRET_KEY = os.environ.get('RCAMP_SECRET_KEY') +else: + SECRET_KEY = 'A terribly insecure key not suitable for production' + +if not DEBUG: + default_hosts = 'rcamp.rc.colorado.edu,portals.rc.colorado.edu,rcamp1.rc.int.colorado.edu' + hosts = os.environ.get('RCAMP_ALLOWEDHOSTS',default_hosts) + ALLOWED_HOSTS = hosts.split(',') +else: + ALLOWED_HOSTS = [] + + +INSTALLED_APPS = [ + 'grappelli', + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + + 'crispy_forms', + 'rest_framework', + + 'ldapdb', + 'lib', + 'mailer', + 'accounts', + 'projects', +] + +if DEBUG: + INSTALLED_APPS.append('tests') + +MIDDLEWARE_CLASSES = ( + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'django.middleware.security.SecurityMiddleware', +) + +ROOT_URLCONF = 'rcamp.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [ + os.path.join(BASE_DIR,'rcamp','templates'), + ], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.template.context_processors.media', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'rcamp.wsgi.application' + + + +LOGIN_REDIRECT_URL = '/' + +# Internationalization +# https://docs.djangoproject.com/en/1.8/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'America/Denver' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.8/howto/static-files/ + +STATIC_URL = '/static/' +STATIC_ROOT = os.path.join(BASE_DIR,'static') +STATICFILES_DIRS = ( + os.path.join(BASE_DIR,'rcamp','static'), +) + +# Media files (User-uploaded files) +# https://docs.djangoproject.com/en/1.8/ref/settings/#media-root +MEDIA_URL = '/media/' +MEDIA_ROOT = os.path.join(BASE_DIR,'media','') + +# GRAPPELLI ADMIN SETTINGS +GRAPPELLI_ADMIN_TITLE = 'RCAMP' + +REST_FRAMEWORK = {} diff --git a/rcamp/rcamp/rcamp/settings/organizations.py b/rcamp/rcamp/rcamp/settings/organizations.py new file mode 100644 index 0000000..ee97250 --- /dev/null +++ b/rcamp/rcamp/rcamp/settings/organizations.py @@ -0,0 +1,31 @@ +LICENSE_GROUPS = { + 'ucb': 'ucb' +} + +ORGANIZATION_INFO = { + 'ucb': { + 'long_name': 'University of Colorado Boulder', + 'suffix': None, + 'general_project_id': 'ucb-general' + }, + 'csu': { + 'long_name': 'Colorado State University', + 'suffix': 'colostate.edu', + 'general_project_id': 'csu-general' + }, + 'xsede': { + 'long_name': 'XSEDE', + 'suffix': 'xsede.org', + 'general_project_id': 'rmacc-general' + }, + 'ncar': { + 'long_name': 'NCAR', + 'suffix': 'ncar.ucar.edu', + 'general_project_id': None + }, + 'internal': { + 'long_name': 'Research Computing - Administrative', + 'suffix': None, + 'general_project_id': None + } +} diff --git a/rcamp/rcamp/rcamp/settings/toggles.py b/rcamp/rcamp/rcamp/settings/toggles.py new file mode 100644 index 0000000..60831cd --- /dev/null +++ b/rcamp/rcamp/rcamp/settings/toggles.py @@ -0,0 +1,3 @@ +import os +_debug = os.environ.get('RCAMP_DEBUG', 'False') +DEBUG = _debug == 'True' diff --git a/rcamp/rcamp/static/css/account-request.css b/rcamp/rcamp/rcamp/static/css/account-request.css similarity index 100% rename from rcamp/rcamp/static/css/account-request.css rename to rcamp/rcamp/rcamp/static/css/account-request.css diff --git a/rcamp/rcamp/static/css/jumbotron.css b/rcamp/rcamp/rcamp/static/css/jumbotron.css similarity index 100% rename from rcamp/rcamp/static/css/jumbotron.css rename to rcamp/rcamp/rcamp/static/css/jumbotron.css diff --git a/rcamp/rcamp/static/css/login.css b/rcamp/rcamp/rcamp/static/css/login.css similarity index 100% rename from rcamp/rcamp/static/css/login.css rename to rcamp/rcamp/rcamp/static/css/login.css diff --git a/rcamp/rcamp/static/css/project-create.css b/rcamp/rcamp/rcamp/static/css/project-create.css similarity index 100% rename from rcamp/rcamp/static/css/project-create.css rename to rcamp/rcamp/rcamp/static/css/project-create.css diff --git a/rcamp/rcamp/static/css/projects.css b/rcamp/rcamp/rcamp/static/css/projects.css similarity index 100% rename from rcamp/rcamp/static/css/projects.css rename to rcamp/rcamp/rcamp/static/css/projects.css diff --git a/rcamp/rcamp/static/css/rcamp.css b/rcamp/rcamp/rcamp/static/css/rcamp.css similarity index 100% rename from rcamp/rcamp/static/css/rcamp.css rename to rcamp/rcamp/rcamp/static/css/rcamp.css diff --git a/rcamp/rcamp/static/css/selector.css b/rcamp/rcamp/rcamp/static/css/selector.css similarity index 100% rename from rcamp/rcamp/static/css/selector.css rename to rcamp/rcamp/rcamp/static/css/selector.css diff --git a/rcamp/rcamp/static/img/._logo.png b/rcamp/rcamp/rcamp/static/img/._logo.png similarity index 100% rename from rcamp/rcamp/static/img/._logo.png rename to rcamp/rcamp/rcamp/static/img/._logo.png diff --git a/rcamp/rcamp/static/img/coolaisle-blue-cmp.jpg b/rcamp/rcamp/rcamp/static/img/coolaisle-blue-cmp.jpg similarity index 100% rename from rcamp/rcamp/static/img/coolaisle-blue-cmp.jpg rename to rcamp/rcamp/rcamp/static/img/coolaisle-blue-cmp.jpg diff --git a/rcamp/rcamp/static/img/logo.png b/rcamp/rcamp/rcamp/static/img/logo.png similarity index 100% rename from rcamp/rcamp/static/img/logo.png rename to rcamp/rcamp/rcamp/static/img/logo.png diff --git a/rcamp/rcamp/static/img/memory-heatmap-cmp.jpg b/rcamp/rcamp/rcamp/static/img/memory-heatmap-cmp.jpg similarity index 100% rename from rcamp/rcamp/static/img/memory-heatmap-cmp.jpg rename to rcamp/rcamp/rcamp/static/img/memory-heatmap-cmp.jpg diff --git a/rcamp/rcamp/static/img/molecule-cmp.jpg b/rcamp/rcamp/rcamp/static/img/molecule-cmp.jpg similarity index 100% rename from rcamp/rcamp/static/img/molecule-cmp.jpg rename to rcamp/rcamp/rcamp/static/img/molecule-cmp.jpg diff --git a/rcamp/rcamp/static/js/SelectFilter2.js b/rcamp/rcamp/rcamp/static/js/SelectFilter2.js similarity index 100% rename from rcamp/rcamp/static/js/SelectFilter2.js rename to rcamp/rcamp/rcamp/static/js/SelectFilter2.js diff --git a/rcamp/rcamp/static/js/jsi18n.js b/rcamp/rcamp/rcamp/static/js/jsi18n.js similarity index 100% rename from rcamp/rcamp/static/js/jsi18n.js rename to rcamp/rcamp/rcamp/static/js/jsi18n.js diff --git a/rcamp/rcamp/templates/404.html b/rcamp/rcamp/rcamp/templates/404.html similarity index 100% rename from rcamp/rcamp/templates/404.html rename to rcamp/rcamp/rcamp/templates/404.html diff --git a/rcamp/rcamp/templates/500.html b/rcamp/rcamp/rcamp/templates/500.html similarity index 100% rename from rcamp/rcamp/templates/500.html rename to rcamp/rcamp/rcamp/templates/500.html diff --git a/rcamp/rcamp/templates/base.html b/rcamp/rcamp/rcamp/templates/base.html similarity index 100% rename from rcamp/rcamp/templates/base.html rename to rcamp/rcamp/rcamp/templates/base.html diff --git a/rcamp/rcamp/templates/index.html b/rcamp/rcamp/rcamp/templates/index.html similarity index 100% rename from rcamp/rcamp/templates/index.html rename to rcamp/rcamp/rcamp/templates/index.html diff --git a/rcamp/rcamp/templates/login.html b/rcamp/rcamp/rcamp/templates/login.html similarity index 100% rename from rcamp/rcamp/templates/login.html rename to rcamp/rcamp/rcamp/templates/login.html diff --git a/rcamp/rcamp/templates/logout.html b/rcamp/rcamp/rcamp/templates/logout.html similarity index 100% rename from rcamp/rcamp/templates/logout.html rename to rcamp/rcamp/rcamp/templates/logout.html diff --git a/rcamp/rcamp/templates/terms-and-conditions.html b/rcamp/rcamp/rcamp/templates/terms-and-conditions.html similarity index 100% rename from rcamp/rcamp/templates/terms-and-conditions.html rename to rcamp/rcamp/rcamp/templates/terms-and-conditions.html diff --git a/rcamp/rcamp/urls.py b/rcamp/rcamp/rcamp/urls.py similarity index 89% rename from rcamp/rcamp/urls.py rename to rcamp/rcamp/rcamp/urls.py index e11e1ce..807b878 100644 --- a/rcamp/rcamp/urls.py +++ b/rcamp/rcamp/rcamp/urls.py @@ -19,6 +19,7 @@ from django.views.generic import TemplateView from django.conf.urls import handler404 from django.conf.urls import handler500 +from django.conf import settings # Make sure signals/receivers get loaded. from mailer import receivers from projects import receivers @@ -38,3 +39,7 @@ url(r'^accounts/', include('accounts.urls', namespace='accounts')), url(r'^projects/', include('projects.urls', namespace='projects')), ] + +if settings.DEBUG: + from django.conf.urls.static import static + urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/rcamp/rcamp/wsgi.py b/rcamp/rcamp/rcamp/wsgi.py similarity index 100% rename from rcamp/rcamp/wsgi.py rename to rcamp/rcamp/rcamp/wsgi.py diff --git a/requirements.txt b/rcamp/rcamp/requirements.txt similarity index 84% rename from requirements.txt rename to rcamp/rcamp/requirements.txt index 673f450..b32b3c1 100644 --- a/requirements.txt +++ b/rcamp/rcamp/requirements.txt @@ -16,4 +16,4 @@ python-ldap==2.4.22 python-pam==1.8.2 pytz==2016.4 six==1.10.0 -git+git://github.com/ResearchComputing/django-ldapdb.git@master +uWSGI==2.0.17 diff --git a/rcamp/rcamp/settings.py b/rcamp/rcamp/settings.py deleted file mode 100644 index 4745367..0000000 --- a/rcamp/rcamp/settings.py +++ /dev/null @@ -1,183 +0,0 @@ -""" -Django settings for rcamp project. - -Generated by 'django-admin startproject' using Django 1.8.5. - -For more information on this file, see -https://docs.djangoproject.com/en/1.8/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/1.8/ref/settings/ -""" - -# Build paths inside the project like this: os.path.join(BASE_DIR, ...) -import os - -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.8/howto/deployment/checklist/ - -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'j38e9!%8z#b=$=g87wzlb*+gqm0kc-6x7lb^_b6_zg1#(b*75s' - -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True - -ALLOWED_HOSTS = [] - - -# Application definition - -INSTALLED_APPS = ( - 'grappelli', - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - - 'crispy_forms', - 'rest_framework', - - 'ldapdb', - 'lib', - 'mailer', - 'accounts', - 'projects', -) - -MIDDLEWARE_CLASSES = ( - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'django.middleware.security.SecurityMiddleware', -) - -ROOT_URLCONF = 'rcamp.urls' - -TEMPLATES = [ - { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [ - os.path.join(os.path.dirname(os.path.abspath(__file__)),'templates'), - ], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.template.context_processors.media', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', - ], - }, - }, -] - -WSGI_APPLICATION = 'rcamp.wsgi.application' - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), - }, -} - -DATABASE_ROUTERS = ['lib.router.LdapRouter',] - -EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend' - -AUTHENTICATION_BACKENDS = ( - 'django.contrib.auth.backends.ModelBackend', - 'lib.pam_backend.PamBackend', -) - -AUTH_USER_MODEL = 'accounts.User' - -LOGIN_URL = '/login' - -LOGIN_REDIRECT_URL = '/' - -# Internationalization -# https://docs.djangoproject.com/en/1.8/topics/i18n/ - -LANGUAGE_CODE = 'en-us' - -TIME_ZONE = 'UTC' - -USE_I18N = True - -USE_L10N = True - -USE_TZ = True - -MEDIA_URL = '/media/' -MEDIA_ROOT = os.path.join(BASE_DIR,'rcamp','media','') - -# Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/1.8/howto/static-files/ - -STATIC_URL = '/static/' -STATIC_ROOT = os.path.join(BASE_DIR,'static') -STATICFILES_DIRS = ( - os.path.join(os.path.dirname(os.path.abspath(__file__)),'static'), -) - -# Media files (User-uploaded files) -# https://docs.djangoproject.com/en/1.8/ref/settings/#media-root -MEDIA_URL = '/media/' -MEDIA_ROOT = os.path.join(BASE_DIR,'media','') - -# GRAPPELLI ADMIN SETTINGS -GRAPPELLI_ADMIN_TITLE = 'RCAMP' - -REST_FRAMEWORK = {} - -PAM_SERVICES = { - 'default': 'login', - 'csu': 'csu' -} - -LICENSE_GROUPS = { - 'ucb': 'ucb' -} - -ORGANIZATION_INFO = { - 'ucb': { - 'long_name': 'University of Colorado Boulder', - 'suffix': None, - 'general_project_id': 'ucb-general' - }, - 'csu': { - 'long_name': 'Colorado State University', - 'suffix': 'colostate.edu', - 'general_project_id': 'csu-general' - }, - 'xsede': { - 'long_name': 'XSEDE', - 'suffix': 'xsede.org', - 'general_project_id': 'rmacc-general' - }, - 'ncar': { - 'long_name': 'NCAR', - 'suffix': 'ncar.ucar.edu', - 'general_project_id': None - }, - 'internal': { - 'long_name': 'Research Computing - Administrative', - 'suffix': None, - 'general_project_id': None - } -} - -try: - from local_settings import * -except: - pass diff --git a/rcamp/rcamp/__init__.py b/rcamp/rcamp/tests/__init__.py similarity index 100% rename from rcamp/rcamp/__init__.py rename to rcamp/rcamp/tests/__init__.py diff --git a/rcamp/accounts/test_commands.py b/rcamp/rcamp/tests/test_accounts_commands.py similarity index 86% rename from rcamp/accounts/test_commands.py rename to rcamp/rcamp/tests/test_accounts_commands.py index b86fb8e..7749d86 100644 --- a/rcamp/accounts/test_commands.py +++ b/rcamp/rcamp/tests/test_accounts_commands.py @@ -7,8 +7,8 @@ from django.conf import settings from django.core.management import call_command -from lib.test.utils import SafeTestCase -from lib.test.ldap import ( +from tests.utilities.utils import SafeTestCase +from tests.utilities.ldap import ( get_ldap_user_defaults, get_ldap_group_defaults, build_mock_rcldap_user, diff --git a/rcamp/accounts/test_forms.py b/rcamp/rcamp/tests/test_accounts_forms.py similarity index 99% rename from rcamp/accounts/test_forms.py rename to rcamp/rcamp/tests/test_accounts_forms.py index 7263ec4..e98808e 100644 --- a/rcamp/accounts/test_forms.py +++ b/rcamp/rcamp/tests/test_accounts_forms.py @@ -7,7 +7,7 @@ import copy from django.conf import settings -from lib.test.ldap import ( +from tests.utilities.ldap import ( LdapTestCase, build_mock_rcldap_user ) diff --git a/rcamp/accounts/test_functional.py b/rcamp/rcamp/tests/test_accounts_functional.py similarity index 99% rename from rcamp/accounts/test_functional.py rename to rcamp/rcamp/tests/test_accounts_functional.py index fedbde5..0455f1e 100644 --- a/rcamp/accounts/test_functional.py +++ b/rcamp/rcamp/tests/test_accounts_functional.py @@ -1,10 +1,10 @@ import mock from unittest import skip -from lib.test.ldap import ( +from tests.utilities.ldap import ( get_ldap_user_defaults, get_ldap_group_defaults ) -from lib.test.functional import ( +from tests.utilities.functional import ( SafeStaticLiveServerTestCase, UserAuthenticatedLiveServerTestCase ) diff --git a/rcamp/accounts/test_models.py b/rcamp/rcamp/tests/test_accounts_models.py similarity index 99% rename from rcamp/accounts/test_models.py rename to rcamp/rcamp/tests/test_accounts_models.py index c5c6926..2be97a1 100644 --- a/rcamp/accounts/test_models.py +++ b/rcamp/rcamp/tests/test_accounts_models.py @@ -6,8 +6,8 @@ from django.conf import settings -from lib.test.utils import SafeTestCase -from lib.test.ldap import ( +from tests.utilities.utils import SafeTestCase +from tests.utilities.ldap import ( get_ldap_user_defaults, get_ldap_group_defaults, build_mock_rcldap_user, diff --git a/rcamp/accounts/test_views.py b/rcamp/rcamp/tests/test_accounts_views.py similarity index 99% rename from rcamp/accounts/test_views.py rename to rcamp/rcamp/tests/test_accounts_views.py index 32aa318..2a02c40 100644 --- a/rcamp/accounts/test_views.py +++ b/rcamp/rcamp/tests/test_accounts_views.py @@ -11,8 +11,8 @@ from django.conf import settings from django.contrib.sessions.middleware import SessionMiddleware -from lib.test.ldap import LdapTestCase -from lib.test.utils import ( +from tests.utilities.ldap import LdapTestCase +from tests.utilities.utils import ( SessionEnabledTestMixin, SafeTestCase ) diff --git a/rcamp/endpoints/tests.py b/rcamp/rcamp/tests/test_endpoints.py similarity index 99% rename from rcamp/endpoints/tests.py rename to rcamp/rcamp/tests/test_endpoints.py index ea60b98..e1cc7c7 100644 --- a/rcamp/endpoints/tests.py +++ b/rcamp/rcamp/tests/test_endpoints.py @@ -4,7 +4,7 @@ import json import datetime -from lib.test.utils import ( +from tests.utilities.utils import ( get_auth_user_defaults, SafeTestCase ) diff --git a/rcamp/lib/test_auth.py b/rcamp/rcamp/tests/test_lib_auth.py similarity index 98% rename from rcamp/lib/test_auth.py rename to rcamp/rcamp/tests/test_lib_auth.py index 0028b80..f33e32d 100644 --- a/rcamp/lib/test_auth.py +++ b/rcamp/rcamp/tests/test_lib_auth.py @@ -2,7 +2,7 @@ import mock import pam from lib.pam_backend import PamBackend -from lib.test.ldap import ( +from tests.utilities.ldap import ( LdapTestCase, get_ldap_user_defaults ) diff --git a/rcamp/lib/test_ldap_utils.py b/rcamp/rcamp/tests/test_lib_ldap_utils.py similarity index 98% rename from rcamp/lib/test_ldap_utils.py rename to rcamp/rcamp/tests/test_lib_ldap_utils.py index 73b9dfa..83b8c7e 100644 --- a/rcamp/lib/test_ldap_utils.py +++ b/rcamp/rcamp/tests/test_lib_ldap_utils.py @@ -4,7 +4,7 @@ get_suffixed_username, get_ldap_username_and_org ) -from lib.test.utils import SafeTestCase +from tests.utilities.utils import SafeTestCase class LdapUtilsTestCase(SafeTestCase): diff --git a/rcamp/mailer/tests.py b/rcamp/rcamp/tests/test_mailer.py similarity index 100% rename from rcamp/mailer/tests.py rename to rcamp/rcamp/tests/test_mailer.py diff --git a/rcamp/projects/test_functional.py b/rcamp/rcamp/tests/test_projects_functional.py similarity index 98% rename from rcamp/projects/test_functional.py rename to rcamp/rcamp/tests/test_projects_functional.py index a9c6821..78883be 100644 --- a/rcamp/projects/test_functional.py +++ b/rcamp/rcamp/tests/test_projects_functional.py @@ -2,8 +2,8 @@ from accounts.models import User import copy -from lib.test.utils import get_auth_user_defaults -from lib.test.functional import UserAuthenticatedLiveServerTestCase +from tests.utilities.utils import get_auth_user_defaults +from tests.utilities.functional import UserAuthenticatedLiveServerTestCase from projects.models import Project diff --git a/rcamp/projects/test_models.py b/rcamp/rcamp/tests/test_projects_models.py similarity index 99% rename from rcamp/projects/test_models.py rename to rcamp/rcamp/tests/test_projects_models.py index 7c24c41..3ce24dc 100644 --- a/rcamp/projects/test_models.py +++ b/rcamp/rcamp/tests/test_projects_models.py @@ -5,7 +5,7 @@ import pytz from django.conf import settings -from lib.test.utils import ( +from tests.utilities.utils import ( SafeTestCase, get_auth_user_defaults ) diff --git a/rcamp/projects/test_receivers.py b/rcamp/rcamp/tests/test_projects_receivers.py similarity index 97% rename from rcamp/projects/test_receivers.py rename to rcamp/rcamp/tests/test_projects_receivers.py index eb4f572..d41a589 100644 --- a/rcamp/projects/test_receivers.py +++ b/rcamp/rcamp/tests/test_projects_receivers.py @@ -2,8 +2,8 @@ import mock from django.test import override_settings -from lib.test.utils import SafeTestCase -from lib.test.ldap import get_ldap_user_defaults +from tests.utilities.utils import SafeTestCase +from tests.utilities.ldap import get_ldap_user_defaults from accounts.models import ( User, AccountRequest, diff --git a/rcamp/projects/test_views.py b/rcamp/rcamp/tests/test_projects_views.py similarity index 99% rename from rcamp/projects/test_views.py rename to rcamp/rcamp/tests/test_projects_views.py index ae240c8..fa1b854 100644 --- a/rcamp/projects/test_views.py +++ b/rcamp/rcamp/tests/test_projects_views.py @@ -6,7 +6,7 @@ from django.core.files.base import ContentFile from django.contrib.auth.models import User from django.contrib.auth.models import AnonymousUser -from lib.test.ldap import ( +from tests.utilities.ldap import ( LdapTestCase, get_ldap_user_defaults ) diff --git a/rcamp/rcamp/tests/utilities/__init__.py b/rcamp/rcamp/tests/utilities/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rcamp/lib/test/functional.py b/rcamp/rcamp/tests/utilities/functional.py similarity index 99% rename from rcamp/lib/test/functional.py rename to rcamp/rcamp/tests/utilities/functional.py index 8126605..22af37e 100644 --- a/rcamp/lib/test/functional.py +++ b/rcamp/rcamp/tests/utilities/functional.py @@ -5,7 +5,7 @@ import unittest import copy -from lib.test.utils import ( +from tests.utilities.utils import ( _assert_test_env_or_false, assert_test_env, _purge_ldap_objects diff --git a/rcamp/lib/test/ldap.py b/rcamp/rcamp/tests/utilities/ldap.py similarity index 98% rename from rcamp/lib/test/ldap.py rename to rcamp/rcamp/tests/utilities/ldap.py index 93dcd4b..6306837 100644 --- a/rcamp/lib/test/ldap.py +++ b/rcamp/rcamp/tests/utilities/ldap.py @@ -1,4 +1,4 @@ -from lib.test.utils import ( +from tests.utilities.utils import ( _purge_ldap_objects, SafeTestCase ) diff --git a/rcamp/lib/test/utils.py b/rcamp/rcamp/tests/utilities/utils.py similarity index 88% rename from rcamp/lib/test/utils.py rename to rcamp/rcamp/tests/utilities/utils.py index 33ce951..d0d9d2f 100644 --- a/rcamp/lib/test/utils.py +++ b/rcamp/rcamp/tests/utilities/utils.py @@ -1,3 +1,4 @@ +import os from django.test import TestCase from django.conf import settings from accounts.models import User @@ -14,11 +15,13 @@ def assert_test_env(): """Helper method to verify that tests are not being executed in a production environment.""" # We can reasonably assume that no production resource will satisfy this criteria, so # this is one of several safeguards against running the functional tests against prod. + assert os.environ.get('RCAMP_DEBUG') == 'True' assert settings.DATABASES['rcldap']['PASSWORD'] == 'password' - # In an abundance of caution, also make sure that the LDAP connection is configured - # to use localhost. - assert 'localhost' in settings.DATABASES['rcldap']['NAME'] - # Probably not running against prod LDAP. + # In an abundance of caution, also make sure that the LDAP and MySQL connections are configured + # to use the test services. + assert 'test-ldap' in settings.DATABASES['rcldap']['NAME'] + assert 'test-mysql' in settings.DATABASES['default']['HOST'] + # Probably not running against prod backends. return True def _assert_test_env_or_false(): @@ -63,7 +66,7 @@ class SafeTestCase(TestCase): connection settings can be changed within the context of of individual test cases. IMPORTANT: Every unit or integration test should inherit from this class. For functional tests - user lib.test.functional.SafeStaticLiveServerTestCase instead. + user tests.utilities.functional.SafeStaticLiveServerTestCase instead. """ @classmethod def setUpClass(cls): diff --git a/rcamp/uwsgi.ini b/rcamp/uwsgi.ini new file mode 100644 index 0000000..7970b42 --- /dev/null +++ b/rcamp/uwsgi.ini @@ -0,0 +1,12 @@ +[uwsgi] +socket = :8000 +chdir = /home/uwsgi/rcamp/ +wsgi-file = rcamp/wsgi.py +enable-threads = true +processes = 2 +threads = 2 +max-requests = 5000 +log-date = true +uid = uwsgi +gid = uwsgi +master = true From 0b5f18f49caa20ec616c4b46ef500b50852f1f55 Mon Sep 17 00:00:00 2001 From: Zebula Sampedro Date: Tue, 29 May 2018 14:37:26 -0600 Subject: [PATCH 02/49] Issues/314 (#315) * Subclassed PhantomJS driver for more durable builds. * Each test case gets a fresh webdriver. Slower, but worth a try. * Removed class-level setup and teardown. Closes #314. --- rcamp/rcamp/tests/utilities/functional.py | 41 +++++++++++++++-------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/rcamp/rcamp/tests/utilities/functional.py b/rcamp/rcamp/tests/utilities/functional.py index 22af37e..14669d9 100644 --- a/rcamp/rcamp/tests/utilities/functional.py +++ b/rcamp/rcamp/tests/utilities/functional.py @@ -1,6 +1,7 @@ from django.contrib.staticfiles.testing import StaticLiveServerTestCase from django.conf import settings from selenium import webdriver +from selenium.common import exceptions import datetime import unittest import copy @@ -18,6 +19,27 @@ ) +class PhantomJSWithRetry(webdriver.PhantomJS): + """ + Pulled from https://github.com/chris48s/UK-Polling-Stations/blob/66e96b52ce6bb6e9c0d864a8eb7e9bd53192f8b8/polling_stations/apps/data_finder/features/index.py + to get around https://github.com/ariya/phantomjs/issues/11526#issuecomment-133570834 + and https://github.com/travis-ci/travis-ci/issues/3251. + + Override execute() so it will retry if we get a selenium.common.exceptions.TimeoutException + this is a hack to work around an underlying issue in selenium and phantomjs running within a + Docker container. + """ + def execute(self, driver_command, params=None): + for _ in range(3): + try: + return super(PhantomJSWithRetry,self).execute(driver_command, params) + except exceptions.TimeoutException as e: + print('trying again...') + error = e + print('giving up! :(') + raise error + + @unittest.skipUnless(_assert_test_env_or_false(),"Tests are not being run against a safe test environment!") class SafeStaticLiveServerTestCase(StaticLiveServerTestCase): """ @@ -36,28 +58,19 @@ class SafeStaticLiveServerTestCase(StaticLiveServerTestCase): All RCAMP functional tests should inherit from this class. """ - @classmethod - def setUpClass(cls): - assert_test_env() - # Start the web driver - cls.browser = webdriver.PhantomJS() - cls.browser.set_window_size(1366, 768) - super(SafeStaticLiveServerTestCase,cls).setUpClass() - - @classmethod - def tearDownClass(cls): - cls.browser.quit() - assert_test_env() - super(SafeStaticLiveServerTestCase,cls).tearDownClass() - def setUp(self): assert_test_env() + self.browser = PhantomJSWithRetry() + self.browser.set_page_load_timeout(10) + self.browser.set_script_timeout(10) + self.browser.set_window_size(1366, 768) _purge_ldap_objects() super(SafeStaticLiveServerTestCase,self).setUp() def tearDown(self): assert_test_env() _purge_ldap_objects() + self.browser.quit() super(SafeStaticLiveServerTestCase,self).tearDown() class UserAuthenticatedLiveServerTestCase(SafeStaticLiveServerTestCase): From 609af78115788ad049ac3f03852d6c8078ba253c Mon Sep 17 00:00:00 2001 From: Zebula Sampedro Date: Tue, 29 May 2018 16:39:52 -0600 Subject: [PATCH 03/49] Added missing import, fixes #303. (#313) * Added missing import, fixes #303. * Issues/314 (#315) * Subclassed PhantomJS driver for more durable builds. * Each test case gets a fresh webdriver. Slower, but worth a try. * Removed class-level setup and teardown. Closes #314. * Added missing import, fixes #303. --- rcamp/rcamp/projects/receivers.py | 3 ++- rcamp/rcamp/tests/test_projects_receivers.py | 22 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/rcamp/rcamp/projects/receivers.py b/rcamp/rcamp/projects/receivers.py index 9009bf4..3268c5a 100644 --- a/rcamp/rcamp/projects/receivers.py +++ b/rcamp/rcamp/projects/receivers.py @@ -5,7 +5,8 @@ from accounts.models import ( User, - AccountRequest + AccountRequest, + Intent ) from projects.models import Project diff --git a/rcamp/rcamp/tests/test_projects_receivers.py b/rcamp/rcamp/tests/test_projects_receivers.py index d41a589..dc07320 100644 --- a/rcamp/rcamp/tests/test_projects_receivers.py +++ b/rcamp/rcamp/tests/test_projects_receivers.py @@ -113,3 +113,25 @@ def test_check_general_eligibility_suffixed(self): project = Project.objects.get() self.assertIn(auth_user,project.collaborators.all()) + + def test_check_general_eligibility_no_intent(self): + user_defaults = get_ldap_user_defaults() + + auth_user_defaults = dict( + username=user_defaults['username'], + first_name=user_defaults['first_name'], + last_name=user_defaults['last_name'], + email=user_defaults['email'] + ) + auth_user = User.objects.create(**auth_user_defaults) + + account_request_defaults = dict( + username=auth_user.username, + first_name=auth_user.first_name, + last_name=auth_user.last_name, + email=auth_user.email, + organization='ucb' + ) + account_request = AccountRequest.objects.create(**account_request_defaults) + + check_general_eligibility(account_request.__class__,account_request=account_request) From a56ea7121d4406fd5b611384527cc65c90ccefdf Mon Sep 17 00:00:00 2001 From: Zebula Sampedro Date: Wed, 30 May 2018 09:58:50 -0600 Subject: [PATCH 04/49] Use the built-in user admin for the custom user model. Fixes #270. (#316) --- rcamp/rcamp/accounts/admin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rcamp/rcamp/accounts/admin.py b/rcamp/rcamp/accounts/admin.py index 1119f58..6469763 100644 --- a/rcamp/rcamp/accounts/admin.py +++ b/rcamp/rcamp/accounts/admin.py @@ -1,4 +1,5 @@ from django.contrib import admin +from django.contrib.auth import admin as auth_admin from django import forms from lib.fields import LdapCsvField from accounts.models import ( @@ -14,7 +15,7 @@ @admin.register(User) -class UserAdmin(admin.ModelAdmin): +class UserAdmin(auth_admin.UserAdmin): list_display = ['username','organization','first_name','last_name','email'] search_fields = ['username','first_name','last_name','email'] From e1fcb6ca53a4c10392e67c24b57ae4c7403b8b52 Mon Sep 17 00:00:00 2001 From: Zebula Sampedro Date: Tue, 22 May 2018 15:54:42 -0600 Subject: [PATCH 05/49] Issues/300 (#312) * Starting to containerize and compose infrastructure. * Got dev stack working under Compose. * Added PhantomJS and prerequisites for test env. * Added prod config to compose stack. * Working prod config. * Separated out test backends for layering on dev and staging deployments. * Moved media uploads directory to a volume, toggle media dev endpoint. * Added gosu entrypoint to properly set permissions on shared volumes. * Toggle entire test suite with debug, closes #302. * Store logs in docker volumes. * Restructured dev config for CI. * Don't require SSH for submodule * Always log to volume. * Added Travis config. * Disabled build notifications for now, updated docker-compose in Travis CI environment. * Override script and install tags. * Added encrypted notifier token to Travis build config. * Updated token. * Revert "Updated token." This reverts commit 66e14e14cceea4d7abcb11d141eba5af020bf1c2. * Updated Slack config. * Refactored environment variables. --- .gitignore | 6 + .gitmodules | 3 + .travis.yml | 25 +++ LICENSE | 2 +- README.md | 43 ++-- docker-compose.dev.yml | 19 ++ docker-compose.prod.yml | 39 ++++ docker-compose.test-backends.yml | 14 ++ docker-compose.yml | 21 ++ nginx/nginx.conf | 64 ++++++ nginx/uwsgi_params | 13 ++ rcamp/Dockerfile | 58 ++++++ rcamp/Dockerfile.test | 18 ++ rcamp/docker-entrypoint.sh | 13 ++ rcamp/ldapdb | 1 + rcamp/{ => rcamp}/accounts/__init__.py | 0 rcamp/{ => rcamp}/accounts/admin.py | 0 rcamp/{ => rcamp}/accounts/forms.py | 0 .../accounts/management/__init__.py | 0 .../accounts/management/commands/__init__.py | 0 .../management/commands/givesuperuser.py | 18 +- .../management/commands/syncldapusers.py | 0 .../management/commands/transformdatadump.py | 0 .../accounts/migrations/0001_initial.py | 0 .../migrations/0002_auto_20171213_1604.py | 0 .../migrations/0003_auto_20180228_1158.py | 0 .../accounts/migrations/__init__.py | 0 rcamp/{ => rcamp}/accounts/models.py | 0 .../templates/account-request-intent.html | 0 .../templates/account-request-org-select.html | 0 .../templates/account-request-review.html | 0 .../templates/account-request-verify-csu.html | 0 .../templates/account-request-verify-ucb.html | 0 rcamp/{ => rcamp}/accounts/urls.py | 0 rcamp/{ => rcamp}/accounts/views.py | 0 rcamp/rcamp/dev_settings.py | 106 ---------- rcamp/{ => rcamp}/endpoints/__init__.py | 0 rcamp/{ => rcamp}/endpoints/filters.py | 0 rcamp/{ => rcamp}/endpoints/serializers.py | 0 rcamp/{ => rcamp}/endpoints/urls.py | 0 rcamp/{ => rcamp}/endpoints/viewsets.py | 0 rcamp/{ => rcamp}/lib/__init__.py | 0 rcamp/{ => rcamp}/lib/fields.py | 0 rcamp/{ => rcamp}/lib/ldap_utils.py | 0 rcamp/{ => rcamp}/lib/pam_backend.py | 0 rcamp/{ => rcamp}/lib/router.py | 0 rcamp/{ => rcamp}/lib/views.py | 0 rcamp/{lib/test => rcamp/mailer}/__init__.py | 0 rcamp/{ => rcamp}/mailer/admin.py | 0 .../mailer/migrations/0001_initial.py | 0 .../mailer/migrations}/__init__.py | 0 rcamp/{ => rcamp}/mailer/models.py | 0 rcamp/{ => rcamp}/mailer/receivers.py | 0 rcamp/{ => rcamp}/mailer/signals.py | 0 rcamp/{ => rcamp}/manage.py | 0 .../migrations => rcamp/projects}/__init__.py | 0 rcamp/{ => rcamp}/projects/admin.py | 0 rcamp/{ => rcamp}/projects/forms.py | 0 .../projects/management}/__init__.py | 0 .../projects/management/commands}/__init__.py | 0 .../projects/migrations/0001_initial.py | 0 .../migrations/0002_auto_20180326_1507.py | 0 .../migrations/0003_auto_20180326_1508.py | 0 .../migrations/0004_auto_20180326_1529.py | 0 .../projects/migrations}/__init__.py | 0 rcamp/{ => rcamp}/projects/models.py | 0 rcamp/{ => rcamp}/projects/receivers.py | 0 .../templates/allocation-request-create.html | 0 .../templates/allocation-request-detail.html | 0 .../projects/templates/project-create.html | 0 .../projects/templates/project-detail.html | 0 .../projects/templates/project-edit.html | 0 .../projects/templates/project-list.html | 0 .../projects/templates/reference-create.html | 0 .../projects/templates/reference-detail.html | 0 .../projects/templates/reference-edit.html | 0 rcamp/{ => rcamp}/projects/urls.py | 0 rcamp/{ => rcamp}/projects/views.py | 0 rcamp/rcamp/{ => rcamp}/.bowerrc | 0 .../migrations => rcamp/rcamp}/__init__.py | 0 rcamp/rcamp/{ => rcamp}/bower.json | 0 rcamp/rcamp/rcamp/settings/__init__.py | 5 + rcamp/rcamp/rcamp/settings/auth.py | 13 ++ rcamp/rcamp/rcamp/settings/databases.py | 96 +++++++++ rcamp/rcamp/rcamp/settings/logging.py | 42 ++++ rcamp/rcamp/rcamp/settings/main.py | 110 +++++++++++ rcamp/rcamp/rcamp/settings/organizations.py | 31 +++ rcamp/rcamp/rcamp/settings/toggles.py | 3 + .../static/css/account-request.css | 0 .../{ => rcamp}/static/css/jumbotron.css | 0 rcamp/rcamp/{ => rcamp}/static/css/login.css | 0 .../{ => rcamp}/static/css/project-create.css | 0 .../rcamp/{ => rcamp}/static/css/projects.css | 0 rcamp/rcamp/{ => rcamp}/static/css/rcamp.css | 0 .../rcamp/{ => rcamp}/static/css/selector.css | 0 rcamp/rcamp/{ => rcamp}/static/img/._logo.png | Bin .../static/img/coolaisle-blue-cmp.jpg | Bin rcamp/rcamp/{ => rcamp}/static/img/logo.png | Bin .../static/img/memory-heatmap-cmp.jpg | Bin .../{ => rcamp}/static/img/molecule-cmp.jpg | Bin .../{ => rcamp}/static/js/SelectFilter2.js | 0 rcamp/rcamp/{ => rcamp}/static/js/jsi18n.js | 0 rcamp/rcamp/{ => rcamp}/templates/404.html | 0 rcamp/rcamp/{ => rcamp}/templates/500.html | 0 rcamp/rcamp/{ => rcamp}/templates/base.html | 0 rcamp/rcamp/{ => rcamp}/templates/index.html | 0 rcamp/rcamp/{ => rcamp}/templates/login.html | 0 rcamp/rcamp/{ => rcamp}/templates/logout.html | 0 .../templates/terms-and-conditions.html | 0 rcamp/rcamp/{ => rcamp}/urls.py | 5 + rcamp/rcamp/{ => rcamp}/wsgi.py | 0 .../rcamp/requirements.txt | 2 +- rcamp/rcamp/settings.py | 183 ------------------ rcamp/rcamp/{ => tests}/__init__.py | 0 .../tests/test_accounts_commands.py} | 4 +- .../tests/test_accounts_forms.py} | 2 +- .../tests/test_accounts_functional.py} | 4 +- .../tests/test_accounts_models.py} | 4 +- .../tests/test_accounts_views.py} | 4 +- .../tests/test_endpoints.py} | 2 +- .../tests/test_lib_auth.py} | 2 +- .../tests/test_lib_ldap_utils.py} | 2 +- .../tests.py => rcamp/tests/test_mailer.py} | 0 .../tests/test_projects_functional.py} | 4 +- .../tests/test_projects_models.py} | 2 +- .../tests/test_projects_receivers.py} | 4 +- .../tests/test_projects_views.py} | 2 +- rcamp/rcamp/tests/utilities/__init__.py | 0 .../tests/utilities}/functional.py | 2 +- .../test => rcamp/tests/utilities}/ldap.py | 2 +- .../test => rcamp/tests/utilities}/utils.py | 13 +- rcamp/uwsgi.ini | 12 ++ 132 files changed, 678 insertions(+), 340 deletions(-) create mode 100644 .gitmodules create mode 100644 .travis.yml create mode 100644 docker-compose.dev.yml create mode 100644 docker-compose.prod.yml create mode 100644 docker-compose.test-backends.yml create mode 100644 docker-compose.yml create mode 100644 nginx/nginx.conf create mode 100644 nginx/uwsgi_params create mode 100644 rcamp/Dockerfile create mode 100644 rcamp/Dockerfile.test create mode 100644 rcamp/docker-entrypoint.sh create mode 160000 rcamp/ldapdb rename rcamp/{ => rcamp}/accounts/__init__.py (100%) rename rcamp/{ => rcamp}/accounts/admin.py (100%) rename rcamp/{ => rcamp}/accounts/forms.py (100%) rename rcamp/{ => rcamp}/accounts/management/__init__.py (100%) rename rcamp/{ => rcamp}/accounts/management/commands/__init__.py (100%) rename rcamp/{ => rcamp}/accounts/management/commands/givesuperuser.py (82%) rename rcamp/{ => rcamp}/accounts/management/commands/syncldapusers.py (100%) rename rcamp/{ => rcamp}/accounts/management/commands/transformdatadump.py (100%) rename rcamp/{ => rcamp}/accounts/migrations/0001_initial.py (100%) rename rcamp/{ => rcamp}/accounts/migrations/0002_auto_20171213_1604.py (100%) rename rcamp/{ => rcamp}/accounts/migrations/0003_auto_20180228_1158.py (100%) rename rcamp/{ => rcamp}/accounts/migrations/__init__.py (100%) rename rcamp/{ => rcamp}/accounts/models.py (100%) rename rcamp/{ => rcamp}/accounts/templates/account-request-intent.html (100%) rename rcamp/{ => rcamp}/accounts/templates/account-request-org-select.html (100%) rename rcamp/{ => rcamp}/accounts/templates/account-request-review.html (100%) rename rcamp/{ => rcamp}/accounts/templates/account-request-verify-csu.html (100%) rename rcamp/{ => rcamp}/accounts/templates/account-request-verify-ucb.html (100%) rename rcamp/{ => rcamp}/accounts/urls.py (100%) rename rcamp/{ => rcamp}/accounts/views.py (100%) delete mode 100644 rcamp/rcamp/dev_settings.py rename rcamp/{ => rcamp}/endpoints/__init__.py (100%) rename rcamp/{ => rcamp}/endpoints/filters.py (100%) rename rcamp/{ => rcamp}/endpoints/serializers.py (100%) rename rcamp/{ => rcamp}/endpoints/urls.py (100%) rename rcamp/{ => rcamp}/endpoints/viewsets.py (100%) rename rcamp/{ => rcamp}/lib/__init__.py (100%) rename rcamp/{ => rcamp}/lib/fields.py (100%) rename rcamp/{ => rcamp}/lib/ldap_utils.py (100%) rename rcamp/{ => rcamp}/lib/pam_backend.py (100%) rename rcamp/{ => rcamp}/lib/router.py (100%) rename rcamp/{ => rcamp}/lib/views.py (100%) rename rcamp/{lib/test => rcamp/mailer}/__init__.py (100%) rename rcamp/{ => rcamp}/mailer/admin.py (100%) rename rcamp/{ => rcamp}/mailer/migrations/0001_initial.py (100%) rename rcamp/{mailer => rcamp/mailer/migrations}/__init__.py (100%) rename rcamp/{ => rcamp}/mailer/models.py (100%) rename rcamp/{ => rcamp}/mailer/receivers.py (100%) rename rcamp/{ => rcamp}/mailer/signals.py (100%) rename rcamp/{ => rcamp}/manage.py (100%) rename rcamp/{mailer/migrations => rcamp/projects}/__init__.py (100%) rename rcamp/{ => rcamp}/projects/admin.py (100%) rename rcamp/{ => rcamp}/projects/forms.py (100%) rename rcamp/{projects => rcamp/projects/management}/__init__.py (100%) rename rcamp/{projects/management => rcamp/projects/management/commands}/__init__.py (100%) rename rcamp/{ => rcamp}/projects/migrations/0001_initial.py (100%) rename rcamp/{ => rcamp}/projects/migrations/0002_auto_20180326_1507.py (100%) rename rcamp/{ => rcamp}/projects/migrations/0003_auto_20180326_1508.py (100%) rename rcamp/{ => rcamp}/projects/migrations/0004_auto_20180326_1529.py (100%) rename rcamp/{projects/management/commands => rcamp/projects/migrations}/__init__.py (100%) rename rcamp/{ => rcamp}/projects/models.py (100%) rename rcamp/{ => rcamp}/projects/receivers.py (100%) rename rcamp/{ => rcamp}/projects/templates/allocation-request-create.html (100%) rename rcamp/{ => rcamp}/projects/templates/allocation-request-detail.html (100%) rename rcamp/{ => rcamp}/projects/templates/project-create.html (100%) rename rcamp/{ => rcamp}/projects/templates/project-detail.html (100%) rename rcamp/{ => rcamp}/projects/templates/project-edit.html (100%) rename rcamp/{ => rcamp}/projects/templates/project-list.html (100%) rename rcamp/{ => rcamp}/projects/templates/reference-create.html (100%) rename rcamp/{ => rcamp}/projects/templates/reference-detail.html (100%) rename rcamp/{ => rcamp}/projects/templates/reference-edit.html (100%) rename rcamp/{ => rcamp}/projects/urls.py (100%) rename rcamp/{ => rcamp}/projects/views.py (100%) rename rcamp/rcamp/{ => rcamp}/.bowerrc (100%) rename rcamp/{projects/migrations => rcamp/rcamp}/__init__.py (100%) rename rcamp/rcamp/{ => rcamp}/bower.json (100%) create mode 100644 rcamp/rcamp/rcamp/settings/__init__.py create mode 100644 rcamp/rcamp/rcamp/settings/auth.py create mode 100644 rcamp/rcamp/rcamp/settings/databases.py create mode 100644 rcamp/rcamp/rcamp/settings/logging.py create mode 100644 rcamp/rcamp/rcamp/settings/main.py create mode 100644 rcamp/rcamp/rcamp/settings/organizations.py create mode 100644 rcamp/rcamp/rcamp/settings/toggles.py rename rcamp/rcamp/{ => rcamp}/static/css/account-request.css (100%) rename rcamp/rcamp/{ => rcamp}/static/css/jumbotron.css (100%) rename rcamp/rcamp/{ => rcamp}/static/css/login.css (100%) rename rcamp/rcamp/{ => rcamp}/static/css/project-create.css (100%) rename rcamp/rcamp/{ => rcamp}/static/css/projects.css (100%) rename rcamp/rcamp/{ => rcamp}/static/css/rcamp.css (100%) rename rcamp/rcamp/{ => rcamp}/static/css/selector.css (100%) rename rcamp/rcamp/{ => rcamp}/static/img/._logo.png (100%) rename rcamp/rcamp/{ => rcamp}/static/img/coolaisle-blue-cmp.jpg (100%) rename rcamp/rcamp/{ => rcamp}/static/img/logo.png (100%) rename rcamp/rcamp/{ => rcamp}/static/img/memory-heatmap-cmp.jpg (100%) rename rcamp/rcamp/{ => rcamp}/static/img/molecule-cmp.jpg (100%) rename rcamp/rcamp/{ => rcamp}/static/js/SelectFilter2.js (100%) rename rcamp/rcamp/{ => rcamp}/static/js/jsi18n.js (100%) rename rcamp/rcamp/{ => rcamp}/templates/404.html (100%) rename rcamp/rcamp/{ => rcamp}/templates/500.html (100%) rename rcamp/rcamp/{ => rcamp}/templates/base.html (100%) rename rcamp/rcamp/{ => rcamp}/templates/index.html (100%) rename rcamp/rcamp/{ => rcamp}/templates/login.html (100%) rename rcamp/rcamp/{ => rcamp}/templates/logout.html (100%) rename rcamp/rcamp/{ => rcamp}/templates/terms-and-conditions.html (100%) rename rcamp/rcamp/{ => rcamp}/urls.py (89%) rename rcamp/rcamp/{ => rcamp}/wsgi.py (100%) rename requirements.txt => rcamp/rcamp/requirements.txt (84%) delete mode 100644 rcamp/rcamp/settings.py rename rcamp/rcamp/{ => tests}/__init__.py (100%) rename rcamp/{accounts/test_commands.py => rcamp/tests/test_accounts_commands.py} (86%) rename rcamp/{accounts/test_forms.py => rcamp/tests/test_accounts_forms.py} (99%) rename rcamp/{accounts/test_functional.py => rcamp/tests/test_accounts_functional.py} (99%) rename rcamp/{accounts/test_models.py => rcamp/tests/test_accounts_models.py} (99%) rename rcamp/{accounts/test_views.py => rcamp/tests/test_accounts_views.py} (99%) rename rcamp/{endpoints/tests.py => rcamp/tests/test_endpoints.py} (99%) rename rcamp/{lib/test_auth.py => rcamp/tests/test_lib_auth.py} (98%) rename rcamp/{lib/test_ldap_utils.py => rcamp/tests/test_lib_ldap_utils.py} (98%) rename rcamp/{mailer/tests.py => rcamp/tests/test_mailer.py} (100%) rename rcamp/{projects/test_functional.py => rcamp/tests/test_projects_functional.py} (98%) rename rcamp/{projects/test_models.py => rcamp/tests/test_projects_models.py} (99%) rename rcamp/{projects/test_receivers.py => rcamp/tests/test_projects_receivers.py} (97%) rename rcamp/{projects/test_views.py => rcamp/tests/test_projects_views.py} (99%) create mode 100644 rcamp/rcamp/tests/utilities/__init__.py rename rcamp/{lib/test => rcamp/tests/utilities}/functional.py (99%) rename rcamp/{lib/test => rcamp/tests/utilities}/ldap.py (98%) rename rcamp/{lib/test => rcamp/tests/utilities}/utils.py (88%) create mode 100644 rcamp/uwsgi.ini diff --git a/.gitignore b/.gitignore index bf8f2ad..4cba4d3 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,9 @@ docs/_build/ # PyBuilder target/ + +# Docker stuff: +.env +certs/ +db/ +media/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..b2304bd --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "rcamp/ldapdb"] + path = rcamp/ldapdb + url = https://github.com/ResearchComputing/django-ldapdb.git diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..e8a0ac3 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,25 @@ +sudo: required + +language: python + +services: + - docker + +before_install: +- pip install --upgrade docker-compose +- cd rcamp +- docker build -t dev/rcamp --build-arg UWSGI_UID=$(id -u) --build-arg UWSGI_GID=$(id -u) . +- cd .. +- export RCAMP_PORT=9000 +- docker-compose -f docker-compose.yml -f docker-compose.test-backends.yml -f docker-compose.dev.yml build +- docker-compose -f docker-compose.yml -f docker-compose.test-backends.yml -f docker-compose.dev.yml run --rm --service-ports rcamp-uwsgi bash -c 'sleep 30s && python manage.py migrate' +- docker-compose -f docker-compose.yml -f docker-compose.test-backends.yml -f docker-compose.dev.yml run --rm --service-ports rcamp-uwsgi bash -c 'python manage.py test' + +install: true +script: true + +notifications: + email: false + slack: + rooms: + secure: sEWHI86XLXXuVAQd15UbDMPpDKop/bTDn/XynrLKqp+GF+28h8BtewVZXCMHHir3ZCFdb2oRqG1qJ+g3kr8AY5xCadt8xu7BYZTAbGJdlv4tqTuGCNdUTr60wkafmvqYx2UZuawTLLAfy31bgzfGcpq068ni0MxYIn4PNJq0lqcUZoFvhlTT5lXrBWhu7q4JCTvfCBni/shjWKW8zmP5QP1GXSpPeHI9AZmBr2luczc2izVJbyTPEipNk1a57l8D5MeAGz+LE8AkXgbd3yl3KWgU+ZgUd8Jga09B9oARBBqG/1sVb1pCAkQQ2qDd+nByNfkPbcOn0LXhT6LM8sX/HVi7NZD1byB/u6qiycmDvf2rb+7Xz7Z2/eN4Rycf5+3JBuKCg2eFbX0Beo3RLJgmn+dYbWqD3YRAupv8nwZci2Km6AS3cWJi3HhQK85r6xGrmWdW5yqMxbaxiz2PAjtwb2aIdaMb+kgYsuDiYBLprNLWRl8sp3feyxWNCeudtQBxrbDX6gGjri2m8IQlDJv+LRwFaFgGF2xkAy/JMpVdDncqLAQrkjVaQbap1uZYVQyafWDPdLQbMdlt+bR92/bqoD9oZLRVsmOiVfLwxki20jm0cQfOQJL3nRIccdrFSLejMmxc+u6aE8EWSHHswoERmU6H4mDSIotV9jhQSNW3qEU= diff --git a/LICENSE b/LICENSE index 137ab56..85e0f2d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ The MIT License (MIT) -Copyright (c) 2016 Zebula Sampedro +Copyright (c) 2018 Zebula Sampedro Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/README.md b/README.md index 75d9f09..dc3a3ad 100644 --- a/README.md +++ b/README.md @@ -15,40 +15,37 @@ Research Computing Administrative & Management Portal **rcamp** - The rcamp directory contains site code and, most importantly, settings. -## Installation +## Setting up your dev environment +You will need Docker 18.03+ and Compose 1.21+ before you begin. Documentation for Docker can be found here: https://docs.docker.com/install/. -Clone RCAMP +Start by cloning RCAMP. ``` -git clone https://github.com/ResearchComputing/RCAMP +$ git clone https://github.com/ResearchComputing/RCAMP +$ git submodule update --init +$ cd RCAMP ``` -Install the RC fork of django-ldapdb +Then build the RCAMP base image, making sure to pass your local account UID/GID as build args _(this is necessary for bind-mounting your code later)_. ``` -git clone https://github.com/ResearchComputing/django-ldapdb -cd django-ldapdb -python setup.py install +$ cd rcamp +$ docker build -t dev/rcamp --build-arg UWSGI_UID=$(id -u) --build-arg UWSGI_GID=$(id -g) . +$ cd .. ``` -Install remaining project dependencies +Build your dev environment and then start it using Compose. ``` -cd ../RCAMP -pip install -r requirements.txt +$ export RCAMP_PORT=9000 +$ docker-compose -f docker-compose.yml -f docker-compose.test-backends.yml -f docker-compose.dev.yml build +$ docker-compose -f docker-compose.yml -f docker-compose.test-backends.yml -f docker-compose.dev.yml run --rm --service-ports rcamp-uwsgi bash -c 'sleep 30s && python manage.py migrate' +$ docker-compose -f docker-compose.yml -f docker-compose.test-backends.yml -f docker-compose.dev.yml up -d ``` -Configure local settings. Configuration in `local_settings.py` will override configuration in `settings.py`. +Finish by migrating the DB and adding a superuser to the RCAMP app. You'll need to attach to the running RCAMP service to do this: ``` -cd rcamp/rcamp -touch local_settings.py -# Configure fields in local_settings as needed. -``` -Collect static files -``` -python manage.py collectstatic -``` - -Set up the database (SQLite3 preferred for dev/testing). -``` -python manage.py migrate +$ docker exec -it rcamp_rcamp-uwsgi_1 /bin/bash +~rcamp-uwsgi$ python manage.py migrate +~rcamp-uwsgi$ python manage.py createsuperuser +... ``` ## Writing and Running Tests diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..820f818 --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,19 @@ +version: "3.6" + +services: + rcamp-uwsgi: + build: + context: rcamp + cache_from: + - dev/rcamp + dockerfile: Dockerfile.test + environment: + - RCAMP_DEBUG=True + volumes: + - ./rcamp/rcamp:/home/uwsgi/rcamp + - ./rcamp/ldapdb:/home/uwsgi/ldapdb + ports: + - "${RCAMP_PORT}:9000" + depends_on: + - test-mysql + - test-ldap diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..578aea0 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,39 @@ +version: "3.6" + +services: + rcamp-uwsgi: + environment: + # Jenkins will load these values from Vault and then export them to the environment + # during deployment. + - RCAMP_DEBUG=False + - RCAMP_SECRET_KEY=${RCAMP_SECRET_KEY} + - RCAMP_ALLOWEDHOSTS=${RCAMP_ALLOWEDHOSTS} + - RCAMP_DB_HOST=${RCAMP_DB_HOST} + - RCAMP_DB_USER=${RCAMP_DB_USER} + - RCAMP_DB_PASSWORD=${RCAMP_DB_PASSWORD} + - RCAMP_RC_LDAP_URI=${RCAMP_RC_LDAP_URI} + - RCAMP_RC_LDAP_USER=${RCAMP_RC_LDAP_USER} + - RCAMP_RC_LDAP_PASSWORD=${RCAMP_RC_LDAP_PASSWORD} + volumes: + - /var/lib/sss/pipes:/var/lib/sss/pipes:rw + - /etc/nsswitch.conf:/etc/nsswitch.conf + - /etc/pam.d:/etc/pam.d + + nginx: + hostname: ${HOSTNAME} + image: nginx:stable + volumes: + - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro + - ./nginx/uwsgi_params:/etc/nginx/uwsgi_params:ro + - ./certs:/etc/nginx/certs:ro + - static-content:/var/www/static:ro + - media-uploads:/var/www/media:ro + - nginx-logs:/var/logs/nginx + ports: + - "80:80" + - "443:443" + depends_on: + - rcamp-uwsgi + +volumes: + nginx-logs: diff --git a/docker-compose.test-backends.yml b/docker-compose.test-backends.yml new file mode 100644 index 0000000..d1b7398 --- /dev/null +++ b/docker-compose.test-backends.yml @@ -0,0 +1,14 @@ +version: "3.6" + +services: + test-mysql: + image: mysql:5.7 + environment: + - MYSQL_ROOT_PASSWORD=password + - MYSQL_DATABASE=rcamp1712 + volumes: + - ./db:/var/lib/mysql + + test-ldap: + image: researchcomputing/rc-test-ldap + # build: ldap diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..0378983 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,21 @@ +version: "3.6" + +services: + rcamp-uwsgi: + build: rcamp + environment: + - RCAMP_UCB_LDAP_URI=${RCAMP_UCB_LDAP_URI} + - RCAMP_UCB_LDAP_USER=${RCAMP_UCB_LDAP_USER} + - RCAMP_UCB_LDAP_PASSWORD=${RCAMP_UCB_LDAP_PASSWORD} + - RCAMP_CSU_LDAP_URI=${RCAMP_CSU_LDAP_URI} + - RCAMP_CSU_LDAP_USER=${RCAMP_CSU_LDAP_USER} + - RCAMP_CSU_LDAP_PASSWORD=${RCAMP_CSU_LDAP_PASSWORD} + volumes: + - static-content:/home/uwsgi/rcamp/static + - media-uploads:/home/uwsgi/rcamp/media + - rcamp-logs:/home/uwsgi/rcamp/logs + +volumes: + static-content: + media-uploads: + rcamp-logs: diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 0000000..7cf0d0d --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,64 @@ +server { + listen *:80; + server_name localhost; + + client_max_body_size 8000M; + client_body_buffer_size 8000M; + client_body_timeout 120; + + if ($ssl_protocol = "") { + return 301 https://$host$request_uri; + } + + location /images { + alias /var/www/images; + } + + location / { + include /etc/nginx/uwsgi_params; + uwsgi_pass rcamp-uwsgi:8000; + } + + location /static { + allow all; + alias /var/www/static; + } + + location /media { + allow all; + alias /var/www/media; + } +} + +server { + listen *:443 ssl; + server_name localhost; + + ssl on; + + ssl_certificate /etc/nginx/certs/rcamp.crt; + ssl_certificate_key /etc/nginx/certs/rcamp.key; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 5m; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA; + ssl_prefer_server_ciphers on; + + access_log /var/log/nginx/rcamp.access.log combined; + error_log /var/log/nginx/rcamp.error.log; + + location / { + include /etc/nginx/uwsgi_params; + uwsgi_pass rcamp-uwsgi:8000; + } + + location /static { + allow all; + alias /var/www/static; + } + + location /media { + allow all; + alias /var/www/media; + } +} diff --git a/nginx/uwsgi_params b/nginx/uwsgi_params new file mode 100644 index 0000000..c7727cd --- /dev/null +++ b/nginx/uwsgi_params @@ -0,0 +1,13 @@ +uwsgi_param QUERY_STRING $query_string; +uwsgi_param REQUEST_METHOD $request_method; +uwsgi_param CONTENT_TYPE $content_type; +uwsgi_param CONTENT_LENGTH $content_length; +uwsgi_param REQUEST_URI $request_uri; +uwsgi_param PATH_INFO $document_uri; +uwsgi_param DOCUMENT_ROOT $document_root; +uwsgi_param SERVER_PROTOCOL $server_protocol; +uwsgi_param REMOTE_ADDR $remote_addr; +uwsgi_param REMOTE_PORT $remote_port; +uwsgi_param SERVER_ADDR $server_addr; +uwsgi_param SERVER_PORT $server_port; +uwsgi_param SERVER_NAME $server_name; diff --git a/rcamp/Dockerfile b/rcamp/Dockerfile new file mode 100644 index 0000000..4b04b0f --- /dev/null +++ b/rcamp/Dockerfile @@ -0,0 +1,58 @@ +FROM centos:7 +MAINTAINER Zebula Sampedro + +# Install gosu to drop user and chown shared volumes at runtime +RUN export GOSU_VERSION=1.10 && \ + yum -y install epel-release && \ + yum -y install wget dpkg && \ + dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')" && \ + wget -O /usr/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch" && \ + wget -O /tmp/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc" && \ + export GNUPGHOME="$(mktemp -d)" && \ + gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 && \ + gpg --batch --verify /tmp/gosu.asc /usr/bin/gosu && \ + rm -r "$GNUPGHOME" /tmp/gosu.asc && \ + chmod +x /usr/bin/gosu; \ + gosu nobody true && \ + yum -y remove wget dpkg && \ + yum clean all && \ + unset GOSU_VERSION + +# Add uwsgi user to the image +ARG UWSGI_UID=1000 +ARG UWSGI_GID=1000 +# Set env vars from these args, as there is no utility in forcing the user to set them twice in dev. +ENV UID=${UWSGI_UID} +ENV GID=${UWSGI_GID} + +RUN groupadd -g $GID uwsgi && \ + useradd -d "/home/uwsgi" -u "$UID" -g "$GID" -m -s /bin/bash "uwsgi" + +WORKDIR /home/uwsgi + +# Install core dependencies +RUN yum -y update && \ + yum makecache fast && \ + yum -y groupinstall "Development Tools" && \ + yum -y install epel-release curl which wget && \ + yum -y install sssd pam-devel openssl-devel && \ + yum -y install python-devel python2-pip && \ + yum -y install openldap-devel MySQL-python + +# Add uwsgi conf +COPY --chown=uwsgi:uwsgi uwsgi.ini /home/uwsgi/uwsgi.ini + +# Add codebase to container and install +COPY --chown=uwsgi:uwsgi ldapdb /home/uwsgi/ldapdb +COPY --chown=uwsgi:uwsgi rcamp /home/uwsgi/rcamp + +WORKDIR /home/uwsgi/ldapdb +RUN pip install -e . + +WORKDIR /home/uwsgi/rcamp +RUN pip2 install -r requirements.txt + +# Set gosu entrypoint and default command +COPY docker-entrypoint.sh /usr/local/bin/ +ENTRYPOINT ["sh","/usr/local/bin/docker-entrypoint.sh"] +CMD ["/usr/bin/uwsgi","/home/uwsgi/uwsgi.ini"] diff --git a/rcamp/Dockerfile.test b/rcamp/Dockerfile.test new file mode 100644 index 0000000..f91db7c --- /dev/null +++ b/rcamp/Dockerfile.test @@ -0,0 +1,18 @@ +FROM dev/rcamp +MAINTAINER Zebula Sampedro + +ENV RCAMP_DEBUG=True + +# Install dev dependencies +RUN yum -y install nodejs npm && \ + yum -y install openssl pamtester fontconfig freetype freetype-devel fontconfig-devel libstdc++ && \ + npm install -g phantomjs-prebuilt && \ + pip install selenium==3.7.0 + +# Add test users for PAM auth +RUN useradd -M -p $(echo password | openssl passwd -1 -stdin) testuser1 && \ + useradd -M -p $(echo password | openssl passwd -1 -stdin) testuser2 + +WORKDIR /home/uwsgi/rcamp + +CMD ["python","manage.py","runserver","0.0.0.0:9000"] diff --git a/rcamp/docker-entrypoint.sh b/rcamp/docker-entrypoint.sh new file mode 100644 index 0000000..cde22ad --- /dev/null +++ b/rcamp/docker-entrypoint.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +STATIC_DIR=/home/uwsgi/rcamp/static +MEDIA_DIR=/home/uwsgi/rcamp/media +LOG_DIR=/home/uwsgi/rcamp/logs + +# Collect static, and set permissions of shared volumes. +RCAMP_DEBUG=True bash -c 'python manage.py collectstatic --noinput' +chown -R uwsgi:uwsgi $STATIC_DIR +chown -R uwsgi:uwsgi $MEDIA_DIR +chown -R uwsgi:uwsgi $LOG_DIR + +exec gosu uwsgi "$@" diff --git a/rcamp/ldapdb b/rcamp/ldapdb new file mode 160000 index 0000000..e0450e5 --- /dev/null +++ b/rcamp/ldapdb @@ -0,0 +1 @@ +Subproject commit e0450e59475a983e14a5835451a5716623022743 diff --git a/rcamp/accounts/__init__.py b/rcamp/rcamp/accounts/__init__.py similarity index 100% rename from rcamp/accounts/__init__.py rename to rcamp/rcamp/accounts/__init__.py diff --git a/rcamp/accounts/admin.py b/rcamp/rcamp/accounts/admin.py similarity index 100% rename from rcamp/accounts/admin.py rename to rcamp/rcamp/accounts/admin.py diff --git a/rcamp/accounts/forms.py b/rcamp/rcamp/accounts/forms.py similarity index 100% rename from rcamp/accounts/forms.py rename to rcamp/rcamp/accounts/forms.py diff --git a/rcamp/accounts/management/__init__.py b/rcamp/rcamp/accounts/management/__init__.py similarity index 100% rename from rcamp/accounts/management/__init__.py rename to rcamp/rcamp/accounts/management/__init__.py diff --git a/rcamp/accounts/management/commands/__init__.py b/rcamp/rcamp/accounts/management/commands/__init__.py similarity index 100% rename from rcamp/accounts/management/commands/__init__.py rename to rcamp/rcamp/accounts/management/commands/__init__.py diff --git a/rcamp/accounts/management/commands/givesuperuser.py b/rcamp/rcamp/accounts/management/commands/givesuperuser.py similarity index 82% rename from rcamp/accounts/management/commands/givesuperuser.py rename to rcamp/rcamp/accounts/management/commands/givesuperuser.py index 2a01f19..db50cce 100644 --- a/rcamp/accounts/management/commands/givesuperuser.py +++ b/rcamp/rcamp/accounts/management/commands/givesuperuser.py @@ -3,7 +3,6 @@ import datetime import sys -from lib.test.ldap import get_ldap_user_defaults from lib.ldap_utils import get_ldap_username_and_org from accounts.models import ( User, @@ -11,6 +10,23 @@ ) +def get_ldap_user_defaults(): + """Return a dictionary of reasonable defaults for creating RcLdapUser objects via the ORM.""" + ldap_user_defaults = dict( + username = 'testuser', + first_name = 'Test', + last_name = 'User', + full_name = 'User, Test', + email = 'testuser@colorado.edu', + modified_date=datetime.datetime(2015,11,06,03,43,24), + uid = 1010, + gid = 1010, + gecos='Test User,,,', + home_directory='/home/testuser' + ) + return ldap_user_defaults + + class Command(BaseCommand): help = 'Gives superuser status to the specified user.' diff --git a/rcamp/accounts/management/commands/syncldapusers.py b/rcamp/rcamp/accounts/management/commands/syncldapusers.py similarity index 100% rename from rcamp/accounts/management/commands/syncldapusers.py rename to rcamp/rcamp/accounts/management/commands/syncldapusers.py diff --git a/rcamp/accounts/management/commands/transformdatadump.py b/rcamp/rcamp/accounts/management/commands/transformdatadump.py similarity index 100% rename from rcamp/accounts/management/commands/transformdatadump.py rename to rcamp/rcamp/accounts/management/commands/transformdatadump.py diff --git a/rcamp/accounts/migrations/0001_initial.py b/rcamp/rcamp/accounts/migrations/0001_initial.py similarity index 100% rename from rcamp/accounts/migrations/0001_initial.py rename to rcamp/rcamp/accounts/migrations/0001_initial.py diff --git a/rcamp/accounts/migrations/0002_auto_20171213_1604.py b/rcamp/rcamp/accounts/migrations/0002_auto_20171213_1604.py similarity index 100% rename from rcamp/accounts/migrations/0002_auto_20171213_1604.py rename to rcamp/rcamp/accounts/migrations/0002_auto_20171213_1604.py diff --git a/rcamp/accounts/migrations/0003_auto_20180228_1158.py b/rcamp/rcamp/accounts/migrations/0003_auto_20180228_1158.py similarity index 100% rename from rcamp/accounts/migrations/0003_auto_20180228_1158.py rename to rcamp/rcamp/accounts/migrations/0003_auto_20180228_1158.py diff --git a/rcamp/accounts/migrations/__init__.py b/rcamp/rcamp/accounts/migrations/__init__.py similarity index 100% rename from rcamp/accounts/migrations/__init__.py rename to rcamp/rcamp/accounts/migrations/__init__.py diff --git a/rcamp/accounts/models.py b/rcamp/rcamp/accounts/models.py similarity index 100% rename from rcamp/accounts/models.py rename to rcamp/rcamp/accounts/models.py diff --git a/rcamp/accounts/templates/account-request-intent.html b/rcamp/rcamp/accounts/templates/account-request-intent.html similarity index 100% rename from rcamp/accounts/templates/account-request-intent.html rename to rcamp/rcamp/accounts/templates/account-request-intent.html diff --git a/rcamp/accounts/templates/account-request-org-select.html b/rcamp/rcamp/accounts/templates/account-request-org-select.html similarity index 100% rename from rcamp/accounts/templates/account-request-org-select.html rename to rcamp/rcamp/accounts/templates/account-request-org-select.html diff --git a/rcamp/accounts/templates/account-request-review.html b/rcamp/rcamp/accounts/templates/account-request-review.html similarity index 100% rename from rcamp/accounts/templates/account-request-review.html rename to rcamp/rcamp/accounts/templates/account-request-review.html diff --git a/rcamp/accounts/templates/account-request-verify-csu.html b/rcamp/rcamp/accounts/templates/account-request-verify-csu.html similarity index 100% rename from rcamp/accounts/templates/account-request-verify-csu.html rename to rcamp/rcamp/accounts/templates/account-request-verify-csu.html diff --git a/rcamp/accounts/templates/account-request-verify-ucb.html b/rcamp/rcamp/accounts/templates/account-request-verify-ucb.html similarity index 100% rename from rcamp/accounts/templates/account-request-verify-ucb.html rename to rcamp/rcamp/accounts/templates/account-request-verify-ucb.html diff --git a/rcamp/accounts/urls.py b/rcamp/rcamp/accounts/urls.py similarity index 100% rename from rcamp/accounts/urls.py rename to rcamp/rcamp/accounts/urls.py diff --git a/rcamp/accounts/views.py b/rcamp/rcamp/accounts/views.py similarity index 100% rename from rcamp/accounts/views.py rename to rcamp/rcamp/accounts/views.py diff --git a/rcamp/rcamp/dev_settings.py b/rcamp/rcamp/dev_settings.py deleted file mode 100644 index 47fa405..0000000 --- a/rcamp/rcamp/dev_settings.py +++ /dev/null @@ -1,106 +0,0 @@ -import ldap -import os - -BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - -ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) -ldap.set_option(ldap.OPT_X_KEEPALIVE_IDLE,30) -ldap.set_option(ldap.OPT_X_KEEPALIVE_PROBES,2) -ldap.set_option(ldap.OPT_X_KEEPALIVE_INTERVAL,2) - -# MEDIA_URL = 'http://localhost:9000/media/' - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': 'rcamp.sqlite', - }, - 'rcldap': { - 'ENGINE': 'ldapdb.backends.ldap', - 'NAME': 'ldap://localhost:10389', - 'USER': 'cn=Directory Manager', - 'PASSWORD': 'password', - }, - 'culdap': { - 'ENGINE': 'ldapdb.backends.ldap', - 'NAME': 'ldap://localhost:10389', - 'USER': 'cn=Directory Manager', - 'PASSWORD': 'password', - }, - 'csuldap': { - 'ENGINE': 'ldapdb.backends.ldap', - 'NAME': 'ldap://localhost:10389', - 'USER': 'cn=Directory Manager', - 'PASSWORD': 'password', - }, -} - -LDAPCONFS = { - 'rcldap': { - 'server': DATABASES['rcldap']['NAME'], - 'bind_dn': DATABASES['rcldap']['USER'], - 'bind_pw': DATABASES['rcldap']['PASSWORD'], - 'base_dn': 'dc=rc,dc=int,dc=colorado,dc=edu', - 'people_dn': 'ou=people,dc=rc,dc=int,dc=colorado,dc=edu', - 'ucb_dn': 'ou=ucb,ou=people,dc=rc,dc=int,dc=colorado,dc=edu', - 'csu_dn': 'ou=csu,ou=people,dc=rc,dc=int,dc=colorado,dc=edu', - 'xsede_dn': 'ou=xsede,ou=people,dc=rc,dc=int,dc=colorado,dc=edu', - 'internal_dn': 'ou=internal,ou=people,dc=rc,dc=int,dc=colorado,dc=edu', - 'group_dn': 'ou=groups,dc=rc,dc=int,dc=colorado,dc=edu', - }, - 'culdap': { - 'server': DATABASES['culdap']['NAME'], - 'bind_dn': DATABASES['culdap']['USER'], - 'bind_pw': DATABASES['culdap']['PASSWORD'], - 'base_dn': 'dc=colorado,dc=edu', - 'group_dn': 'ou=groups,dc=colorado,dc=edu', - 'people_dn': 'ou=users,dc=colorado,dc=edu', - }, - 'csuldap': { - 'server': DATABASES['csuldap']['NAME'], - 'bind_dn': DATABASES['csuldap']['USER'], - 'bind_pw': DATABASES['csuldap']['PASSWORD'], - 'base_dn': 'ou=eIdentityUsers,dc=ColoState,dc=edu', - 'group_dn': 'ou=eIdentityUsers,dc=ColoState,dc=edu', - 'people_dn': 'ou=eIdentityUsers,dc=ColoState,dc=edu', - }, -} - -TIME_ZONE = 'America/Denver' - -# DEBUG = False -EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' - -LOGGING = { - 'version': 1, - 'disable_existing_loggers': False, - 'handlers': { - 'file': { - 'level': 'WARN', - 'class': 'logging.FileHandler', - 'filename': 'rcamp.log', - }, - }, - 'loggers': { - 'django': { - 'handlers': ['file'], - 'level': 'DEBUG', - 'propagate': True, - }, - 'rcamp': { - 'handlers': ['file'], - 'level': 'DEBUG', - 'propagate': True, - }, - 'projects': { - 'handlers': ['file'], - 'level': 'DEBUG', - 'propagate': True, - }, - 'accounts': { - 'handlers': ['file'], - 'level': 'DEBUG', - 'propagate': True, - }, - }, -} diff --git a/rcamp/endpoints/__init__.py b/rcamp/rcamp/endpoints/__init__.py similarity index 100% rename from rcamp/endpoints/__init__.py rename to rcamp/rcamp/endpoints/__init__.py diff --git a/rcamp/endpoints/filters.py b/rcamp/rcamp/endpoints/filters.py similarity index 100% rename from rcamp/endpoints/filters.py rename to rcamp/rcamp/endpoints/filters.py diff --git a/rcamp/endpoints/serializers.py b/rcamp/rcamp/endpoints/serializers.py similarity index 100% rename from rcamp/endpoints/serializers.py rename to rcamp/rcamp/endpoints/serializers.py diff --git a/rcamp/endpoints/urls.py b/rcamp/rcamp/endpoints/urls.py similarity index 100% rename from rcamp/endpoints/urls.py rename to rcamp/rcamp/endpoints/urls.py diff --git a/rcamp/endpoints/viewsets.py b/rcamp/rcamp/endpoints/viewsets.py similarity index 100% rename from rcamp/endpoints/viewsets.py rename to rcamp/rcamp/endpoints/viewsets.py diff --git a/rcamp/lib/__init__.py b/rcamp/rcamp/lib/__init__.py similarity index 100% rename from rcamp/lib/__init__.py rename to rcamp/rcamp/lib/__init__.py diff --git a/rcamp/lib/fields.py b/rcamp/rcamp/lib/fields.py similarity index 100% rename from rcamp/lib/fields.py rename to rcamp/rcamp/lib/fields.py diff --git a/rcamp/lib/ldap_utils.py b/rcamp/rcamp/lib/ldap_utils.py similarity index 100% rename from rcamp/lib/ldap_utils.py rename to rcamp/rcamp/lib/ldap_utils.py diff --git a/rcamp/lib/pam_backend.py b/rcamp/rcamp/lib/pam_backend.py similarity index 100% rename from rcamp/lib/pam_backend.py rename to rcamp/rcamp/lib/pam_backend.py diff --git a/rcamp/lib/router.py b/rcamp/rcamp/lib/router.py similarity index 100% rename from rcamp/lib/router.py rename to rcamp/rcamp/lib/router.py diff --git a/rcamp/lib/views.py b/rcamp/rcamp/lib/views.py similarity index 100% rename from rcamp/lib/views.py rename to rcamp/rcamp/lib/views.py diff --git a/rcamp/lib/test/__init__.py b/rcamp/rcamp/mailer/__init__.py similarity index 100% rename from rcamp/lib/test/__init__.py rename to rcamp/rcamp/mailer/__init__.py diff --git a/rcamp/mailer/admin.py b/rcamp/rcamp/mailer/admin.py similarity index 100% rename from rcamp/mailer/admin.py rename to rcamp/rcamp/mailer/admin.py diff --git a/rcamp/mailer/migrations/0001_initial.py b/rcamp/rcamp/mailer/migrations/0001_initial.py similarity index 100% rename from rcamp/mailer/migrations/0001_initial.py rename to rcamp/rcamp/mailer/migrations/0001_initial.py diff --git a/rcamp/mailer/__init__.py b/rcamp/rcamp/mailer/migrations/__init__.py similarity index 100% rename from rcamp/mailer/__init__.py rename to rcamp/rcamp/mailer/migrations/__init__.py diff --git a/rcamp/mailer/models.py b/rcamp/rcamp/mailer/models.py similarity index 100% rename from rcamp/mailer/models.py rename to rcamp/rcamp/mailer/models.py diff --git a/rcamp/mailer/receivers.py b/rcamp/rcamp/mailer/receivers.py similarity index 100% rename from rcamp/mailer/receivers.py rename to rcamp/rcamp/mailer/receivers.py diff --git a/rcamp/mailer/signals.py b/rcamp/rcamp/mailer/signals.py similarity index 100% rename from rcamp/mailer/signals.py rename to rcamp/rcamp/mailer/signals.py diff --git a/rcamp/manage.py b/rcamp/rcamp/manage.py similarity index 100% rename from rcamp/manage.py rename to rcamp/rcamp/manage.py diff --git a/rcamp/mailer/migrations/__init__.py b/rcamp/rcamp/projects/__init__.py similarity index 100% rename from rcamp/mailer/migrations/__init__.py rename to rcamp/rcamp/projects/__init__.py diff --git a/rcamp/projects/admin.py b/rcamp/rcamp/projects/admin.py similarity index 100% rename from rcamp/projects/admin.py rename to rcamp/rcamp/projects/admin.py diff --git a/rcamp/projects/forms.py b/rcamp/rcamp/projects/forms.py similarity index 100% rename from rcamp/projects/forms.py rename to rcamp/rcamp/projects/forms.py diff --git a/rcamp/projects/__init__.py b/rcamp/rcamp/projects/management/__init__.py similarity index 100% rename from rcamp/projects/__init__.py rename to rcamp/rcamp/projects/management/__init__.py diff --git a/rcamp/projects/management/__init__.py b/rcamp/rcamp/projects/management/commands/__init__.py similarity index 100% rename from rcamp/projects/management/__init__.py rename to rcamp/rcamp/projects/management/commands/__init__.py diff --git a/rcamp/projects/migrations/0001_initial.py b/rcamp/rcamp/projects/migrations/0001_initial.py similarity index 100% rename from rcamp/projects/migrations/0001_initial.py rename to rcamp/rcamp/projects/migrations/0001_initial.py diff --git a/rcamp/projects/migrations/0002_auto_20180326_1507.py b/rcamp/rcamp/projects/migrations/0002_auto_20180326_1507.py similarity index 100% rename from rcamp/projects/migrations/0002_auto_20180326_1507.py rename to rcamp/rcamp/projects/migrations/0002_auto_20180326_1507.py diff --git a/rcamp/projects/migrations/0003_auto_20180326_1508.py b/rcamp/rcamp/projects/migrations/0003_auto_20180326_1508.py similarity index 100% rename from rcamp/projects/migrations/0003_auto_20180326_1508.py rename to rcamp/rcamp/projects/migrations/0003_auto_20180326_1508.py diff --git a/rcamp/projects/migrations/0004_auto_20180326_1529.py b/rcamp/rcamp/projects/migrations/0004_auto_20180326_1529.py similarity index 100% rename from rcamp/projects/migrations/0004_auto_20180326_1529.py rename to rcamp/rcamp/projects/migrations/0004_auto_20180326_1529.py diff --git a/rcamp/projects/management/commands/__init__.py b/rcamp/rcamp/projects/migrations/__init__.py similarity index 100% rename from rcamp/projects/management/commands/__init__.py rename to rcamp/rcamp/projects/migrations/__init__.py diff --git a/rcamp/projects/models.py b/rcamp/rcamp/projects/models.py similarity index 100% rename from rcamp/projects/models.py rename to rcamp/rcamp/projects/models.py diff --git a/rcamp/projects/receivers.py b/rcamp/rcamp/projects/receivers.py similarity index 100% rename from rcamp/projects/receivers.py rename to rcamp/rcamp/projects/receivers.py diff --git a/rcamp/projects/templates/allocation-request-create.html b/rcamp/rcamp/projects/templates/allocation-request-create.html similarity index 100% rename from rcamp/projects/templates/allocation-request-create.html rename to rcamp/rcamp/projects/templates/allocation-request-create.html diff --git a/rcamp/projects/templates/allocation-request-detail.html b/rcamp/rcamp/projects/templates/allocation-request-detail.html similarity index 100% rename from rcamp/projects/templates/allocation-request-detail.html rename to rcamp/rcamp/projects/templates/allocation-request-detail.html diff --git a/rcamp/projects/templates/project-create.html b/rcamp/rcamp/projects/templates/project-create.html similarity index 100% rename from rcamp/projects/templates/project-create.html rename to rcamp/rcamp/projects/templates/project-create.html diff --git a/rcamp/projects/templates/project-detail.html b/rcamp/rcamp/projects/templates/project-detail.html similarity index 100% rename from rcamp/projects/templates/project-detail.html rename to rcamp/rcamp/projects/templates/project-detail.html diff --git a/rcamp/projects/templates/project-edit.html b/rcamp/rcamp/projects/templates/project-edit.html similarity index 100% rename from rcamp/projects/templates/project-edit.html rename to rcamp/rcamp/projects/templates/project-edit.html diff --git a/rcamp/projects/templates/project-list.html b/rcamp/rcamp/projects/templates/project-list.html similarity index 100% rename from rcamp/projects/templates/project-list.html rename to rcamp/rcamp/projects/templates/project-list.html diff --git a/rcamp/projects/templates/reference-create.html b/rcamp/rcamp/projects/templates/reference-create.html similarity index 100% rename from rcamp/projects/templates/reference-create.html rename to rcamp/rcamp/projects/templates/reference-create.html diff --git a/rcamp/projects/templates/reference-detail.html b/rcamp/rcamp/projects/templates/reference-detail.html similarity index 100% rename from rcamp/projects/templates/reference-detail.html rename to rcamp/rcamp/projects/templates/reference-detail.html diff --git a/rcamp/projects/templates/reference-edit.html b/rcamp/rcamp/projects/templates/reference-edit.html similarity index 100% rename from rcamp/projects/templates/reference-edit.html rename to rcamp/rcamp/projects/templates/reference-edit.html diff --git a/rcamp/projects/urls.py b/rcamp/rcamp/projects/urls.py similarity index 100% rename from rcamp/projects/urls.py rename to rcamp/rcamp/projects/urls.py diff --git a/rcamp/projects/views.py b/rcamp/rcamp/projects/views.py similarity index 100% rename from rcamp/projects/views.py rename to rcamp/rcamp/projects/views.py diff --git a/rcamp/rcamp/.bowerrc b/rcamp/rcamp/rcamp/.bowerrc similarity index 100% rename from rcamp/rcamp/.bowerrc rename to rcamp/rcamp/rcamp/.bowerrc diff --git a/rcamp/projects/migrations/__init__.py b/rcamp/rcamp/rcamp/__init__.py similarity index 100% rename from rcamp/projects/migrations/__init__.py rename to rcamp/rcamp/rcamp/__init__.py diff --git a/rcamp/rcamp/bower.json b/rcamp/rcamp/rcamp/bower.json similarity index 100% rename from rcamp/rcamp/bower.json rename to rcamp/rcamp/rcamp/bower.json diff --git a/rcamp/rcamp/rcamp/settings/__init__.py b/rcamp/rcamp/rcamp/settings/__init__.py new file mode 100644 index 0000000..bfb6240 --- /dev/null +++ b/rcamp/rcamp/rcamp/settings/__init__.py @@ -0,0 +1,5 @@ +from .main import * +from .databases import * +from .organizations import * +from .auth import * +from .logging import * diff --git a/rcamp/rcamp/rcamp/settings/auth.py b/rcamp/rcamp/rcamp/settings/auth.py new file mode 100644 index 0000000..ee04f5a --- /dev/null +++ b/rcamp/rcamp/rcamp/settings/auth.py @@ -0,0 +1,13 @@ +AUTHENTICATION_BACKENDS = ( + 'django.contrib.auth.backends.ModelBackend', + 'lib.pam_backend.PamBackend', +) + +AUTH_USER_MODEL = 'accounts.User' + +LOGIN_URL = '/login' + +PAM_SERVICES = { + 'default': 'login', + 'csu': 'csu' +} diff --git a/rcamp/rcamp/rcamp/settings/databases.py b/rcamp/rcamp/rcamp/settings/databases.py new file mode 100644 index 0000000..8c7f11f --- /dev/null +++ b/rcamp/rcamp/rcamp/settings/databases.py @@ -0,0 +1,96 @@ +import os +from .toggles import * + +BASE_DIR = '/home/uwsgi/rcamp' + +if not DEBUG: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': 'rcamp1712', + 'USER': os.environ.get('RCAMP_DB_USER'), + 'PASSWORD': os.environ.get('RCAMP_DB_PASSWORD'), + 'HOST': os.environ.get('RCAMP_DB_HOST'), + }, + 'rcldap': { + 'ENGINE': 'ldapdb.backends.ldap', + 'NAME': os.environ.get('RCAMP_RC_LDAP_URI'), + 'USER': os.environ.get('RCAMP_RC_LDAP_USER'), + 'PASSWORD': os.environ.get('RCAMP_RC_LDAP_PASSWORD'), + }, + 'culdap': { + 'ENGINE': 'ldapdb.backends.ldap', + 'NAME': os.environ.get('RCAMP_UCB_LDAP_URI'), + 'USER': os.environ.get('RCAMP_UCB_LDAP_USER'), + 'PASSWORD': os.environ.get('RCAMP_UCB_LDAP_PASSWORD'), + }, + 'csuldap': { + 'ENGINE': 'ldapdb.backends.ldap', + 'NAME': os.environ.get('RCAMP_CSU_LDAP_URI'), + 'USER': os.environ.get('RCAMP_CSU_LDAP_USER'), + 'PASSWORD': os.environ.get('RCAMP_CSU_LDAP_PASSWORD'), + }, + } +else: + DATABASES = { + # `test-mysql` is the name of the rc-test-mysql service + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': 'rcamp1712', + 'USER': 'root', + 'PASSWORD': 'password', + 'HOST': 'test-mysql', + }, + # `test-ldap` is the name of the rc-test-ldap service + 'rcldap': { + 'ENGINE': 'ldapdb.backends.ldap', + 'NAME': 'ldap://test-ldap', + 'USER': 'cn=Directory Manager', + 'PASSWORD': 'password', + }, + 'culdap': { + 'ENGINE': 'ldapdb.backends.ldap', + 'NAME': os.environ.get('RCAMP_UCB_LDAP_URI','ldap://test-ldap'), + 'USER': os.environ.get('RCAMP_UCB_LDAP_USER','cn=Directory Manager'), + 'PASSWORD': os.environ.get('RCAMP_UCB_LDAP_PASSWORD','password'), + }, + 'csuldap': { + 'ENGINE': 'ldapdb.backends.ldap', + 'NAME': os.environ.get('RCAMP_CSU_LDAP_URI','ldap://test-ldap'), + 'USER': os.environ.get('RCAMP_CSU_LDAP_USER','cn=Directory Manager'), + 'PASSWORD': os.environ.get('RCAMP_CSU_LDAP_PASSWORD','password'), + }, + } + +LDAPCONFS = { + 'rcldap': { + 'server': DATABASES['rcldap']['NAME'], + 'bind_dn': DATABASES['rcldap']['USER'], + 'bind_pw': DATABASES['rcldap']['PASSWORD'], + 'base_dn': 'dc=rc,dc=int,dc=colorado,dc=edu', + 'people_dn': 'ou=people,dc=rc,dc=int,dc=colorado,dc=edu', + 'ucb_dn': 'ou=ucb,ou=people,dc=rc,dc=int,dc=colorado,dc=edu', + 'csu_dn': 'ou=csu,ou=people,dc=rc,dc=int,dc=colorado,dc=edu', + 'xsede_dn': 'ou=xsede,ou=people,dc=rc,dc=int,dc=colorado,dc=edu', + 'internal_dn': 'ou=internal,ou=people,dc=rc,dc=int,dc=colorado,dc=edu', + 'group_dn': 'ou=groups,dc=rc,dc=int,dc=colorado,dc=edu', + }, + 'culdap': { + 'server': DATABASES['culdap']['NAME'], + 'bind_dn': DATABASES['culdap']['USER'], + 'bind_pw': DATABASES['culdap']['PASSWORD'], + 'base_dn': 'dc=colorado,dc=edu', + 'group_dn': 'ou=groups,dc=colorado,dc=edu', + 'people_dn': 'ou=users,dc=colorado,dc=edu', + }, + 'csuldap': { + 'server': DATABASES['csuldap']['NAME'], + 'bind_dn': DATABASES['csuldap']['USER'], + 'bind_pw': DATABASES['csuldap']['PASSWORD'], + 'base_dn': 'ou=eIdentityUsers,dc=ColoState,dc=edu', + 'group_dn': 'ou=eIdentityUsers,dc=ColoState,dc=edu', + 'people_dn': 'ou=eIdentityUsers,dc=ColoState,dc=edu', + }, +} + +DATABASE_ROUTERS = ['lib.router.LdapRouter',] diff --git a/rcamp/rcamp/rcamp/settings/logging.py b/rcamp/rcamp/rcamp/settings/logging.py new file mode 100644 index 0000000..167486d --- /dev/null +++ b/rcamp/rcamp/rcamp/settings/logging.py @@ -0,0 +1,42 @@ +from .toggles import * + +if not DEBUG: + EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' + EMAIL_HOST = 'mail.rc.int.colorado.edu' + EMAIL_PORT = 25 +else: + EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' + +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'handlers': { + 'file': { + 'level': 'WARN', + 'class': 'logging.FileHandler', + 'filename': '/home/uwsgi/rcamp/logs/rcamp.log', + }, + }, + 'loggers': { + 'django': { + 'handlers': ['file'], + 'level': 'DEBUG', + 'propagate': True, + }, + 'rcamp': { + 'handlers': ['file'], + 'level': 'DEBUG', + 'propagate': True, + }, + 'projects': { + 'handlers': ['file'], + 'level': 'DEBUG', + 'propagate': True, + }, + 'accounts': { + 'handlers': ['file'], + 'level': 'DEBUG', + 'propagate': True, + }, + }, +} diff --git a/rcamp/rcamp/rcamp/settings/main.py b/rcamp/rcamp/rcamp/settings/main.py new file mode 100644 index 0000000..3537828 --- /dev/null +++ b/rcamp/rcamp/rcamp/settings/main.py @@ -0,0 +1,110 @@ +import os +from .toggles import * + +BASE_DIR = '/home/uwsgi/rcamp' + + +if not DEBUG: + SECRET_KEY = os.environ.get('RCAMP_SECRET_KEY') +else: + SECRET_KEY = 'A terribly insecure key not suitable for production' + +if not DEBUG: + default_hosts = 'rcamp.rc.colorado.edu,portals.rc.colorado.edu,rcamp1.rc.int.colorado.edu' + hosts = os.environ.get('RCAMP_ALLOWEDHOSTS',default_hosts) + ALLOWED_HOSTS = hosts.split(',') +else: + ALLOWED_HOSTS = [] + + +INSTALLED_APPS = [ + 'grappelli', + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + + 'crispy_forms', + 'rest_framework', + + 'ldapdb', + 'lib', + 'mailer', + 'accounts', + 'projects', +] + +if DEBUG: + INSTALLED_APPS.append('tests') + +MIDDLEWARE_CLASSES = ( + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'django.middleware.security.SecurityMiddleware', +) + +ROOT_URLCONF = 'rcamp.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [ + os.path.join(BASE_DIR,'rcamp','templates'), + ], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.template.context_processors.media', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'rcamp.wsgi.application' + + + +LOGIN_REDIRECT_URL = '/' + +# Internationalization +# https://docs.djangoproject.com/en/1.8/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'America/Denver' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.8/howto/static-files/ + +STATIC_URL = '/static/' +STATIC_ROOT = os.path.join(BASE_DIR,'static') +STATICFILES_DIRS = ( + os.path.join(BASE_DIR,'rcamp','static'), +) + +# Media files (User-uploaded files) +# https://docs.djangoproject.com/en/1.8/ref/settings/#media-root +MEDIA_URL = '/media/' +MEDIA_ROOT = os.path.join(BASE_DIR,'media','') + +# GRAPPELLI ADMIN SETTINGS +GRAPPELLI_ADMIN_TITLE = 'RCAMP' + +REST_FRAMEWORK = {} diff --git a/rcamp/rcamp/rcamp/settings/organizations.py b/rcamp/rcamp/rcamp/settings/organizations.py new file mode 100644 index 0000000..ee97250 --- /dev/null +++ b/rcamp/rcamp/rcamp/settings/organizations.py @@ -0,0 +1,31 @@ +LICENSE_GROUPS = { + 'ucb': 'ucb' +} + +ORGANIZATION_INFO = { + 'ucb': { + 'long_name': 'University of Colorado Boulder', + 'suffix': None, + 'general_project_id': 'ucb-general' + }, + 'csu': { + 'long_name': 'Colorado State University', + 'suffix': 'colostate.edu', + 'general_project_id': 'csu-general' + }, + 'xsede': { + 'long_name': 'XSEDE', + 'suffix': 'xsede.org', + 'general_project_id': 'rmacc-general' + }, + 'ncar': { + 'long_name': 'NCAR', + 'suffix': 'ncar.ucar.edu', + 'general_project_id': None + }, + 'internal': { + 'long_name': 'Research Computing - Administrative', + 'suffix': None, + 'general_project_id': None + } +} diff --git a/rcamp/rcamp/rcamp/settings/toggles.py b/rcamp/rcamp/rcamp/settings/toggles.py new file mode 100644 index 0000000..60831cd --- /dev/null +++ b/rcamp/rcamp/rcamp/settings/toggles.py @@ -0,0 +1,3 @@ +import os +_debug = os.environ.get('RCAMP_DEBUG', 'False') +DEBUG = _debug == 'True' diff --git a/rcamp/rcamp/static/css/account-request.css b/rcamp/rcamp/rcamp/static/css/account-request.css similarity index 100% rename from rcamp/rcamp/static/css/account-request.css rename to rcamp/rcamp/rcamp/static/css/account-request.css diff --git a/rcamp/rcamp/static/css/jumbotron.css b/rcamp/rcamp/rcamp/static/css/jumbotron.css similarity index 100% rename from rcamp/rcamp/static/css/jumbotron.css rename to rcamp/rcamp/rcamp/static/css/jumbotron.css diff --git a/rcamp/rcamp/static/css/login.css b/rcamp/rcamp/rcamp/static/css/login.css similarity index 100% rename from rcamp/rcamp/static/css/login.css rename to rcamp/rcamp/rcamp/static/css/login.css diff --git a/rcamp/rcamp/static/css/project-create.css b/rcamp/rcamp/rcamp/static/css/project-create.css similarity index 100% rename from rcamp/rcamp/static/css/project-create.css rename to rcamp/rcamp/rcamp/static/css/project-create.css diff --git a/rcamp/rcamp/static/css/projects.css b/rcamp/rcamp/rcamp/static/css/projects.css similarity index 100% rename from rcamp/rcamp/static/css/projects.css rename to rcamp/rcamp/rcamp/static/css/projects.css diff --git a/rcamp/rcamp/static/css/rcamp.css b/rcamp/rcamp/rcamp/static/css/rcamp.css similarity index 100% rename from rcamp/rcamp/static/css/rcamp.css rename to rcamp/rcamp/rcamp/static/css/rcamp.css diff --git a/rcamp/rcamp/static/css/selector.css b/rcamp/rcamp/rcamp/static/css/selector.css similarity index 100% rename from rcamp/rcamp/static/css/selector.css rename to rcamp/rcamp/rcamp/static/css/selector.css diff --git a/rcamp/rcamp/static/img/._logo.png b/rcamp/rcamp/rcamp/static/img/._logo.png similarity index 100% rename from rcamp/rcamp/static/img/._logo.png rename to rcamp/rcamp/rcamp/static/img/._logo.png diff --git a/rcamp/rcamp/static/img/coolaisle-blue-cmp.jpg b/rcamp/rcamp/rcamp/static/img/coolaisle-blue-cmp.jpg similarity index 100% rename from rcamp/rcamp/static/img/coolaisle-blue-cmp.jpg rename to rcamp/rcamp/rcamp/static/img/coolaisle-blue-cmp.jpg diff --git a/rcamp/rcamp/static/img/logo.png b/rcamp/rcamp/rcamp/static/img/logo.png similarity index 100% rename from rcamp/rcamp/static/img/logo.png rename to rcamp/rcamp/rcamp/static/img/logo.png diff --git a/rcamp/rcamp/static/img/memory-heatmap-cmp.jpg b/rcamp/rcamp/rcamp/static/img/memory-heatmap-cmp.jpg similarity index 100% rename from rcamp/rcamp/static/img/memory-heatmap-cmp.jpg rename to rcamp/rcamp/rcamp/static/img/memory-heatmap-cmp.jpg diff --git a/rcamp/rcamp/static/img/molecule-cmp.jpg b/rcamp/rcamp/rcamp/static/img/molecule-cmp.jpg similarity index 100% rename from rcamp/rcamp/static/img/molecule-cmp.jpg rename to rcamp/rcamp/rcamp/static/img/molecule-cmp.jpg diff --git a/rcamp/rcamp/static/js/SelectFilter2.js b/rcamp/rcamp/rcamp/static/js/SelectFilter2.js similarity index 100% rename from rcamp/rcamp/static/js/SelectFilter2.js rename to rcamp/rcamp/rcamp/static/js/SelectFilter2.js diff --git a/rcamp/rcamp/static/js/jsi18n.js b/rcamp/rcamp/rcamp/static/js/jsi18n.js similarity index 100% rename from rcamp/rcamp/static/js/jsi18n.js rename to rcamp/rcamp/rcamp/static/js/jsi18n.js diff --git a/rcamp/rcamp/templates/404.html b/rcamp/rcamp/rcamp/templates/404.html similarity index 100% rename from rcamp/rcamp/templates/404.html rename to rcamp/rcamp/rcamp/templates/404.html diff --git a/rcamp/rcamp/templates/500.html b/rcamp/rcamp/rcamp/templates/500.html similarity index 100% rename from rcamp/rcamp/templates/500.html rename to rcamp/rcamp/rcamp/templates/500.html diff --git a/rcamp/rcamp/templates/base.html b/rcamp/rcamp/rcamp/templates/base.html similarity index 100% rename from rcamp/rcamp/templates/base.html rename to rcamp/rcamp/rcamp/templates/base.html diff --git a/rcamp/rcamp/templates/index.html b/rcamp/rcamp/rcamp/templates/index.html similarity index 100% rename from rcamp/rcamp/templates/index.html rename to rcamp/rcamp/rcamp/templates/index.html diff --git a/rcamp/rcamp/templates/login.html b/rcamp/rcamp/rcamp/templates/login.html similarity index 100% rename from rcamp/rcamp/templates/login.html rename to rcamp/rcamp/rcamp/templates/login.html diff --git a/rcamp/rcamp/templates/logout.html b/rcamp/rcamp/rcamp/templates/logout.html similarity index 100% rename from rcamp/rcamp/templates/logout.html rename to rcamp/rcamp/rcamp/templates/logout.html diff --git a/rcamp/rcamp/templates/terms-and-conditions.html b/rcamp/rcamp/rcamp/templates/terms-and-conditions.html similarity index 100% rename from rcamp/rcamp/templates/terms-and-conditions.html rename to rcamp/rcamp/rcamp/templates/terms-and-conditions.html diff --git a/rcamp/rcamp/urls.py b/rcamp/rcamp/rcamp/urls.py similarity index 89% rename from rcamp/rcamp/urls.py rename to rcamp/rcamp/rcamp/urls.py index e11e1ce..807b878 100644 --- a/rcamp/rcamp/urls.py +++ b/rcamp/rcamp/rcamp/urls.py @@ -19,6 +19,7 @@ from django.views.generic import TemplateView from django.conf.urls import handler404 from django.conf.urls import handler500 +from django.conf import settings # Make sure signals/receivers get loaded. from mailer import receivers from projects import receivers @@ -38,3 +39,7 @@ url(r'^accounts/', include('accounts.urls', namespace='accounts')), url(r'^projects/', include('projects.urls', namespace='projects')), ] + +if settings.DEBUG: + from django.conf.urls.static import static + urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/rcamp/rcamp/wsgi.py b/rcamp/rcamp/rcamp/wsgi.py similarity index 100% rename from rcamp/rcamp/wsgi.py rename to rcamp/rcamp/rcamp/wsgi.py diff --git a/requirements.txt b/rcamp/rcamp/requirements.txt similarity index 84% rename from requirements.txt rename to rcamp/rcamp/requirements.txt index 673f450..b32b3c1 100644 --- a/requirements.txt +++ b/rcamp/rcamp/requirements.txt @@ -16,4 +16,4 @@ python-ldap==2.4.22 python-pam==1.8.2 pytz==2016.4 six==1.10.0 -git+git://github.com/ResearchComputing/django-ldapdb.git@master +uWSGI==2.0.17 diff --git a/rcamp/rcamp/settings.py b/rcamp/rcamp/settings.py deleted file mode 100644 index 4745367..0000000 --- a/rcamp/rcamp/settings.py +++ /dev/null @@ -1,183 +0,0 @@ -""" -Django settings for rcamp project. - -Generated by 'django-admin startproject' using Django 1.8.5. - -For more information on this file, see -https://docs.djangoproject.com/en/1.8/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/1.8/ref/settings/ -""" - -# Build paths inside the project like this: os.path.join(BASE_DIR, ...) -import os - -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.8/howto/deployment/checklist/ - -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'j38e9!%8z#b=$=g87wzlb*+gqm0kc-6x7lb^_b6_zg1#(b*75s' - -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True - -ALLOWED_HOSTS = [] - - -# Application definition - -INSTALLED_APPS = ( - 'grappelli', - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - - 'crispy_forms', - 'rest_framework', - - 'ldapdb', - 'lib', - 'mailer', - 'accounts', - 'projects', -) - -MIDDLEWARE_CLASSES = ( - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'django.middleware.security.SecurityMiddleware', -) - -ROOT_URLCONF = 'rcamp.urls' - -TEMPLATES = [ - { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [ - os.path.join(os.path.dirname(os.path.abspath(__file__)),'templates'), - ], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.template.context_processors.media', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', - ], - }, - }, -] - -WSGI_APPLICATION = 'rcamp.wsgi.application' - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), - }, -} - -DATABASE_ROUTERS = ['lib.router.LdapRouter',] - -EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend' - -AUTHENTICATION_BACKENDS = ( - 'django.contrib.auth.backends.ModelBackend', - 'lib.pam_backend.PamBackend', -) - -AUTH_USER_MODEL = 'accounts.User' - -LOGIN_URL = '/login' - -LOGIN_REDIRECT_URL = '/' - -# Internationalization -# https://docs.djangoproject.com/en/1.8/topics/i18n/ - -LANGUAGE_CODE = 'en-us' - -TIME_ZONE = 'UTC' - -USE_I18N = True - -USE_L10N = True - -USE_TZ = True - -MEDIA_URL = '/media/' -MEDIA_ROOT = os.path.join(BASE_DIR,'rcamp','media','') - -# Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/1.8/howto/static-files/ - -STATIC_URL = '/static/' -STATIC_ROOT = os.path.join(BASE_DIR,'static') -STATICFILES_DIRS = ( - os.path.join(os.path.dirname(os.path.abspath(__file__)),'static'), -) - -# Media files (User-uploaded files) -# https://docs.djangoproject.com/en/1.8/ref/settings/#media-root -MEDIA_URL = '/media/' -MEDIA_ROOT = os.path.join(BASE_DIR,'media','') - -# GRAPPELLI ADMIN SETTINGS -GRAPPELLI_ADMIN_TITLE = 'RCAMP' - -REST_FRAMEWORK = {} - -PAM_SERVICES = { - 'default': 'login', - 'csu': 'csu' -} - -LICENSE_GROUPS = { - 'ucb': 'ucb' -} - -ORGANIZATION_INFO = { - 'ucb': { - 'long_name': 'University of Colorado Boulder', - 'suffix': None, - 'general_project_id': 'ucb-general' - }, - 'csu': { - 'long_name': 'Colorado State University', - 'suffix': 'colostate.edu', - 'general_project_id': 'csu-general' - }, - 'xsede': { - 'long_name': 'XSEDE', - 'suffix': 'xsede.org', - 'general_project_id': 'rmacc-general' - }, - 'ncar': { - 'long_name': 'NCAR', - 'suffix': 'ncar.ucar.edu', - 'general_project_id': None - }, - 'internal': { - 'long_name': 'Research Computing - Administrative', - 'suffix': None, - 'general_project_id': None - } -} - -try: - from local_settings import * -except: - pass diff --git a/rcamp/rcamp/__init__.py b/rcamp/rcamp/tests/__init__.py similarity index 100% rename from rcamp/rcamp/__init__.py rename to rcamp/rcamp/tests/__init__.py diff --git a/rcamp/accounts/test_commands.py b/rcamp/rcamp/tests/test_accounts_commands.py similarity index 86% rename from rcamp/accounts/test_commands.py rename to rcamp/rcamp/tests/test_accounts_commands.py index b86fb8e..7749d86 100644 --- a/rcamp/accounts/test_commands.py +++ b/rcamp/rcamp/tests/test_accounts_commands.py @@ -7,8 +7,8 @@ from django.conf import settings from django.core.management import call_command -from lib.test.utils import SafeTestCase -from lib.test.ldap import ( +from tests.utilities.utils import SafeTestCase +from tests.utilities.ldap import ( get_ldap_user_defaults, get_ldap_group_defaults, build_mock_rcldap_user, diff --git a/rcamp/accounts/test_forms.py b/rcamp/rcamp/tests/test_accounts_forms.py similarity index 99% rename from rcamp/accounts/test_forms.py rename to rcamp/rcamp/tests/test_accounts_forms.py index 7263ec4..e98808e 100644 --- a/rcamp/accounts/test_forms.py +++ b/rcamp/rcamp/tests/test_accounts_forms.py @@ -7,7 +7,7 @@ import copy from django.conf import settings -from lib.test.ldap import ( +from tests.utilities.ldap import ( LdapTestCase, build_mock_rcldap_user ) diff --git a/rcamp/accounts/test_functional.py b/rcamp/rcamp/tests/test_accounts_functional.py similarity index 99% rename from rcamp/accounts/test_functional.py rename to rcamp/rcamp/tests/test_accounts_functional.py index fedbde5..0455f1e 100644 --- a/rcamp/accounts/test_functional.py +++ b/rcamp/rcamp/tests/test_accounts_functional.py @@ -1,10 +1,10 @@ import mock from unittest import skip -from lib.test.ldap import ( +from tests.utilities.ldap import ( get_ldap_user_defaults, get_ldap_group_defaults ) -from lib.test.functional import ( +from tests.utilities.functional import ( SafeStaticLiveServerTestCase, UserAuthenticatedLiveServerTestCase ) diff --git a/rcamp/accounts/test_models.py b/rcamp/rcamp/tests/test_accounts_models.py similarity index 99% rename from rcamp/accounts/test_models.py rename to rcamp/rcamp/tests/test_accounts_models.py index c5c6926..2be97a1 100644 --- a/rcamp/accounts/test_models.py +++ b/rcamp/rcamp/tests/test_accounts_models.py @@ -6,8 +6,8 @@ from django.conf import settings -from lib.test.utils import SafeTestCase -from lib.test.ldap import ( +from tests.utilities.utils import SafeTestCase +from tests.utilities.ldap import ( get_ldap_user_defaults, get_ldap_group_defaults, build_mock_rcldap_user, diff --git a/rcamp/accounts/test_views.py b/rcamp/rcamp/tests/test_accounts_views.py similarity index 99% rename from rcamp/accounts/test_views.py rename to rcamp/rcamp/tests/test_accounts_views.py index 32aa318..2a02c40 100644 --- a/rcamp/accounts/test_views.py +++ b/rcamp/rcamp/tests/test_accounts_views.py @@ -11,8 +11,8 @@ from django.conf import settings from django.contrib.sessions.middleware import SessionMiddleware -from lib.test.ldap import LdapTestCase -from lib.test.utils import ( +from tests.utilities.ldap import LdapTestCase +from tests.utilities.utils import ( SessionEnabledTestMixin, SafeTestCase ) diff --git a/rcamp/endpoints/tests.py b/rcamp/rcamp/tests/test_endpoints.py similarity index 99% rename from rcamp/endpoints/tests.py rename to rcamp/rcamp/tests/test_endpoints.py index ea60b98..e1cc7c7 100644 --- a/rcamp/endpoints/tests.py +++ b/rcamp/rcamp/tests/test_endpoints.py @@ -4,7 +4,7 @@ import json import datetime -from lib.test.utils import ( +from tests.utilities.utils import ( get_auth_user_defaults, SafeTestCase ) diff --git a/rcamp/lib/test_auth.py b/rcamp/rcamp/tests/test_lib_auth.py similarity index 98% rename from rcamp/lib/test_auth.py rename to rcamp/rcamp/tests/test_lib_auth.py index 0028b80..f33e32d 100644 --- a/rcamp/lib/test_auth.py +++ b/rcamp/rcamp/tests/test_lib_auth.py @@ -2,7 +2,7 @@ import mock import pam from lib.pam_backend import PamBackend -from lib.test.ldap import ( +from tests.utilities.ldap import ( LdapTestCase, get_ldap_user_defaults ) diff --git a/rcamp/lib/test_ldap_utils.py b/rcamp/rcamp/tests/test_lib_ldap_utils.py similarity index 98% rename from rcamp/lib/test_ldap_utils.py rename to rcamp/rcamp/tests/test_lib_ldap_utils.py index 73b9dfa..83b8c7e 100644 --- a/rcamp/lib/test_ldap_utils.py +++ b/rcamp/rcamp/tests/test_lib_ldap_utils.py @@ -4,7 +4,7 @@ get_suffixed_username, get_ldap_username_and_org ) -from lib.test.utils import SafeTestCase +from tests.utilities.utils import SafeTestCase class LdapUtilsTestCase(SafeTestCase): diff --git a/rcamp/mailer/tests.py b/rcamp/rcamp/tests/test_mailer.py similarity index 100% rename from rcamp/mailer/tests.py rename to rcamp/rcamp/tests/test_mailer.py diff --git a/rcamp/projects/test_functional.py b/rcamp/rcamp/tests/test_projects_functional.py similarity index 98% rename from rcamp/projects/test_functional.py rename to rcamp/rcamp/tests/test_projects_functional.py index a9c6821..78883be 100644 --- a/rcamp/projects/test_functional.py +++ b/rcamp/rcamp/tests/test_projects_functional.py @@ -2,8 +2,8 @@ from accounts.models import User import copy -from lib.test.utils import get_auth_user_defaults -from lib.test.functional import UserAuthenticatedLiveServerTestCase +from tests.utilities.utils import get_auth_user_defaults +from tests.utilities.functional import UserAuthenticatedLiveServerTestCase from projects.models import Project diff --git a/rcamp/projects/test_models.py b/rcamp/rcamp/tests/test_projects_models.py similarity index 99% rename from rcamp/projects/test_models.py rename to rcamp/rcamp/tests/test_projects_models.py index cf55f48..dcda187 100644 --- a/rcamp/projects/test_models.py +++ b/rcamp/rcamp/tests/test_projects_models.py @@ -5,7 +5,7 @@ import pytz from django.conf import settings -from lib.test.utils import ( +from tests.utilities.utils import ( SafeTestCase, get_auth_user_defaults ) diff --git a/rcamp/projects/test_receivers.py b/rcamp/rcamp/tests/test_projects_receivers.py similarity index 97% rename from rcamp/projects/test_receivers.py rename to rcamp/rcamp/tests/test_projects_receivers.py index eb4f572..d41a589 100644 --- a/rcamp/projects/test_receivers.py +++ b/rcamp/rcamp/tests/test_projects_receivers.py @@ -2,8 +2,8 @@ import mock from django.test import override_settings -from lib.test.utils import SafeTestCase -from lib.test.ldap import get_ldap_user_defaults +from tests.utilities.utils import SafeTestCase +from tests.utilities.ldap import get_ldap_user_defaults from accounts.models import ( User, AccountRequest, diff --git a/rcamp/projects/test_views.py b/rcamp/rcamp/tests/test_projects_views.py similarity index 99% rename from rcamp/projects/test_views.py rename to rcamp/rcamp/tests/test_projects_views.py index ae240c8..fa1b854 100644 --- a/rcamp/projects/test_views.py +++ b/rcamp/rcamp/tests/test_projects_views.py @@ -6,7 +6,7 @@ from django.core.files.base import ContentFile from django.contrib.auth.models import User from django.contrib.auth.models import AnonymousUser -from lib.test.ldap import ( +from tests.utilities.ldap import ( LdapTestCase, get_ldap_user_defaults ) diff --git a/rcamp/rcamp/tests/utilities/__init__.py b/rcamp/rcamp/tests/utilities/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rcamp/lib/test/functional.py b/rcamp/rcamp/tests/utilities/functional.py similarity index 99% rename from rcamp/lib/test/functional.py rename to rcamp/rcamp/tests/utilities/functional.py index 8126605..22af37e 100644 --- a/rcamp/lib/test/functional.py +++ b/rcamp/rcamp/tests/utilities/functional.py @@ -5,7 +5,7 @@ import unittest import copy -from lib.test.utils import ( +from tests.utilities.utils import ( _assert_test_env_or_false, assert_test_env, _purge_ldap_objects diff --git a/rcamp/lib/test/ldap.py b/rcamp/rcamp/tests/utilities/ldap.py similarity index 98% rename from rcamp/lib/test/ldap.py rename to rcamp/rcamp/tests/utilities/ldap.py index 93dcd4b..6306837 100644 --- a/rcamp/lib/test/ldap.py +++ b/rcamp/rcamp/tests/utilities/ldap.py @@ -1,4 +1,4 @@ -from lib.test.utils import ( +from tests.utilities.utils import ( _purge_ldap_objects, SafeTestCase ) diff --git a/rcamp/lib/test/utils.py b/rcamp/rcamp/tests/utilities/utils.py similarity index 88% rename from rcamp/lib/test/utils.py rename to rcamp/rcamp/tests/utilities/utils.py index 33ce951..d0d9d2f 100644 --- a/rcamp/lib/test/utils.py +++ b/rcamp/rcamp/tests/utilities/utils.py @@ -1,3 +1,4 @@ +import os from django.test import TestCase from django.conf import settings from accounts.models import User @@ -14,11 +15,13 @@ def assert_test_env(): """Helper method to verify that tests are not being executed in a production environment.""" # We can reasonably assume that no production resource will satisfy this criteria, so # this is one of several safeguards against running the functional tests against prod. + assert os.environ.get('RCAMP_DEBUG') == 'True' assert settings.DATABASES['rcldap']['PASSWORD'] == 'password' - # In an abundance of caution, also make sure that the LDAP connection is configured - # to use localhost. - assert 'localhost' in settings.DATABASES['rcldap']['NAME'] - # Probably not running against prod LDAP. + # In an abundance of caution, also make sure that the LDAP and MySQL connections are configured + # to use the test services. + assert 'test-ldap' in settings.DATABASES['rcldap']['NAME'] + assert 'test-mysql' in settings.DATABASES['default']['HOST'] + # Probably not running against prod backends. return True def _assert_test_env_or_false(): @@ -63,7 +66,7 @@ class SafeTestCase(TestCase): connection settings can be changed within the context of of individual test cases. IMPORTANT: Every unit or integration test should inherit from this class. For functional tests - user lib.test.functional.SafeStaticLiveServerTestCase instead. + user tests.utilities.functional.SafeStaticLiveServerTestCase instead. """ @classmethod def setUpClass(cls): diff --git a/rcamp/uwsgi.ini b/rcamp/uwsgi.ini new file mode 100644 index 0000000..7970b42 --- /dev/null +++ b/rcamp/uwsgi.ini @@ -0,0 +1,12 @@ +[uwsgi] +socket = :8000 +chdir = /home/uwsgi/rcamp/ +wsgi-file = rcamp/wsgi.py +enable-threads = true +processes = 2 +threads = 2 +max-requests = 5000 +log-date = true +uid = uwsgi +gid = uwsgi +master = true From a3340ce9e69b1002e0576d8c17e26c56b8ffe609 Mon Sep 17 00:00:00 2001 From: Zebula Sampedro Date: Tue, 29 May 2018 14:37:26 -0600 Subject: [PATCH 06/49] Issues/314 (#315) * Subclassed PhantomJS driver for more durable builds. * Each test case gets a fresh webdriver. Slower, but worth a try. * Removed class-level setup and teardown. Closes #314. --- rcamp/rcamp/tests/utilities/functional.py | 41 +++++++++++++++-------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/rcamp/rcamp/tests/utilities/functional.py b/rcamp/rcamp/tests/utilities/functional.py index 22af37e..14669d9 100644 --- a/rcamp/rcamp/tests/utilities/functional.py +++ b/rcamp/rcamp/tests/utilities/functional.py @@ -1,6 +1,7 @@ from django.contrib.staticfiles.testing import StaticLiveServerTestCase from django.conf import settings from selenium import webdriver +from selenium.common import exceptions import datetime import unittest import copy @@ -18,6 +19,27 @@ ) +class PhantomJSWithRetry(webdriver.PhantomJS): + """ + Pulled from https://github.com/chris48s/UK-Polling-Stations/blob/66e96b52ce6bb6e9c0d864a8eb7e9bd53192f8b8/polling_stations/apps/data_finder/features/index.py + to get around https://github.com/ariya/phantomjs/issues/11526#issuecomment-133570834 + and https://github.com/travis-ci/travis-ci/issues/3251. + + Override execute() so it will retry if we get a selenium.common.exceptions.TimeoutException + this is a hack to work around an underlying issue in selenium and phantomjs running within a + Docker container. + """ + def execute(self, driver_command, params=None): + for _ in range(3): + try: + return super(PhantomJSWithRetry,self).execute(driver_command, params) + except exceptions.TimeoutException as e: + print('trying again...') + error = e + print('giving up! :(') + raise error + + @unittest.skipUnless(_assert_test_env_or_false(),"Tests are not being run against a safe test environment!") class SafeStaticLiveServerTestCase(StaticLiveServerTestCase): """ @@ -36,28 +58,19 @@ class SafeStaticLiveServerTestCase(StaticLiveServerTestCase): All RCAMP functional tests should inherit from this class. """ - @classmethod - def setUpClass(cls): - assert_test_env() - # Start the web driver - cls.browser = webdriver.PhantomJS() - cls.browser.set_window_size(1366, 768) - super(SafeStaticLiveServerTestCase,cls).setUpClass() - - @classmethod - def tearDownClass(cls): - cls.browser.quit() - assert_test_env() - super(SafeStaticLiveServerTestCase,cls).tearDownClass() - def setUp(self): assert_test_env() + self.browser = PhantomJSWithRetry() + self.browser.set_page_load_timeout(10) + self.browser.set_script_timeout(10) + self.browser.set_window_size(1366, 768) _purge_ldap_objects() super(SafeStaticLiveServerTestCase,self).setUp() def tearDown(self): assert_test_env() _purge_ldap_objects() + self.browser.quit() super(SafeStaticLiveServerTestCase,self).tearDown() class UserAuthenticatedLiveServerTestCase(SafeStaticLiveServerTestCase): From ab22cfa9bcadf71e9e815752946c2108e44dcc73 Mon Sep 17 00:00:00 2001 From: Zebula Sampedro Date: Tue, 29 May 2018 16:39:52 -0600 Subject: [PATCH 07/49] Added missing import, fixes #303. (#313) * Added missing import, fixes #303. * Issues/314 (#315) * Subclassed PhantomJS driver for more durable builds. * Each test case gets a fresh webdriver. Slower, but worth a try. * Removed class-level setup and teardown. Closes #314. * Added missing import, fixes #303. --- rcamp/rcamp/tests/test_projects_receivers.py | 22 ++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/rcamp/rcamp/tests/test_projects_receivers.py b/rcamp/rcamp/tests/test_projects_receivers.py index d41a589..dc07320 100644 --- a/rcamp/rcamp/tests/test_projects_receivers.py +++ b/rcamp/rcamp/tests/test_projects_receivers.py @@ -113,3 +113,25 @@ def test_check_general_eligibility_suffixed(self): project = Project.objects.get() self.assertIn(auth_user,project.collaborators.all()) + + def test_check_general_eligibility_no_intent(self): + user_defaults = get_ldap_user_defaults() + + auth_user_defaults = dict( + username=user_defaults['username'], + first_name=user_defaults['first_name'], + last_name=user_defaults['last_name'], + email=user_defaults['email'] + ) + auth_user = User.objects.create(**auth_user_defaults) + + account_request_defaults = dict( + username=auth_user.username, + first_name=auth_user.first_name, + last_name=auth_user.last_name, + email=auth_user.email, + organization='ucb' + ) + account_request = AccountRequest.objects.create(**account_request_defaults) + + check_general_eligibility(account_request.__class__,account_request=account_request) From 5b2be8de0b9fbc04becf6e774669b34703ded8e9 Mon Sep 17 00:00:00 2001 From: Zebula Sampedro Date: Wed, 30 May 2018 09:58:50 -0600 Subject: [PATCH 08/49] Use the built-in user admin for the custom user model. Fixes #270. (#316) --- rcamp/rcamp/accounts/admin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rcamp/rcamp/accounts/admin.py b/rcamp/rcamp/accounts/admin.py index 1119f58..6469763 100644 --- a/rcamp/rcamp/accounts/admin.py +++ b/rcamp/rcamp/accounts/admin.py @@ -1,4 +1,5 @@ from django.contrib import admin +from django.contrib.auth import admin as auth_admin from django import forms from lib.fields import LdapCsvField from accounts.models import ( @@ -14,7 +15,7 @@ @admin.register(User) -class UserAdmin(admin.ModelAdmin): +class UserAdmin(auth_admin.UserAdmin): list_display = ['username','organization','first_name','last_name','email'] search_fields = ['username','first_name','last_name','email'] From 8ad15d5a611f85f68f3e855c8ba773ef6d47ab95 Mon Sep 17 00:00:00 2001 From: Zebula Sampedro Date: Fri, 24 Aug 2018 13:14:20 -0600 Subject: [PATCH 09/49] Updated query form, fixes #319. (#328) --- rcamp/rcamp/projects/views.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/rcamp/rcamp/projects/views.py b/rcamp/rcamp/projects/views.py index ea08624..56571c2 100644 --- a/rcamp/rcamp/projects/views.py +++ b/rcamp/rcamp/projects/views.py @@ -286,10 +286,7 @@ def form_valid(self, form): ar_dict.update(form.cleaned_data) ar = AllocationRequest.objects.create(**ar_dict) - try: - requester = RcLdapUser.objects.get(username=ar.requester.username) - except RcLdapUser.DoesNotExist: - requester = None + requester = RcLdapUser.objects.get_user_from_suffixed_username(ar.requester.username) allocation_request_created_by_user.send(sender=ar.__class__,allocation_request=ar,requester=requester) self.success_url = reverse_lazy( From 7cbb773c9d727ed5ce5aca61d9f3a20e39c1d6f7 Mon Sep 17 00:00:00 2001 From: Zebula Sampedro Date: Mon, 27 Aug 2018 15:02:50 -0600 Subject: [PATCH 10/49] Order by username instead of primary key. Fixes #304. (#329) --- rcamp/rcamp/projects/admin.py | 4 ++-- rcamp/rcamp/projects/forms.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rcamp/rcamp/projects/admin.py b/rcamp/rcamp/projects/admin.py index 293df23..26d2cfe 100644 --- a/rcamp/rcamp/projects/admin.py +++ b/rcamp/rcamp/projects/admin.py @@ -19,7 +19,7 @@ # for filtered multiselect widget. class ProjectAdminForm(forms.ModelForm): managers = forms.ModelMultipleChoiceField( - queryset=User.objects.all(), + queryset=User.objects.all().order_by('username'), required=False, widget=admin.widgets.FilteredSelectMultiple( 'managers', @@ -27,7 +27,7 @@ class ProjectAdminForm(forms.ModelForm): ) ) collaborators = forms.ModelMultipleChoiceField( - queryset=User.objects.all(), + queryset=User.objects.all().order_by('username'), required=False, widget=admin.widgets.FilteredSelectMultiple( 'collaborators', diff --git a/rcamp/rcamp/projects/forms.py b/rcamp/rcamp/projects/forms.py index 221ba17..098b9b0 100644 --- a/rcamp/rcamp/projects/forms.py +++ b/rcamp/rcamp/projects/forms.py @@ -28,7 +28,7 @@ class Meta: pi_emails = MultiEmailField(required=True) managers = ProjectMembersModelMultipleChoiceField( - queryset=User.objects.all(), + queryset=User.objects.all().order_by('username'), required=False, widget=admin.widgets.FilteredSelectMultiple( 'managers', @@ -36,7 +36,7 @@ class Meta: ) ) collaborators = ProjectMembersModelMultipleChoiceField( - queryset=User.objects.all(), + queryset=User.objects.all().order_by('username'), required=False, widget=admin.widgets.FilteredSelectMultiple( 'collaborators', From 1bf364427bc34628edfebcc136dadbc09a7cd0dd Mon Sep 17 00:00:00 2001 From: Zebula Sampedro Date: Wed, 29 Aug 2018 15:00:51 -0600 Subject: [PATCH 11/49] Issues/307 (#331) * Starting to redesign user-facing pages. * Redirect authed users to project management page. Closes #310, closes #308. * Revised placement and content on jumbotrons. Closes #306. * Finished minimizing jumbotron use and content. Closes #307. --- .../templates/account-request-intent.html | 33 ------- .../templates/account-request-org-select.html | 24 ++--- .../templates/account-request-review.html | 22 ++--- .../templates/account-request-verify-csu.html | 25 ------ .../templates/account-request-verify-ucb.html | 25 ------ rcamp/rcamp/lib/views.py | 9 ++ .../templates/allocation-request-create.html | 15 ++-- .../templates/allocation-request-detail.html | 5 -- .../projects/templates/project-create.html | 12 +-- .../projects/templates/project-detail.html | 5 -- .../projects/templates/project-edit.html | 5 -- .../projects/templates/project-list.html | 12 +-- .../projects/templates/reference-create.html | 12 +-- .../projects/templates/reference-detail.html | 5 -- .../projects/templates/reference-edit.html | 5 -- rcamp/rcamp/rcamp/static/css/jumbotron.css | 88 ------------------- rcamp/rcamp/rcamp/static/css/rcamp.css | 14 ++- rcamp/rcamp/rcamp/templates/404.html | 17 ++-- rcamp/rcamp/rcamp/templates/500.html | 17 ++-- rcamp/rcamp/rcamp/templates/base.html | 61 ++++++------- rcamp/rcamp/rcamp/templates/index.html | 70 +++++++-------- rcamp/rcamp/rcamp/templates/login.html | 20 ++--- rcamp/rcamp/rcamp/templates/logout.html | 20 ++--- .../rcamp/templates/terms-and-conditions.html | 21 ----- rcamp/rcamp/rcamp/urls.py | 2 +- 25 files changed, 161 insertions(+), 383 deletions(-) delete mode 100644 rcamp/rcamp/rcamp/static/css/jumbotron.css delete mode 100644 rcamp/rcamp/rcamp/templates/terms-and-conditions.html diff --git a/rcamp/rcamp/accounts/templates/account-request-intent.html b/rcamp/rcamp/accounts/templates/account-request-intent.html index 23bbb82..52a11b4 100644 --- a/rcamp/rcamp/accounts/templates/account-request-intent.html +++ b/rcamp/rcamp/accounts/templates/account-request-intent.html @@ -6,39 +6,6 @@ {% endblock %} -{% block jumbotron_heading %}

Account Request

{% endblock %} -{% block jumbotron_subheading %} -

Request an account with University of Colorado Boulder Research Computing.

-{% endblock %} -{% block jumbotron_button %} -

Definitions & Form Help »

-{% endblock %} - -{% block modal_title %} - -{% endblock %} -{% block modal_body %} -
    -
  • - Summit supercomputing cluster (2016) -

    Summit is a heterogeneous supercomputing cluster based primarily on the Intel Xeon "Haswell" CPU, with secondary NVidia Tesla K80 and high-memory resources and, in the future, an Intel Xeon Phi "knights landing" MIC resource. It replaces Janus as Research Computing's flagship computational resource. All nodes sit on a first-generation Intel Omni-Path Architecture interconnect which also provides access to an IBM GPFS Parallel scratch file system. Learn more about Summit.

    -
  • -
  • - Blanca "condo" compute cluster -

    The Research Computing Condo Computing service offers researchers the opportunity to purchase and own compute nodes that will be operated as part of the Blanca compute cluster. The aggregate cluster is made available to all condo partners while maintaining priority for the owner of each node. Learn more about Blanca.

    -
  • -
  • - PetaLibrary/active disk storage -

    The PetaLibrary/active storage service is mounted at /work/ on all Research Computing computational systems. This storage may be used by compute workloads, but it is not designed to be performant under I/O-intensive applications or parallel writes. Learn more about PetaLibrary.

    -
  • -
  • - PetaLibrary/archive long-term disk+tape storage -

    PetaLibrary/archive is a hierarchical storage system that dynamically and simultaneously manages data on both disk and tape storage systems while presenting all data as part of a single, unified filesystem namespace. This provides good performance when accessing frequently-used data while remaining cost-effective for storing large quantities of archive data. Learn more about PetaLibrary.

    -
  • -
-{% endblock %} - {% block container %}
Questions about the account request process? diff --git a/rcamp/rcamp/accounts/templates/account-request-org-select.html b/rcamp/rcamp/accounts/templates/account-request-org-select.html index 0e3af65..7363f83 100644 --- a/rcamp/rcamp/accounts/templates/account-request-org-select.html +++ b/rcamp/rcamp/accounts/templates/account-request-org-select.html @@ -6,25 +6,13 @@ {% endblock %} -{% block jumbotron_heading %}

Account Request

{% endblock %} -{% block jumbotron_subheading %} -

Request a Research Computing account.

-{% endblock %} - -{% block jumbotron_button %} -

Terms & Conditions »

-{% endblock %} - -{% block modal_title %} - -{% endblock %} - -{% block modal_body %} -{% include "terms-and-conditions.html" %} -{% endblock %} - {% block container %} +
+
+

Account Request

+

Request a Research Computing account.

+
+
Please select your organization to begin.