From 23d8c20768b4f91791b86d2438dee97e8d78f169 Mon Sep 17 00:00:00 2001 From: "Jiaqi (Jacky) Wang" Date: Fri, 12 Apr 2024 21:22:15 -0400 Subject: [PATCH 1/4] saml: config saml auth settings --- .gitignore | 4 +- authpipe/urls.py | 1 + authpipe/views.py | 14 ++ build/semesterly-base/Dockerfile | 2 + requirements.txt | 154 ++++++++++++++++-- semesterly/settings.py | 34 ++++ .../redux/ui/modals/UserAcquisitionModal.tsx | 2 +- 7 files changed, 196 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index ddc3df0207..529bea3afc 100644 --- a/.gitignore +++ b/.gitignore @@ -57,4 +57,6 @@ venv/ webpack-stats.json workfile.html cache -stunnel/ \ No newline at end of file +stunnel/ +saml.crt +saml.key \ No newline at end of file diff --git a/authpipe/urls.py b/authpipe/urls.py index ee12f66d02..e65a60b91e 100644 --- a/authpipe/urls.py +++ b/authpipe/urls.py @@ -19,4 +19,5 @@ # auth re_path("", include("social_django.urls", namespace="social")), re_path("", include(("django.contrib.auth.urls", "auth"), namespace="auth")), + re_path(r"^saml/metadata$", authpipe.views.saml_metadata_view), ] diff --git a/authpipe/views.py b/authpipe/views.py index defc0f99ee..6eb0b564a4 100644 --- a/authpipe/views.py +++ b/authpipe/views.py @@ -9,3 +9,17 @@ # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. +from django.http import HttpResponse +from django.urls import reverse +from social_django.utils import load_strategy, load_backend + +def saml_metadata_view(request): + complete_url = reverse('social:complete', args=("saml", )) + saml_backend = load_backend( + load_strategy(request), + "saml", + redirect_uri=complete_url, + ) + metadata, errors = saml_backend.generate_metadata_xml() + if not errors: + return HttpResponse(content=metadata, content_type='text/xml') \ No newline at end of file diff --git a/build/semesterly-base/Dockerfile b/build/semesterly-base/Dockerfile index 160b1c394b..2444970a79 100644 --- a/build/semesterly-base/Dockerfile +++ b/build/semesterly-base/Dockerfile @@ -14,5 +14,7 @@ RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - RUN apt-get install -y nodejs # This saves some build time by installing base requirements +RUN apt install libxmlsec1 libxmlsec1-dev + ADD ./requirements_base.txt /tmp RUN pip3 install -r /tmp/requirements_base.txt diff --git a/requirements.txt b/requirements.txt index a9d793e744..6bc3257fa0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,60 +1,188 @@ -setuptools==65.5.1 -Pygments==2.15.0 -Sphinx==4.0.2 alabaster==0.7.10 -argparse==1.4.0 +amqp==5.2.0 +anyjson==0.3.3 +argh==0.26.2 +asgiref==3.7.2 +asn1crypto==0.22.0 +attrs==21.2.0 +autopep8==1.3.2 +Babel==2.5.0 +backports.functools-lru-cache==1.4 +backports.zoneinfo==0.2.1 beautifulsoup4==4.6.0 -black==24.3.0 +billiard==3.6.4.0 +black==22.3.0 +bottlenose==1.1.3 bs4==0.0.1 +caniusepython3==5.0.0 celery==5.2.2 +certifi==2017.7.27.1 +cffi==1.14.4 +chardet==3.0.4 +charset-normalizer==3.3.2 +click==8.1.7 +click-didyoumean==0.3.0 +click-plugins==1.1.1 +click-repl==0.3.0 +colorama==0.3.9 +CommonMark==0.5.4 +coreapi==2.3.3 +coreschema==0.0.4 coverage==6.3.2 -cryptography==41.0.6 +cryptography==41.0.4 dateparser==1.1.0 +defusedxml==0.5.0 +distlib==0.2.5 +distro==1.5.0 +dj-database-url==0.5.0 Django==3.2.20 django-cachalot==2.4.3 -django-ckeditor==6.2.0 -django-debug-toolbar==3.8.1 +django-celery==3.3.1 +django-celery-beat==1.0.0 +django-ckeditor==6.2.0 django-extensions==3.1.5 +django-js-asset==2.1.0 django-picklefield==3.0.1 +django-rest-swagger==2.2.0 django-webpack-loader==0.7.0 +django_debug_toolbar==3.8.1 djangorestframework==3.12.2 +docutils==0.14 drf-yasg==1.20.0 +ecdsa==0.13 +exceptiongroup==1.1.3 fake-useragent==1.1.1 +flake8==3.8.4 future==0.18.3 futures==3.1.1 fuzzywuzzy==0.15.1 +google-api-python-client==1.6.2 gunicorn==19.7.1 +h11==0.14.0 hashids==1.2.0 +html5lib==0.999999999 +http-ece==1.0.5 +httplib2==0.10.3 +idna==2.6 +imagesize==0.7.1 +importlib-metadata==6.8.0 +importlib-resources==6.1.1 +inflection==0.5.1 interruptingcow==0.7 +isodate==0.6.1 +itypes==1.1.0 +Jinja2==2.9.6 +joblib==1.0.1 jsondiff==1.1.1 +jsonfield==2.0.2 +jsonpatch==1.16 +jsonpointer==1.10 jsonschema==3.2.0 +kombu==5.3.3 +livereload==2.5.1 lxml==4.9.1 -markdown==3.4.1 +Markdown==3.4.1 +MarkupSafe==1.1.1 +mccabe==0.6.1 mock==2.0.0 +mypy-extensions==1.0.0 nltk==3.6.6 numpy==1.22.0 +oauth==1.0.1 oauth2client==4.1.2 +oauthlib==2.0.2 +openapi-codec==1.3.2 +outcome==1.3.0.post0 +packaging==16.8 +pathspec==0.11.2 +pathtools==0.1.2 +pbr==3.1.1 +pep8==1.7.0 +platformdirs==3.11.0 +port-for==0.3.1 +prettytable==0.7.2 progressbar2==3.34.2 +prompt-toolkit==3.0.39 +psycopg2==2.8.6 psycopg2-binary==2.8.6 +py-vapid==1.3.0 +pyasn1==0.3.2 +pyasn1-modules==0.0.11 pycodestyle==2.6.0 +pycparser==2.18 +pycrypto==2.6.1 +pyelliptic==1.5.8 +pyflakes==2.2.0 +Pygments==2.15.0 +PyJWT==2.3.0 +pyparsing==2.2.0 +pyrsistent==0.18.0 +pyserial==3.4 +python-amazon-simple-product-api==2.2.11 python-dateutil==2.8.2 -social-auth-core==4.0.3 -social-auth-app-django==4.0.0 +python-dotenv==1.0.0 +python-jose==1.3.2 python-memcached==1.59 python-social-auth==0.2.21 +python-utils==2.2.0 +python3-openid==3.2.0 +python3-saml==1.16.0 pytz==2017.2 pywebpush==1.4.0 -PyJWT[crypto]==2.3.0 PyYAML==6.0 +recommonmark==0.4.0 +redis==2.10.6 regex==2022.3.2 requests==2.31.0 +requests-oauthlib==0.8.0 rollbar==0.16.1 +rsa==3.4.2 +ruamel.yaml==0.18.5 +ruamel.yaml.clib==0.2.8 +scikit-learn==0.24.1 scipy==1.10.0 selenium==4.1.3 +semly-webdriver-manager-fork==4.0.1 simplejson==3.11.1 +six==1.16.0 +sniffio==1.3.0 +snowballstemmer==1.2.1 +social-auth-app-django==4.0.0 +social-auth-core==4.0.3 +sortedcontainers==2.4.0 +South==1.0.2 +Sphinx==4.0.2 sphinx-autobuild==2021.3.14 sphinx-rtd-theme==0.5.2 +sphinxcontrib-applehelp==1.0.2 +sphinxcontrib-devhelp==1.0.2 +sphinxcontrib-htmlhelp==2.0.0 sphinxcontrib-inlinesyntaxhighlight==0.2 +sphinxcontrib-jsmath==1.0.1 +sphinxcontrib-qthelp==1.0.3 +sphinxcontrib-serializinghtml==1.1.5 sphinxcontrib-websupport==1.2.4 +sqlparse==0.4.1 +ssh-import-id==5.11 supervisor==4.2.2 -semly-webdriver-manager-fork==4.0.1 +threadpoolctl==2.2.0 +tomli==2.0.1 +toolz==0.11.1 +tornado==4.5.1 +tqdm==4.66.1 +trio==0.23.1 +trio-websocket==0.11.1 +typing_extensions==4.8.0 +tzdata==2023.3 +tzlocal==2.1 +uritemplate==3.0.0 +urllib3==1.24.1 +vine==5.1.0 +virtualenv==15.1.0 +watchdog==0.8.3 +wcwidth==0.2.9 +webencodings==0.5.1 +whitenoise==4.1.4 +wsproto==1.2.0 +xmlsec==1.3.13 +zipp==3.17.0 diff --git a/semesterly/settings.py b/semesterly/settings.py index e6676734e1..cc1a2c95bf 100644 --- a/semesterly/settings.py +++ b/semesterly/settings.py @@ -68,6 +68,38 @@ def get_secret(key): USE_X_FORWARDED_HOST = True +SOCIAL_AUTH_SAML_SP_ENTITY_ID = "http://jhu.semester.ly" + +SOCIAL_AUTH_SAML_SP_PUBLIC_CERT = get_secret("SOCIAL_AUTH_SAML_SP_PUBLIC_CERT") + +SOCIAL_AUTH_SAML_SP_PRIVATE_KEY = get_secret("SOCIAL_AUTH_SAML_SP_PRIVATE_KEY") + +SOCIAL_AUTH_SAML_ORG_INFO = { + "en-US": { + "name": "semesterly", + "displayname": "Semester.ly", + "url": "http://jhu.semester.ly", + } +} + +SOCIAL_AUTH_SAML_TECHNICAL_CONTACT = { + "givenName": "Semester.ly", + "emailAddress": "semester.ly@jh.edu", +} + +SOCIAL_AUTH_SAML_SUPPORT_CONTACT = { + "givenName": "Semester.ly", + "emailAddress": "semester.ly@jh.edu", +} + +SOCIAL_AUTH_SAML_ENABLED_IDPS = { + "jhu": { + "entity_id": "https://idp.jh.edu/idp/shibboleth", + "url": "https://idp.jh.edu/idp/profile/SAML2/Redirect/SSO", + "x509cert": get_secret("JHU_SAML_IDP_CERT"), + } +} + SOCIAL_AUTH_FACEBOOK_SCOPE = [ "email", "user_friends", @@ -104,6 +136,7 @@ def get_secret(key): "social_core.backends.google.GooglePlusAuth", "social_core.backends.google.GoogleOAuth2", "social_core.backends.azuread_tenant.AzureADTenantOAuth2", + "social_core.backends.saml.SAMLAuth", ) FIELDS_STORED_IN_SESSION = ["student_token", "login_hash"] @@ -229,6 +262,7 @@ def get_secret(key): "social_core.backends.google.GoogleOAuth2", "social_core.backends.twitter.TwitterOAuth", "social_core.backends.azuread_tenant.AzureADTenantOAuth2", + "social_core.backends.saml.SAMLAuth", "django.contrib.auth.backends.ModelBackend", ) diff --git a/static/js/redux/ui/modals/UserAcquisitionModal.tsx b/static/js/redux/ui/modals/UserAcquisitionModal.tsx index d8208ffec7..83e556f7a7 100644 --- a/static/js/redux/ui/modals/UserAcquisitionModal.tsx +++ b/static/js/redux/ui/modals/UserAcquisitionModal.tsx @@ -79,7 +79,7 @@ const UserAcquisitionModal = () => { className="btn abnb-btn secondary" onClick={() => { const link = document.createElement("a"); - link.href = `/login/azuread-tenant-oauth2/?student_token=${LoginToken}&login_hash=${LoginHash}`; + link.href = `/login/saml/?idp=jhu&student_token=${LoginToken}&login_hash=${LoginHash}`; document.body.appendChild(link); link.click(); }} From 12b516b01935fb8fbc599ff443cc4834b8b333e4 Mon Sep 17 00:00:00 2001 From: "Jiaqi (Jacky) Wang" Date: Fri, 12 Apr 2024 22:09:38 -0400 Subject: [PATCH 2/4] add command to install required linux deps --- Dockerfile | 3 + build/semesterly-base/Dockerfile | 2 - requirements.txt | 155 +++---------------------------- 3 files changed, 17 insertions(+), 143 deletions(-) diff --git a/Dockerfile b/Dockerfile index e77fd2f5e4..a52970ba42 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,6 +24,9 @@ COPY ./build/local_settings.py /code/semesterly/local_settings.py # Add parser script COPY ./build/run_parser.sh /code/run_parser.sh +RUN apt-get --allow-releaseinfo-change update +RUN apt install libxmlsec1 libxmlsec1-dev -y + RUN pip3 install -r /code/requirements.txt # Install package.json dependencies diff --git a/build/semesterly-base/Dockerfile b/build/semesterly-base/Dockerfile index 2444970a79..160b1c394b 100644 --- a/build/semesterly-base/Dockerfile +++ b/build/semesterly-base/Dockerfile @@ -14,7 +14,5 @@ RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - RUN apt-get install -y nodejs # This saves some build time by installing base requirements -RUN apt install libxmlsec1 libxmlsec1-dev - ADD ./requirements_base.txt /tmp RUN pip3 install -r /tmp/requirements_base.txt diff --git a/requirements.txt b/requirements.txt index 6bc3257fa0..22cf125567 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,188 +1,61 @@ +setuptools==65.5.1 +Pygments==2.15.0 +Sphinx==4.0.2 alabaster==0.7.10 -amqp==5.2.0 -anyjson==0.3.3 -argh==0.26.2 -asgiref==3.7.2 -asn1crypto==0.22.0 -attrs==21.2.0 -autopep8==1.3.2 -Babel==2.5.0 -backports.functools-lru-cache==1.4 -backports.zoneinfo==0.2.1 +argparse==1.4.0 beautifulsoup4==4.6.0 -billiard==3.6.4.0 -black==22.3.0 -bottlenose==1.1.3 +black==24.3.0 bs4==0.0.1 -caniusepython3==5.0.0 celery==5.2.2 -certifi==2017.7.27.1 -cffi==1.14.4 -chardet==3.0.4 -charset-normalizer==3.3.2 -click==8.1.7 -click-didyoumean==0.3.0 -click-plugins==1.1.1 -click-repl==0.3.0 -colorama==0.3.9 -CommonMark==0.5.4 -coreapi==2.3.3 -coreschema==0.0.4 coverage==6.3.2 -cryptography==41.0.4 +cryptography==41.0.6 dateparser==1.1.0 -defusedxml==0.5.0 -distlib==0.2.5 -distro==1.5.0 -dj-database-url==0.5.0 Django==3.2.20 django-cachalot==2.4.3 -django-celery==3.3.1 -django-celery-beat==1.0.0 -django-ckeditor==6.2.0 +django-ckeditor==6.2.0 +django-debug-toolbar==3.8.1 django-extensions==3.1.5 -django-js-asset==2.1.0 django-picklefield==3.0.1 -django-rest-swagger==2.2.0 django-webpack-loader==0.7.0 -django_debug_toolbar==3.8.1 djangorestframework==3.12.2 -docutils==0.14 drf-yasg==1.20.0 -ecdsa==0.13 -exceptiongroup==1.1.3 fake-useragent==1.1.1 -flake8==3.8.4 future==0.18.3 futures==3.1.1 fuzzywuzzy==0.15.1 -google-api-python-client==1.6.2 gunicorn==19.7.1 -h11==0.14.0 hashids==1.2.0 -html5lib==0.999999999 -http-ece==1.0.5 -httplib2==0.10.3 -idna==2.6 -imagesize==0.7.1 -importlib-metadata==6.8.0 -importlib-resources==6.1.1 -inflection==0.5.1 interruptingcow==0.7 -isodate==0.6.1 -itypes==1.1.0 -Jinja2==2.9.6 -joblib==1.0.1 jsondiff==1.1.1 -jsonfield==2.0.2 -jsonpatch==1.16 -jsonpointer==1.10 jsonschema==3.2.0 -kombu==5.3.3 -livereload==2.5.1 lxml==4.9.1 -Markdown==3.4.1 -MarkupSafe==1.1.1 -mccabe==0.6.1 +markdown==3.4.1 mock==2.0.0 -mypy-extensions==1.0.0 nltk==3.6.6 numpy==1.22.0 -oauth==1.0.1 oauth2client==4.1.2 -oauthlib==2.0.2 -openapi-codec==1.3.2 -outcome==1.3.0.post0 -packaging==16.8 -pathspec==0.11.2 -pathtools==0.1.2 -pbr==3.1.1 -pep8==1.7.0 -platformdirs==3.11.0 -port-for==0.3.1 -prettytable==0.7.2 progressbar2==3.34.2 -prompt-toolkit==3.0.39 -psycopg2==2.8.6 psycopg2-binary==2.8.6 -py-vapid==1.3.0 -pyasn1==0.3.2 -pyasn1-modules==0.0.11 pycodestyle==2.6.0 -pycparser==2.18 -pycrypto==2.6.1 -pyelliptic==1.5.8 -pyflakes==2.2.0 -Pygments==2.15.0 -PyJWT==2.3.0 -pyparsing==2.2.0 -pyrsistent==0.18.0 -pyserial==3.4 -python-amazon-simple-product-api==2.2.11 python-dateutil==2.8.2 -python-dotenv==1.0.0 -python-jose==1.3.2 +social-auth-core==4.0.3 +social-auth-app-django==4.0.0 python-memcached==1.59 -python-social-auth==0.2.21 -python-utils==2.2.0 -python3-openid==3.2.0 python3-saml==1.16.0 +python-social-auth==0.2.21 pytz==2017.2 pywebpush==1.4.0 +PyJWT[crypto]==2.3.0 PyYAML==6.0 -recommonmark==0.4.0 -redis==2.10.6 regex==2022.3.2 requests==2.31.0 -requests-oauthlib==0.8.0 rollbar==0.16.1 -rsa==3.4.2 -ruamel.yaml==0.18.5 -ruamel.yaml.clib==0.2.8 -scikit-learn==0.24.1 scipy==1.10.0 selenium==4.1.3 -semly-webdriver-manager-fork==4.0.1 simplejson==3.11.1 -six==1.16.0 -sniffio==1.3.0 -snowballstemmer==1.2.1 -social-auth-app-django==4.0.0 -social-auth-core==4.0.3 -sortedcontainers==2.4.0 -South==1.0.2 -Sphinx==4.0.2 sphinx-autobuild==2021.3.14 sphinx-rtd-theme==0.5.2 -sphinxcontrib-applehelp==1.0.2 -sphinxcontrib-devhelp==1.0.2 -sphinxcontrib-htmlhelp==2.0.0 sphinxcontrib-inlinesyntaxhighlight==0.2 -sphinxcontrib-jsmath==1.0.1 -sphinxcontrib-qthelp==1.0.3 -sphinxcontrib-serializinghtml==1.1.5 sphinxcontrib-websupport==1.2.4 -sqlparse==0.4.1 -ssh-import-id==5.11 supervisor==4.2.2 -threadpoolctl==2.2.0 -tomli==2.0.1 -toolz==0.11.1 -tornado==4.5.1 -tqdm==4.66.1 -trio==0.23.1 -trio-websocket==0.11.1 -typing_extensions==4.8.0 -tzdata==2023.3 -tzlocal==2.1 -uritemplate==3.0.0 -urllib3==1.24.1 -vine==5.1.0 -virtualenv==15.1.0 -watchdog==0.8.3 -wcwidth==0.2.9 -webencodings==0.5.1 -whitenoise==4.1.4 -wsproto==1.2.0 -xmlsec==1.3.13 -zipp==3.17.0 +semly-webdriver-manager-fork==4.0.1 From 56f9c85b7a96991c26aba2a2d2035a31ddeba0d2 Mon Sep 17 00:00:00 2001 From: "Jiaqi (Jacky) Wang" Date: Fri, 12 Apr 2024 22:52:03 -0400 Subject: [PATCH 3/4] try to fix CI --- .github/workflows/semesterly.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/semesterly.yml b/.github/workflows/semesterly.yml index fd5fa9fa4b..a3402f46f8 100644 --- a/.github/workflows/semesterly.yml +++ b/.github/workflows/semesterly.yml @@ -50,6 +50,8 @@ jobs: - name: Install Python Dependencies run: | + apt-get --allow-releaseinfo-change update + apt install libxmlsec1 libxmlsec1-dev -y python -m pip install --upgrade pip pip install -r requirements.txt From 1c40983b11d8c2890e764ba17ca2c2f61a6339cf Mon Sep 17 00:00:00 2001 From: "Jiaqi (Jacky) Wang" Date: Fri, 12 Apr 2024 22:54:29 -0400 Subject: [PATCH 4/4] add sudo to actions command --- .github/workflows/semesterly.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/semesterly.yml b/.github/workflows/semesterly.yml index a3402f46f8..b1ce88168b 100644 --- a/.github/workflows/semesterly.yml +++ b/.github/workflows/semesterly.yml @@ -50,8 +50,8 @@ jobs: - name: Install Python Dependencies run: | - apt-get --allow-releaseinfo-change update - apt install libxmlsec1 libxmlsec1-dev -y + sudo apt-get --allow-releaseinfo-change update + sudo apt install libxmlsec1 libxmlsec1-dev -y python -m pip install --upgrade pip pip install -r requirements.txt