1313from pgadmin .authenticate .registry import AuthSourceRegistry
1414from unittest .mock import patch , MagicMock
1515from pgadmin .authenticate import AuthSourceManager
16- from pgadmin .utils .constants import OAUTH2 , LDAP , INTERNAL
16+ from pgadmin .utils .constants import OAUTH2 , INTERNAL
1717
1818
1919class Oauth2LoginMockTestCase (BaseTestGenerator ):
@@ -33,18 +33,23 @@ class Oauth2LoginMockTestCase(BaseTestGenerator):
3333 oauth2_provider = 'github' ,
3434 flag = 2
3535 )),
36- ('Oauth2 Authentication' , dict (
36+ ('Oauth2 Additional Claims Authentication' , dict (
3737 auth_source = ['oauth2' ],
3838 oauth2_provider = 'auth-with-additional-claim-check' ,
3939 flag = 3
4040 )),
41+ ('Oauth2 PKCE Support' , dict (
42+ auth_source = ['oauth2' ],
43+ oauth2_provider = 'keycloak-pkce' ,
44+ flag = 4
45+ )),
4146 ]
4247
4348 @classmethod
4449 def setUpClass (cls ):
4550 """
4651 We need to logout the test client as we are testing
47- spnego/kerberos login scenarios.
52+ OAuth2 login scenarios.
4853 """
4954 cls .tester .logout ()
5055
@@ -63,7 +68,7 @@ def setUp(self):
6368 'https://github.com/login/oauth/authorize' ,
6469 'OAUTH2_API_BASE_URL' : 'https://api.github.com/' ,
6570 'OAUTH2_USERINFO_ENDPOINT' : 'user' ,
66- 'OAUTH2_SCOPE' : 'email profile' ,
71+ 'OAUTH2_SCOPE' : 'openid email profile' ,
6772 'OAUTH2_ICON' : 'fa-github' ,
6873 'OAUTH2_BUTTON_COLOR' : '#3253a8' ,
6974 },
@@ -82,9 +87,30 @@ def setUp(self):
8287 'OAUTH2_ICON' : 'briefcase' ,
8388 'OAUTH2_BUTTON_COLOR' : '#0000ff' ,
8489 'OAUTH2_ADDITIONAL_CLAIMS' : {
85- 'groups' : ['123' ,'456' ],
90+ 'groups' : ['123' , '456' ],
8691 'wids' : ['789' ]
8792 }
93+ },
94+ {
95+ 'OAUTH2_NAME' : 'keycloak-pkce' ,
96+ 'OAUTH2_DISPLAY_NAME' : 'Keycloak with PKCE' ,
97+ 'OAUTH2_CLIENT_ID' : 'testclientid' ,
98+ 'OAUTH2_CLIENT_SECRET' : 'testclientsec' ,
99+ 'OAUTH2_TOKEN_URL' :
100+ 'https://keycloak.org/auth/realms/TEST-REALM/protocol/'
101+ 'openid-connect/token' ,
102+ 'OAUTH2_AUTHORIZATION_URL' :
103+ 'https://keycloak.org/auth/realms/TEST-REALM/protocol/'
104+ 'openid-connect/auth' ,
105+ 'OAUTH2_API_BASE_URL' :
106+ 'https://keycloak.org/auth/realms/TEST-REALM' ,
107+ 'OAUTH2_USERINFO_ENDPOINT' : 'user' ,
108+ 'OAUTH2_SCOPE' : 'openid email profile' ,
109+ 'OAUTH2_SSL_CERT_VERIFICATION' : True ,
110+ 'OAUTH2_ICON' : 'fa-black-tie' ,
111+ 'OAUTH2_BUTTON_COLOR' : '#3253a8' ,
112+ 'OAUTH2_CHALLENGE_METHOD' : 'S256' ,
113+ 'OAUTH2_RESPONSE_TYPE' : 'code' ,
88114 }
89115 ]
90116
@@ -101,6 +127,8 @@ def runTest(self):
101127 self .test_oauth2_authentication ()
102128 elif self .flag == 3 :
103129 self .test_oauth2_authentication_with_additional_claims_success ()
130+ elif self .flag == 4 :
131+ self .test_oauth2_authentication_with_pkce ()
104132
105133 def test_external_authentication (self ):
106134 """
@@ -184,6 +212,32 @@ def test_oauth2_authentication_with_additional_claims_success(self):
184212 respdata = 'Gravatar image for %s' % profile ['email' ]
185213 self .assertTrue (respdata in res .data .decode ('utf8' ))
186214
215+ def test_oauth2_authentication_with_pkce (self ):
216+ """
217+ Ensure that when PKCE parameters are configured, they are passed
218+ to the OAuth client registration as part of client_kwargs, and that
219+ the default client_kwargs is correctly included.
220+ """
221+
222+ with patch ('pgadmin.authenticate.oauth2.OAuth.register' ) as \
223+ mock_register :
224+ from pgadmin .authenticate .oauth2 import OAuth2Authentication
225+
226+ OAuth2Authentication ()
227+
228+ args , kwargs = mock_register .call_args
229+ client_kwargs = kwargs .get ('client_kwargs' , {})
230+
231+ # Check that PKCE and default client_kwargs are included
232+ self .assertEqual (
233+ client_kwargs .get ('code_challenge_method' ), 'S256' )
234+ self .assertEqual (
235+ client_kwargs .get ('response_type' ), 'code' )
236+ self .assertEqual (
237+ client_kwargs .get ('scope' ), 'openid email profile' )
238+ self .assertEqual (
239+ client_kwargs .get ('verify' ), 'true' )
240+
187241 def mock_user_profile_with_additional_claims (self ):
188242 profile = {'email' : 'oauth2@gmail.com' , 'wids' : ['789' ]}
189243
0 commit comments