diff --git a/llmstack/server/adapters.py b/llmstack/server/adapters.py index 904e5673ddc..8aeb2efe43c 100644 --- a/llmstack/server/adapters.py +++ b/llmstack/server/adapters.py @@ -35,3 +35,17 @@ def populate_user(self, request, sociallogin, data): user.email = user.username return user + + def pre_social_login(self, request, sociallogin): + if sociallogin.is_existing: + return + + user = sociallogin.user + + if not user.username: + user.username = user.email + + if not user.email: + user.email = user.username + + sociallogin.connect(request, user) diff --git a/llmstack/server/settings.py b/llmstack/server/settings.py index f9feea2e7cc..9917466a3be 100644 --- a/llmstack/server/settings.py +++ b/llmstack/server/settings.py @@ -584,6 +584,80 @@ }, } +ENABLE_SAML_SOCIALACCOUNT = os.getenv("ENABLE_SAML_SOCIALACCOUNT", "False") == "True" +if ENABLE_SAML_SOCIALACCOUNT: + SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") + + if "allauth.socialaccount.providers.saml" not in INSTALLED_APPS: + INSTALLED_APPS.append("allauth.socialaccount.providers.saml") + + """ + SAMPLE CONFIG from .bashrc/.zshrc. x509cert is configure in a separate env variable + + ```bash + export SAML_APP_NAME="Test Org Inc" + export SAML_APP_CLIENT_ID="test-org-inc" + export SAML_APP_TENANT_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + export SAML_APP_CONFIG=$(cat <=1.7", extras = ["crypto"]} python3-openid = ">=3.0.8" +python3-saml = {version = ">=1.15.0,<2.0.0", optional = true, markers = "extra == \"saml\""} requests = ">=2.0.0" requests-oauthlib = ">=0.3.0" @@ -2446,6 +2447,20 @@ typing_extensions = "*" [package.extras] aws = ["boto3"] +[[package]] +name = "isodate" +version = "0.6.1" +description = "An ISO 8601 date/time/duration parser and formatter" +optional = false +python-versions = "*" +files = [ + {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, + {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, +] + +[package.dependencies] +six = "*" + [[package]] name = "itemadapter" version = "0.8.0" @@ -5103,6 +5118,26 @@ defusedxml = "*" mysql = ["mysql-connector-python"] postgresql = ["psycopg2"] +[[package]] +name = "python3-saml" +version = "1.16.0" +description = "Saml Python Toolkit. Add SAML support to your Python software using this library" +optional = false +python-versions = "*" +files = [ + {file = "python3-saml-1.16.0.tar.gz", hash = "sha256:97c9669aecabc283c6e5fb4eb264f446b6e006f5267d01c9734f9d8bffdac133"}, + {file = "python3_saml-1.16.0-py2-none-any.whl", hash = "sha256:c49097863c278ff669a337a96c46dc1f25d16307b4bb2679d2d1733cc4f5176a"}, + {file = "python3_saml-1.16.0-py3-none-any.whl", hash = "sha256:20b97d11b04f01ee22e98f4a38242e2fea2e28fbc7fbc9bdd57cab5ac7fc2d0d"}, +] + +[package.dependencies] +isodate = ">=0.6.1" +lxml = ">=4.6.5,<4.7.0 || >4.7.0" +xmlsec = ">=1.3.9" + +[package.extras] +test = ["coverage (>=4.5.2)", "flake8 (>=3.6.0,<=5.0.0)", "freezegun (>=0.3.11,<=1.1.0)", "pytest (>=4.6)"] + [[package]] name = "pytz" version = "2022.7.1" @@ -7917,6 +7952,31 @@ files = [ {file = "XlsxWriter-3.2.0.tar.gz", hash = "sha256:9977d0c661a72866a61f9f7a809e25ebbb0fb7036baa3b9fe74afcfca6b3cb8c"}, ] +[[package]] +name = "xmlsec" +version = "1.3.13" +description = "Python bindings for the XML Security Library" +optional = false +python-versions = ">=3.5" +files = [ + {file = "xmlsec-1.3.13-cp310-cp310-win32.whl", hash = "sha256:2174e8c88555383322d8b7d3927490a92ef72ad72a6ddaf4fa1b96a3f27c3e90"}, + {file = "xmlsec-1.3.13-cp310-cp310-win_amd64.whl", hash = "sha256:46d1daf16a8f4430efca5bb9c6a15776f2671f69f48a1941d6bb335e6f8cb29d"}, + {file = "xmlsec-1.3.13-cp35-cp35m-win32.whl", hash = "sha256:d47062c42775a025aa94fb8b15de97c1db86e301e549d3168157e0b1223d51b1"}, + {file = "xmlsec-1.3.13-cp35-cp35m-win_amd64.whl", hash = "sha256:7c7e8ef52688ddaf5b66750cc8d901f61716f46727014ff012f41d8858cedeb0"}, + {file = "xmlsec-1.3.13-cp36-cp36m-win32.whl", hash = "sha256:1725d70ee2bb2cd8dd66c7a7451be02bb59dc8280103db4f68e731f00135b1e0"}, + {file = "xmlsec-1.3.13-cp36-cp36m-win_amd64.whl", hash = "sha256:1f8c41162152d7086fd459926e61bc7cb2d52ffc829e760bf8b2c221a645d568"}, + {file = "xmlsec-1.3.13-cp37-cp37m-win32.whl", hash = "sha256:ff1c61f296e75cba5bac802d0000bfde09143eed946ced1a5162211867c335f8"}, + {file = "xmlsec-1.3.13-cp37-cp37m-win_amd64.whl", hash = "sha256:d249c0a2bf3ff13a231bca6a588e7d276b3f1e2cf09316b542f470a63855799e"}, + {file = "xmlsec-1.3.13-cp38-cp38-win32.whl", hash = "sha256:56cfcf3487b6ad269eb1fb543c04dee2c101f1bc91e06d6cf7bfab9ac486efd8"}, + {file = "xmlsec-1.3.13-cp38-cp38-win_amd64.whl", hash = "sha256:e6626bece0e97a8598b5df28c27bc6f2ae1e97d29dca3c1a4910a7598a4d1d0f"}, + {file = "xmlsec-1.3.13-cp39-cp39-win32.whl", hash = "sha256:091f23765729df6f3b3a55c8a6a96f9c713fa86e76b86a19cdb756aaa6dc0646"}, + {file = "xmlsec-1.3.13-cp39-cp39-win_amd64.whl", hash = "sha256:5162f416179350587c4ff64737af68a846a9b86f95fd465df4e68b589ce56618"}, + {file = "xmlsec-1.3.13.tar.gz", hash = "sha256:916f5d78e8041f6cd9391abba659da8c94a4fef7196d126d40af1ff417f2cf86"}, +] + +[package.dependencies] +lxml = ">=3.8" + [[package]] name = "yamlordereddictloader" version = "0.4.2" @@ -8129,4 +8189,4 @@ networking = ["junos-eznc"] [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "964bdad489131c6913edf63b94884298beb605f6fde1c990b27a20b637d0c60f" +content-hash = "fdfb51b9e81128d387aca386020426d382a9c3620a43b27d2b6df649693c85d6" diff --git a/pyproject.toml b/pyproject.toml index 20a06fda186..3a032f21737 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -151,7 +151,7 @@ optional = false [tool.poetry.group.server.dependencies] django = {version = "5.0", python = ">=3.10,<3.12" } -django-allauth = {version = "^0.61.1", allow-prereleases = true} +django-allauth = {version = "^0.61.1", allow-prereleases = true, extras = ["saml"]} django-environ = {version = "^0.10.0", allow-prereleases = true} django-picklefield = {version = "^3.1", allow-prereleases = true} django-redis = {version = "^5.2.0", allow-prereleases = true}