Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mabcP-0002ir-Pn for pgadmin-hackers@arkaria.postgresql.org; Wed, 13 Oct 2021 10:36:17 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1mabcO-0004zX-P8 for pgadmin-hackers@arkaria.postgresql.org; Wed, 13 Oct 2021 10:36:16 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mZWIJ-0001D4-LT for pgadmin-hackers@lists.postgresql.org; Sun, 10 Oct 2021 10:43:03 +0000 Received: from mout01.posteo.de ([185.67.36.65]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mZWIA-0003ed-7R for pgadmin-hackers@postgresql.org; Sun, 10 Oct 2021 10:42:58 +0000 Received: from submission (posteo.de [89.146.220.130]) by mout01.posteo.de (Postfix) with ESMTPS id A9CB1240029 for ; Sun, 10 Oct 2021 12:42:52 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.de; s=2017; t=1633862572; bh=PIRUwi7S9ZQSbxxpj6ZhATodJAOmRSluMmNZOL7IjVo=; h=To:From:Subject:Autocrypt:Date:From; b=Mg9yr7IbZ53BLaV3lxYbZebW2Dngc5pOElFfaBhu5+1NtzcZpki+gbU2Kr3HDtksK f0TEJ3SZmvHzIiQrQYWe+PDz/JyFxu0NtIxERSIQIJyjxL43gPTluSHiqDCslJa5UN i5oFfKIAlR3DQuLVG5mZtG1cGkF7XrolkHqzSulz5KlsJi/EQN9QTzGcl9AITaHgWh CLhyhAH7mnyGdmja4gFouvc0JwYYrt1YkYExcYHF/axovgJfDhaSK4BO2v0UGZnKwK QsK+VGOUb57b3A8HMkUd0C5UfNaAjpbHmwQxT8zm+duvFT9Q4afp9KiQGl5z2/603/ cDy+rfUdujq+Q== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4HRz641YBMz9rxD for ; Sun, 10 Oct 2021 12:42:51 +0200 (CEST) To: pgadmin-hackers@postgresql.org From: Florian Sabonchi Subject: feature #6640 Autocrypt: addr=sabonchi@posteo.de; keydata= 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 Message-ID: <1d3c17a7-1721-ab4c-c1ef-d206fcd20870@posteo.de> Date: Sun, 10 Oct 2021 10:42:51 +0000 MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="LSMpTBDmT2V3KmfZKMlmb67nI73pa61xy" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --LSMpTBDmT2V3KmfZKMlmb67nI73pa61xy Content-Type: multipart/mixed; boundary="2yTJYXBnacxk4Snep0ER31Z2e9GweM85k"; protected-headers="v1" From: Florian Sabonchi To: pgadmin-hackers@postgresql.org Message-ID: <1d3c17a7-1721-ab4c-c1ef-d206fcd20870@posteo.de> Subject: feature #6640 --2yTJYXBnacxk4Snep0ER31Z2e9GweM85k Content-Type: multipart/mixed; boundary="------------74DCB0D2BDD72B687BAF6D77" Content-Language: en-US This is a multi-part message in MIME format. --------------74DCB0D2BDD72B687BAF6D77 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable Hi I have written a patch for feature #6640 --------------74DCB0D2BDD72B687BAF6D77 Content-Type: text/x-patch; charset=UTF-8; name="0001-first-draft-for-feature-6640.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0001-first-draft-for-feature-6640.patch" =46rom fd3978884501845099ca6547cd342ead0f833b14 Mon Sep 17 00:00:00 2001 From: Florian Sabonchi Date: Sun, 10 Oct 2021 12:38:50 +0200 Subject: [PATCH] first draft for feature #6640 --- docs/en_US/oauth2.rst | 1 + web/config.py | 2 ++ web/pgadmin/authenticate/oauth2.py | 19 +++++++++++++++++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/docs/en_US/oauth2.rst b/docs/en_US/oauth2.rst index 4cc2628f5..6cf2f5aba 100644 --- a/docs/en_US/oauth2.rst +++ b/docs/en_US/oauth2.rst @@ -36,6 +36,7 @@ and modify the values for the following parameters: "OAUTH2_AUTO_CREATE_USER", "Set the value to *True* if you want to a= utomatically create a pgAdmin user corresponding to a successfully authenticated = Oauth2 user. Please note that password is not stored in the pgAdmin database." + "ALLOWED_ORGANIZATIONS", "Github organizations which are allowed. If = the user is in an organization that is not in the list, logging in is not= possible." =20 Redirect URL =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D diff --git a/web/config.py b/web/config.py index 7a1f4ab1f..ec8ec0959 100644 --- a/web/config.py +++ b/web/config.py @@ -719,6 +719,8 @@ OAUTH2_CONFIG =3D [ 'OAUTH2_ICON': None, # UI button colour, ex: #0000ff 'OAUTH2_BUTTON_COLOR': None, + # Allowed github organizations + 'ALLOWED_ORGANIZATIONS': [''], } ] =20 diff --git a/web/pgadmin/authenticate/oauth2.py b/web/pgadmin/authenticat= e/oauth2.py index cc1143e06..866e12680 100644 --- a/web/pgadmin/authenticate/oauth2.py +++ b/web/pgadmin/authenticate/oauth2.py @@ -8,11 +8,12 @@ ########################################################################= ## =20 """A blueprint module implementing the Oauth2 authentication.""" +import requests as requests =20 import config =20 from authlib.integrations.flask_client import OAuth -from flask import current_app, url_for, session, request,\ +from flask import current_app, url_for, session, request, \ redirect, Flask, flash from flask_babelex import gettext from flask_security import login_user, current_user @@ -91,7 +92,6 @@ class OAuth2Authentication(BaseAuthentication): =20 def __init__(self): for oauth2_config in config.OAUTH2_CONFIG: - OAuth2Authentication.oauth2_config[ oauth2_config['OAUTH2_NAME']] =3D oauth2_config =20 @@ -130,6 +130,17 @@ class OAuth2Authentication(BaseAuthentication): =20 user, msg =3D self.__auto_create_user(profile) if user: + organizations =3D self.get_organizations(profile['organizati= ons_url']) + + for oauth2_config in config.OAUTH2_CONFIG: + allowed_organizations =3D oauth2_config['ALLOWED_ORGANIZ= ATIONS'] + if allowed_organizations: + for organization in organizations: + if organization['login'] not in allowed_organiza= tions: + return False, gettext("You are in an organiz= ation " + "that is not on the " + "whitelist") + user =3D db.session.query(User).filter_by( username=3Dprofile['email'], auth_source=3DOAUTH2).first= () current_app.login_manager.logout_view =3D \ @@ -137,6 +148,10 @@ class OAuth2Authentication(BaseAuthentication): return login_user(user), None return False, msg =20 + def get_organizations(self, organizations_url: str): + organizations =3D requests.get(organizations_url) + return organizations.json() + def get_user_profile(self): session['oauth2_token'] =3D self.oauth2_clients[ self.oauth2_current_client].authorize_access_token() --=20 2.25.1 --------------74DCB0D2BDD72B687BAF6D77 Content-Type: application/pgp-keys; name="OpenPGP_0x9B79A5A968AF5F8F.asc" Content-Transfer-Encoding: quoted-printable Content-Description: OpenPGP public key Content-Disposition: attachment; filename="OpenPGP_0x9B79A5A968AF5F8F.asc" -----BEGIN PGP PUBLIC KEY BLOCK----- xsDNBGAYfy0BDADJ5R14gK3xoGCkFPFKF4uoNwXFc8AA/AE6+pMbbZv730AJFCnkH/jhGR1tz= LMT l6tQGT7/EtUIrietvEYPYLKNL5wUo5TPIa0qGg7DbsKaeqX7+6/GCSQcLf7HhcS4W87J9ba67= 1Pd TgmxNGw+v1kGnzNNKleDphEli5eqCOHMV1KliArrtCZa1H6jar9XUyp1XkQ+ubEIf+LeE4nJl= mP/ 1JU52tm8EEpRNxqx2tZ+XMPrZ6sciiT8xRNH+DyXWp0TbwWW1GfcDEdG8yUVuN1YzNlBO69oL= rLT 4yw0vN6odmTipIVBeMwcRibGXevwidK1yNNoTvNuHqxlK+fG0IupbMSnl0eroR2ykhd+euXxH= N8o thlgU6f73VZNpNJTvuUJFrtexBuC1EWuBFqTYpEKttszaF3a7SPsHhayJERSTOaJ3GkxFO3Rv= DQh +mzQ86MvFxz2HeovPlGmJ4BEPQx2526ORJg0bW8Xk7ew9zgUoZiurA80hH3i5lCJluU1VtkAE= QEA Ac0rRmxvcmlhbiBKYWZhciBTYWJvbmNoaSA8c2Fib25jaGlAcG9zdGVvLmRlPsLBFAQTAQoAP= hYh BPjrSDhVc5p9/V6N/Zt5palor1+PBQJgGH8tAhsDBQkDwccDBQsJCAcCBhUKCQgLAgQWAgMBA= h4B AheAAAoJEJt5palor1+P4VwMAINDxB+jya1kTddCsJ4+sCFrBAZOTU36WzUz0gdtk4M0gaZgB= dF6 dJ5V9YKcWlDkqIXIdL/s4wyYP4tns8ms3aUVKeEOPUW6+kXKjdLeJ61EjoyRW+RnzpSW88u+b= mT0 mX5c9tNZnW7KCtNSInnYjRM+UZaMWxNRIFrvcC4qBGO1qq69bEPray8LmMYtP2na27p59cnj2= GTp 01DVci5cu7k+WR/2oAgaEAeYPIGs9622Ln3hZDP/iq8oBquO6PYjoO94bTn/NT+CO6WPGcSFa= ymP +qFF3OvDWZLut+FlBc1+EPeKzfMtU/Vadn+iejkfwmBHBenIPGcYA3/xEGM+s6FelDo7yMGYz= OFU /DWw7+UslpiylgmVgaMNv/sB29swlRC98D4YvvBRmnyKdPw3oq3XE+YSjLeaJVONcWUSUTToT= HDF DnkHirzg7QBnE7Cax4nnON8RDC5siXXqOlUH8DelAz3/9ic10O3tRTCTQoamZbXPnwfjEg23o= 2se WMap7c7AzQRgGH8tAQwA5GXoqeVSYJP3nXTcghvEXJ1B8GYkwscVmQBIg66Hv8XbMaf7VYhgR= /xG 34FkZQ00zZKAYaV7qP6Su/lB6tAUl6z3WofdHLS9amDdN1A7eCOcsZRKTR8ybXeHkCk0ZLnNV= ZKN DTDMMAUDJTpc+doZQY7qJi9Sj0ai0eF1RAtcTvlRLsEiuhquwnV/6HqT9h/657oY0zDPhoj/L= kkF 2s1vvhNo4Dofmx0N5He0bNoCdWAOh6LiWdoD66q5gPeSYdHv1klthbAHiqK9yIZnILJMB+Mtm= DvE j9BLuyFU5IBDn7X/uxKEsSlpKlCSaXwBKS8nd+6ToBqGvqZ8cZvphv36wGJ8s3zGyb0KviP1o= iG5 OhjNMyEDNEWH2GXig3Z2rRVl8Zdr5ScXmt6lYZIVIrfT2mXdBOSk/eePB935slk9xf1DuTULD= AXK MDzXyz4JEVb9W4Jm0xywRxAeX+9/M0UBIzZjsiYBUx0IlXyF2067ElFSocxiighxjcYpIqdgp= jYZ ABEBAAHCwPwEGAEKACYWIQT460g4VXOaff1ejf2beaWpaK9fjwUCYBh/LQIbDAUJA8HHAwAKC= RCb eaWpaK9fj3ILDACBeItnYGcOkYC4RmGdwdX8uEBb9xEiTROiRfGWwSXiSinoG8NxGZTzKa4mA= Dhn EtYlexuGDL3Y1c+jx/6R/2z+b7g4UHLEoO7XRP5ye78Doxp13VWN3pGqELJSp7Z/3LADICVdA= 0v9 im0gUPsfB2jx823lACj037qzBebXM8TdB6j3SNGmLXetZAWMs2Az8ZbBOil91RpP5FjKjNiZP= goN B0s+RrSf/B4/3wd/05sRnboeETFZr0OlIvXy25hmaJbgrkDYTOFdde5sIVsX366i3lPcyF9zw= J0b aQ2xQtJe2vgYyCSDEETtiMftVHbT0rdiphLJ6GTbKzHVAieYKRcHEMnfqEoXOlDwY6WpFIuwk= /l6 R3ww9EqXDossi4tosCNWYFqPf/Zb5pTTnEBK9doKmmuC9Llg5UGOxwalNBgt+IgvDyiX/mR5Z= 3ut 7wKI3aSrwOnNEkM2sGDoVz394QjCltB2dM8z/0CD80kiuiqtw5c/3otP8GYX29aTRjHWQgc=3D= =3DbkqS -----END PGP PUBLIC KEY BLOCK----- --------------74DCB0D2BDD72B687BAF6D77-- --2yTJYXBnacxk4Snep0ER31Z2e9GweM85k-- --LSMpTBDmT2V3KmfZKMlmb67nI73pa61xy Content-Type: application/pgp-signature; name="OpenPGP_signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="OpenPGP_signature" -----BEGIN PGP SIGNATURE----- wsD5BAABCAAjFiEE+OtIOFVzmn39Xo39m3mlqWivX48FAmFiw6sFAwAAAAAACgkQm3mlqWivX4/G /Qv/aFgM+WZSUWn7Fcf+gpwXx+QOURjiYYH13bTBK+rdp76ONCIA7VPQ435NuJIJfiDLptTBdgqw dZ0VqP9ZCfL4gZQqFKhjyXySt6Si42KfwgtroxuFMtDPvHpjvWnyGrmXbGPwUc92u42KZSXbs6da dd3H6EI4H2tRITXcekqyVHywXglbuOkAOBmJZF6FlX9pDSdRhF8NmHEXdXJ2pk49xnSC4ZpAbaBV a9AEF0tAFo+ocOxKVy2l9xv018II8iZXe0yRdwW8nQeSkLtsNPg5gFsvh0/P6NvET71hqPPUR6SI rikTxHnKXaRi1Z+akQz6tqxqD3xoDK+COzKvspAkbHnFh3wjxQfqm1GU4AsC+PigzbhOip3WS9DF 7DSKgJwGRleFA5NCXtSJJYGInm4fj9uux2kkASetrt/MPNhIN//avW8ScaJ3dOIU7aNNN+ofP2E4 f8Nyu+W79VytDX7AEZ83gn2LH2JFjH8Y7xaCzyVZRey3je0kZhftHX6XSA4g =m8Hw -----END PGP SIGNATURE----- --LSMpTBDmT2V3KmfZKMlmb67nI73pa61xy--