diff --git a/.travis.yml b/.travis.yml index fba238f6..9ca51691 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: python python: - - "3.7" + - "3.6.9" services: - postgresql diff --git a/Dockerfile b/Dockerfile index 8ff7af23..fae1657f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,27 +1,24 @@ -FROM python:3.7 +FROM python:3.6.9-slim -ENV PATH=/root/.local/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin +WORKDIR /app -# install node and yarn -RUN apt-get update -RUN apt-get -y install postgresql-client +COPY Pipfile Pipfile.lock /app/ -# config project dir -RUN mkdir /crc-workflow -WORKDIR /crc-workflow +RUN pip install pipenv && \ + apt-get update && \ + apt-get install -y --no-install-recommends \ + gcc python3-dev libssl-dev \ + curl postgresql-client git-core && \ + pipenv install --dev && \ + apt-get remove -y gcc python3-dev libssl-dev && \ + apt-get purge -y --auto-remove && \ + rm -rf /var/lib/apt/lists/ * -# install python requirements -RUN pip install pipenv -ADD Pipfile /crc-workflow/ -ADD Pipfile.lock /crc-workflow/ -RUN pipenv install --dev +COPY . /app/ -# include rejoiner code (gets overriden by local changes) -COPY . /crc-workflow/ - -# run webserver by default -ENV FLASK_APP=./crc/__init__.py -CMD ["pipenv", "run", "python", "./run.py"] +ENV FLASK_APP=/app/crc/__init__.py +CMD ["pipenv", "run", "flask", "db", "upgrade"] +CMD ["pipenv", "run", "python", "/app/run.py"] # expose ports EXPOSE 5000 diff --git a/Pipfile b/Pipfile index 6f374722..77c70afc 100644 --- a/Pipfile +++ b/Pipfile @@ -24,18 +24,17 @@ pyjwt = "*" requests = "*" xlsxwriter = "*" webtest = "*" -spiffworkflow = {editable = true,git = "https://github.com/sartography/SpiffWorkflow.git",ref = "bug/the_horror"} +spiffworkflow = {editable = true,git = "https://github.com/sartography/SpiffWorkflow.git",ref = "master"} alembic = "*" coverage = "*" sphinx = "*" recommonmark = "*" psycopg2-binary = "*" docxtpl = "*" -flask-sso = "*" python-dateutil = "*" pandas = "*" xlrd = "*" ldap3 = "*" [requires] -python_version = "3.7" +python_version = "3.6.9" diff --git a/Pipfile.lock b/Pipfile.lock index 4f8b70c9..036d4bf9 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,11 +1,11 @@ { "_meta": { "hash": { - "sha256": "bd289126c41b0f5f2761f0415d85e1110a584256460374a9ce4cda07c0033ddd" + "sha256": "1ca737db75750ea4351c15b4b0b26155d90bc5522705ed293a0c2773600b6a0a" }, "pipfile-spec": 6, "requires": { - "python_version": "3.7" + "python_version": "3.6.9" }, "sources": [ { @@ -96,12 +96,6 @@ ], "version": "==3.6.3.0" }, - "blinker": { - "hashes": [ - "sha256:471aee25f3992bd325afa3772f1063dbdbbca947a041b8b89466dc00d606f8b6" - ], - "version": "==1.4" - }, "celery": { "hashes": [ "sha256:108a0bf9018a871620936c33a3ee9f6336a89f8ef0a0f567a9001f4aa361415f", @@ -307,13 +301,6 @@ ], "version": "==2.4.1" }, - "flask-sso": { - "hashes": [ - "sha256:541a8a2387c6eac4325c53f8f7f863a03173b37aa558a37a430010d7fc1a3633" - ], - "index": "pypi", - "version": "==0.4.0" - }, "future": { "hashes": [ "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d" @@ -401,35 +388,35 @@ }, "lxml": { "hashes": [ - "sha256:06d4e0bbb1d62e38ae6118406d7cdb4693a3fa34ee3762238bcb96c9e36a93cd", - "sha256:0701f7965903a1c3f6f09328c1278ac0eee8f56f244e66af79cb224b7ef3801c", - "sha256:1f2c4ec372bf1c4a2c7e4bb20845e8bcf8050365189d86806bad1e3ae473d081", - "sha256:4235bc124fdcf611d02047d7034164897ade13046bda967768836629bc62784f", - "sha256:5828c7f3e615f3975d48f40d4fe66e8a7b25f16b5e5705ffe1d22e43fb1f6261", - "sha256:585c0869f75577ac7a8ff38d08f7aac9033da2c41c11352ebf86a04652758b7a", - "sha256:5d467ce9c5d35b3bcc7172c06320dddb275fea6ac2037f72f0a4d7472035cea9", - "sha256:63dbc21efd7e822c11d5ddbedbbb08cd11a41e0032e382a0fd59b0b08e405a3a", - "sha256:7bc1b221e7867f2e7ff1933165c0cec7153dce93d0cdba6554b42a8beb687bdb", - "sha256:8620ce80f50d023d414183bf90cc2576c2837b88e00bea3f33ad2630133bbb60", - "sha256:8a0ebda56ebca1a83eb2d1ac266649b80af8dd4b4a3502b2c1e09ac2f88fe128", - "sha256:90ed0e36455a81b25b7034038e40880189169c308a3df360861ad74da7b68c1a", - "sha256:95e67224815ef86924fbc2b71a9dbd1f7262384bca4bc4793645794ac4200717", - "sha256:afdb34b715daf814d1abea0317b6d672476b498472f1e5aacbadc34ebbc26e89", - "sha256:b4b2c63cc7963aedd08a5f5a454c9f67251b1ac9e22fd9d72836206c42dc2a72", - "sha256:d068f55bda3c2c3fcaec24bd083d9e2eede32c583faf084d6e4b9daaea77dde8", - "sha256:d5b3c4b7edd2e770375a01139be11307f04341ec709cf724e0f26ebb1eef12c3", - "sha256:deadf4df349d1dcd7b2853a2c8796593cc346600726eff680ed8ed11812382a7", - "sha256:df533af6f88080419c5a604d0d63b2c33b1c0c4409aba7d0cb6de305147ea8c8", - "sha256:e4aa948eb15018a657702fee0b9db47e908491c64d36b4a90f59a64741516e77", - "sha256:e5d842c73e4ef6ed8c1bd77806bf84a7cb535f9c0cf9b2c74d02ebda310070e1", - "sha256:ebec08091a22c2be870890913bdadd86fcd8e9f0f22bcb398abd3af914690c15", - "sha256:edc15fcfd77395e24543be48871c251f38132bb834d9fdfdad756adb6ea37679", - "sha256:f2b74784ed7e0bc2d02bd53e48ad6ba523c9b36c194260b7a5045071abbb1012", - "sha256:fa071559f14bd1e92077b1b5f6c22cf09756c6de7139370249eb372854ce51e6", - "sha256:fd52e796fee7171c4361d441796b64df1acfceb51f29e545e812f16d023c4bbc", - "sha256:fe976a0f1ef09b3638778024ab9fb8cde3118f203364212c198f71341c0715ca" + "sha256:06748c7192eab0f48e3d35a7adae609a329c6257495d5e53878003660dc0fec6", + "sha256:0790ddca3f825dd914978c94c2545dbea5f56f008b050e835403714babe62a5f", + "sha256:1aa7a6197c1cdd65d974f3e4953764eee3d9c7b67e3966616b41fab7f8f516b7", + "sha256:22c6d34fdb0e65d5f782a4d1a1edb52e0a8365858dafb1c08cb1d16546cf0786", + "sha256:2754d4406438c83144f9ffd3628bbe2dcc6d62b20dbc5c1ec4bc4385e5d44b42", + "sha256:27ee0faf8077c7c1a589573b1450743011117f1aa1a91d5ae776bbc5ca6070f2", + "sha256:2b02c106709466a93ed424454ce4c970791c486d5fcdf52b0d822a7e29789626", + "sha256:2d1ddce96cf15f1254a68dba6935e6e0f1fe39247de631c115e84dd404a6f031", + "sha256:4f282737d187ae723b2633856085c31ae5d4d432968b7f3f478a48a54835f5c4", + "sha256:51bb4edeb36d24ec97eb3e6a6007be128b720114f9a875d6b370317d62ac80b9", + "sha256:7eee37c1b9815e6505847aa5e68f192e8a1b730c5c7ead39ff317fde9ce29448", + "sha256:7fd88cb91a470b383aafad554c3fe1ccf6dfb2456ff0e84b95335d582a799804", + "sha256:9144ce36ca0824b29ebc2e02ca186e54040ebb224292072250467190fb613b96", + "sha256:925baf6ff1ef2c45169f548cc85204433e061360bfa7d01e1be7ae38bef73194", + "sha256:a636346c6c0e1092ffc202d97ec1843a75937d8c98aaf6771348ad6422e44bb0", + "sha256:a87dbee7ad9dce3aaefada2081843caf08a44a8f52e03e0a4cc5819f8398f2f4", + "sha256:a9e3b8011388e7e373565daa5e92f6c9cb844790dc18e43073212bb3e76f7007", + "sha256:afb53edf1046599991fb4a7d03e601ab5f5422a5435c47ee6ba91ec3b61416a6", + "sha256:b26719890c79a1dae7d53acac5f089d66fd8cc68a81f4e4bd355e45470dc25e1", + "sha256:b7462cdab6fffcda853338e1741ce99706cdf880d921b5a769202ea7b94e8528", + "sha256:b77975465234ff49fdad871c08aa747aae06f5e5be62866595057c43f8d2f62c", + "sha256:c47a8a5d00060122ca5908909478abce7bbf62d812e3fc35c6c802df8fb01fe7", + "sha256:c79e5debbe092e3c93ca4aee44c9a7631bdd407b2871cb541b979fd350bbbc29", + "sha256:d8d40e0121ca1606aa9e78c28a3a7d88a05c06b3ca61630242cded87d8ce55fa", + "sha256:ee2be8b8f72a2772e72ab926a3bccebf47bb727bda41ae070dc91d1fb759b726", + "sha256:f95d28193c3863132b1f55c1056036bf580b5a488d908f7d22a04ace8935a3a9", + "sha256:fadd2a63a2bfd7fb604508e553d1cf68eca250b2fbdbd81213b5f6f2fbf23529" ], - "version": "==4.5.0" + "version": "==4.5.1" }, "mako": { "hashes": [ @@ -543,10 +530,10 @@ }, "packaging": { "hashes": [ - "sha256:3c292b474fda1671ec57d46d739d072bfd495a4f51ad01a055121d81e952b7a3", - "sha256:82f77b9bee21c1bafbf35a84905d604d5d1223801d639cf3ed140bd651c08752" + "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8", + "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181" ], - "version": "==20.3" + "version": "==20.4" }, "pandas": { "hashes": [ @@ -711,10 +698,10 @@ }, "six": { "hashes": [ - "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a", - "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c" + "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", + "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "version": "==1.14.0" + "version": "==1.15.0" }, "snowballstemmer": { "hashes": [ @@ -783,7 +770,7 @@ "spiffworkflow": { "editable": true, "git": "https://github.com/sartography/SpiffWorkflow.git", - "ref": "070d80fd670e129aae7ee949b3e66cc744520e49" + "ref": "cb098ee6d55b85bf7795997f4ad5f78c27d15381" }, "sqlalchemy": { "hashes": [ @@ -919,10 +906,10 @@ }, "packaging": { "hashes": [ - "sha256:3c292b474fda1671ec57d46d739d072bfd495a4f51ad01a055121d81e952b7a3", - "sha256:82f77b9bee21c1bafbf35a84905d604d5d1223801d639cf3ed140bd651c08752" + "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8", + "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181" ], - "version": "==20.3" + "version": "==20.4" }, "pluggy": { "hashes": [ @@ -955,10 +942,10 @@ }, "six": { "hashes": [ - "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a", - "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c" + "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", + "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "version": "==1.14.0" + "version": "==1.15.0" }, "wcwidth": { "hashes": [ diff --git a/config/default.py b/config/default.py index dd19f2ab..d2486f86 100644 --- a/config/default.py +++ b/config/default.py @@ -27,19 +27,6 @@ TOKEN_AUTH_SECRET_KEY = environ.get('TOKEN_AUTH_SECRET_KEY', default="Shhhh!!! T FRONTEND_AUTH_CALLBACK = environ.get('FRONTEND_AUTH_CALLBACK', default="http://localhost:4200/session") SWAGGER_AUTH_KEY = environ.get('SWAGGER_AUTH_KEY', default="SWAGGER") -#: Default attribute map for single signon. -SSO_LOGIN_URL = '/login' -SSO_ATTRIBUTE_MAP = { - 'eppn': (False, 'eppn'), # dhf8r@virginia.edu - 'uid': (True, 'uid'), # dhf8r - 'givenName': (False, 'first_name'), # Daniel - 'mail': (False, 'email_address'), # dhf8r@Virginia.EDU - 'sn': (False, 'last_name'), # Funk - 'affiliation': (False, 'affiliation'), # 'staff@virginia.edu;member@virginia.edu' - 'displayName': (False, 'display_name'), # Daniel Harold Funk - 'title': (False, 'title') # SOFTWARE ENGINEER V -} - # %s/%i placeholders expected for uva_id and study_id in various calls. PB_BASE_URL = environ.get('PB_BASE_URL', default="http://localhost:5001/pb/") PB_USER_STUDIES_URL = environ.get('PB_USER_STUDIES_URL', default=PB_BASE_URL + "user_studies?uva_id=%s") diff --git a/crc/__init__.py b/crc/__init__.py index aa301108..9f1c4ee3 100644 --- a/crc/__init__.py +++ b/crc/__init__.py @@ -6,7 +6,6 @@ from flask_cors import CORS from flask_marshmallow import Marshmallow from flask_migrate import Migrate from flask_sqlalchemy import SQLAlchemy -from flask_sso import SSO logging.basicConfig(level=logging.INFO) @@ -31,7 +30,6 @@ session = db.session migrate = Migrate(app, db) ma = Marshmallow(app) -sso = SSO(app=app) from crc import models from crc import api diff --git a/crc/api/user.py b/crc/api/user.py index 83245d19..6924eb27 100644 --- a/crc/api/user.py +++ b/crc/api/user.py @@ -1,12 +1,12 @@ import json import connexion -from flask import redirect, g +from flask import redirect, g, request -from crc import sso, app, db +from crc import app, db from crc.api.common import ApiError from crc.models.user import UserModel, UserModelSchema - +from crc.services.ldap_service import LdapService, LdapUserInfo """ .. module:: crc.api.user @@ -32,53 +32,76 @@ def verify_token(token): def get_current_user(): return UserModelSchema().dump(g.user) +@app.route('/login') +def sso_login(): + # This what I see coming back: + # X-Remote-Cn: Daniel Harold Funk (dhf8r) + # X-Remote-Sn: Funk + # X-Remote-Givenname: Daniel + # X-Remote-Uid: dhf8r + # Eppn: dhf8r@virginia.edu + # Cn: Daniel Harold Funk (dhf8r) + # Sn: Funk + # Givenname: Daniel + # Uid: dhf8r + # X-Remote-User: dhf8r@virginia.edu + # X-Forwarded-For: 128.143.0.10 + # X-Forwarded-Host: dev.crconnect.uvadcos.io + # X-Forwarded-Server: dev.crconnect.uvadcos.io + # Connection: Keep-Alive + uid = request.headers.get("Uid") + if not uid: + uid = request.headers.get("X-Remote-Uid") -@sso.login_handler -def sso_login(user_info): - app.logger.info("Login from Shibboleth happening. " + json.dump(user_info)) - # TODO: Get redirect URL from Shibboleth request header - _handle_login(user_info) + if not uid: + raise ApiError("invalid_sso_credentials", "'Uid' nor 'X-Remote-Uid' were present in the headers: %s" + % str(request.headers)) + + redirect = request.args.get('redirect') + app.logger.info("SSO_LOGIN: Full URL: " + request.url) + app.logger.info("SSO_LOGIN: User Id: " + uid) + app.logger.info("SSO_LOGIN: Will try to redirect to : " + str(redirect)) + + ldap_service = LdapService() + info = ldap_service.user_info(uid) + + return _handle_login(info, redirect) + +@app.route('/sso') +def sso(): + response = "" + response += "

Headers

" + response += "