Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tent): support additional params #4044

Merged
merged 13 commits into from
Mar 13, 2023
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion demos/jans-tent/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#auth-client-tdd-specific
clientapp/config.py
clientapp/client_secrets.json

# Byte-compiled / optimized / DLL files
Expand Down
9 changes: 6 additions & 3 deletions demos/jans-tent/clientapp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,10 @@ def login():
query_args['acr_values'] = cfg.ACR_VALUES

if cfg.PROVIDER_HOST_STRING is not None:
query_args["providerHost"] = get_provider_host()
query_args["providerHost"] = get_provider_host()

if cfg.ADDITIONAL_PARAMS is not None:
query_args |= cfg.ADDITIONAL_PARAMS

response = oauth.op.authorize_redirect(**query_args)

Expand Down Expand Up @@ -218,8 +221,8 @@ def callback():
except Exception as error:
print('exception!')
print(error)
app.logger.error(error)
return {'error': error}, 400
app.logger.error(str(error))
return {'error': str(error)}, 400

@app.route("/configuration", methods=["POST"])
def configuration():
Expand Down
19 changes: 7 additions & 12 deletions demos/jans-tent/clientapp/client_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
limitations under the License.
'''


from flask_oidc import registration, discovery
import json
from httplib2 import RelativeURIError
Expand All @@ -27,7 +26,7 @@ class ClientHandler:
__client_url = None
__client_id = None
__client_secret = None
__metadata_url= None
__metadata_url = None
__op_url = None
op_data = None

Expand All @@ -43,23 +42,20 @@ def __init__(self, op_url: str, client_url: str):
self.__client_url = client_url
self.__metadata_url = '%s/.well-known/openid-configuration' % op_url
self.op_data = self.discover(op_url)
self.reg_info = self.register_client(op_data=self.op_data,client_url=client_url)
self.reg_info = self.register_client(op_data=self.op_data, client_url=client_url)
self.__client_id = self.reg_info['web']['client_id']
self.__client_secret = self.reg_info['web']['client_secret']



def get_client_dict(self) -> dict:
r = {
'op_metadata_url' : self.__metadata_url,
'client_id' : self.__client_id,
'client_secret' : self.__client_secret
'op_metadata_url': self.__metadata_url,
'client_id': self.__client_id,
'client_secret': self.__client_secret
}

return r


def register_client(self, op_data: Optional[dict]=op_data, client_url: Optional[str]=__client_url) -> dict:
def register_client(self, op_data: Optional[dict] = op_data, client_url: Optional[str] = __client_url) -> dict:
"""[register client and returns client information]

:param op_data: [description]
Expand All @@ -73,7 +69,7 @@ def register_client(self, op_data: Optional[dict]=op_data, client_url: Optional[
reg_info = registration.register_client(op_data, [redirect_uri])
return reg_info

def discover(self, op_url: Optional[str]=__op_url, disc:discovery=discovery) -> dict :
def discover(self, op_url: Optional[str] = __op_url, disc: discovery = discovery) -> dict:
"""Discover op information on .well-known/open-id-configuration
:param op_url: [description], defaults to __op_url
:type op_url: str, optional
Expand All @@ -98,4 +94,3 @@ def discover(self, op_url: Optional[str]=__op_url, disc:discovery=discovery) ->
print('An unexpected ocurred: %s' % e)

return op_data

52 changes: 52 additions & 0 deletions demos/jans-tent/clientapp/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
'''
Project: Test Auth Client
Author: Christian Hawk
Copyright 2023 Christian Hawk

Licensed under the Apache License, Version 2.0 (the 'License');
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an 'AS IS' BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
'''

CLIENT_ID = "YOUR-CLIENT-ID"
CLIENT_SECRET = "YOUR-CLIENT-SECRET"
SERVER_META_URL = 'https://YOUR_OP_HOST/.well-known/openid-configuration'
REDIRECT_URIS = [
'https://localhost:9090/oidc_callback'
]

USERINFO_URI = "https://your-userinfo-endpoint"

ISSUER = "https://your-server-fqdn"


# Token authentication method can be
# client_secret_basic
# client_secret_post
# none

SERVER_TOKEN_AUTH_METHOD = "client_secret_post"

# for gluu
ACR_VALUES = 'agama'
PRE_SELECTED_PROVIDER = False
PRE_SELECTED_PROVIDER_ID = ''
HAS_PROVIDER_HOST = False
PROVIDER_HOST_STRING = None

# ADDITIONAL PARAMS TO CALL AUTHORIZE ENDPOINT, WITHOUT BASE64 ENCODING. USE DICT {'param': 'value'}
# ADDITIONAL_PARAMS = {'paramOne': 'valueOne', 'paramTwo': 'valueTwo'}
ADDITIONAL_PARAMS = None


# SYSTEM SETTINGS
# use with caution, unsecure requests, for develpment environments
SSL_VERIFY = False
6 changes: 3 additions & 3 deletions demos/jans-tent/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ astroid==2.12.5
asttokens==2.0.8
async-generator==1.10
attrs==22.1.0
Authlib==1.0.1
Authlib==1.2.0
autopep8==1.7.0
backcall==0.2.0
bandit==1.7.4
behave==1.2.6
certifi==2022.6.15
certifi==2022.12.7
cffi==1.15.1
chardet==5.0.0
charset-normalizer==2.1.1
Expand All @@ -26,7 +26,7 @@ flask-oidc==1.4.0
gitdb==4.0.9
GitPython==3.1.27
h11==0.13.0
httplib2==0.20.4
httplib2==0.21.0
idna==3.3
importlib-metadata==4.12.0
iniconfig==1.1.1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from unittest import TestCase


import clientapp
import helper
import os
Expand All @@ -8,7 +10,6 @@
import inspect



class TestRegisterEndpoint(TestCase):

def setUp(self):
Expand All @@ -17,17 +18,22 @@ def setUp(self):
self.app_context = self.app.test_request_context()
self.app_context.push()
self.client = self.app.test_client()
#self.oauth = OAuth(self.app)
# self.oauth = OAuth(self.app)
os.environ['AUTHLIB_INSECURE_TRANSPORT'] = "1"
# stashing to restore on teardown
self.CHd = ClientHandler.discover
self.register = ClientHandler.register_client

ClientHandler.discover = MagicMock(name='discover')
# discover will always return a valid data
ClientHandler.discover.return_value = helper.OP_DATA_DICT_RESPONSE
ClientHandler.register_client = MagicMock(name='register_client')
ClientHandler.register_client.return_value = helper.REGISTER_CLIENT_RESPONSE

def tearDown(self):
# restoring original method from stash
ClientHandler.discover = self.CHd
ClientHandler.register_client = self.register

def test_if_app_has_register_endpoint(self):
self.assertIn(
Expand All @@ -52,26 +58,25 @@ def test_if_endpoint_accepts_post(self):
def test_endpoint_should_return_valid_req(self):
self.assertIn(
self.client.post(url_for('register')).status_code,
range(100,511),
range(100, 511),
'/register returned invalid requisition'
)

@patch('clientapp.client_handler.ClientHandler.__init__', MagicMock(return_value = None))
@patch('clientapp.client_handler.ClientHandler.__init__', MagicMock(return_value=None))
def test_endpoint_should_init_client_handler(self):
self.client.post(url_for('register'), json={
'op_url' : 'https://test.com',
'client_url' : 'https://clienttoberegistered.com'
'op_url': 'https://test.com',
'client_url': 'https://clienttoberegistered.com'
})
ClientHandler.__init__ .assert_called_once()
ClientHandler.__init__.assert_called_once()


@patch('clientapp.client_handler.ClientHandler.__init__', MagicMock(return_value = None))
@patch('clientapp.client_handler.ClientHandler.__init__', MagicMock(return_value=None))
def test_endpoint_should_accept_2_params(self):
firstValue = 'https://op'
secondValue = 'https://client.com.br'
self.client.post(url_for('register'), json={
'op_url' : firstValue,
'client_url' : secondValue
'op_url': firstValue,
'client_url': secondValue
})
ClientHandler.__init__.assert_called_once_with(firstValue, secondValue)

Expand All @@ -85,47 +90,46 @@ def test_endpoint_should_return_error_code_400_if_no_data_sent(self):
def test_should_return_400_error_if_no_needed_keys_provided(self):
self.assertEqual(
self.client.post(url_for('register'), json={
'other_key' : 'othervalue',
'another_key' : 'another_value'
}).status_code,
'other_key': 'othervalue',
'another_key': 'another_value'
}).status_code,
400,
'not returning 400 code if no needed keys provided'
)

def test_should_return_400_if_values_are_not_valid_urls(self):
self.assertEqual(
self.client.post(url_for('register'), json={
'op_url' : 'not_valid_url',
'client_url' : 'also_not_valid_url'
'op_url': 'not_valid_url',
'client_url': 'also_not_valid_url'
}).status_code,
400,
'not returning status 400 if values are not valid urls'
)


@patch('clientapp.client_handler.ClientHandler.get_client_dict', MagicMock(return_value = None))
@patch('clientapp.client_handler.ClientHandler.get_client_dict', MagicMock(return_value=None))
def test_valid_post_should_should_call_get_client_dict_once(self):
op_url = 'https://op.com.br'
client_url = 'https://client.com.br'
self.client.post(url_for('register'), json = {
'op_url' : op_url,
'client_url' : client_url
})
self.client.post(url_for('register'), json={
'op_url': op_url,
'client_url': client_url
})
ClientHandler.get_client_dict.assert_called_once()

def test_should_should_return_200_if_registered(self):
op_url = 'https://op.com.br'
client_url = 'https://client.com.br'
test_client_id = '1234-5678-9ten11'
test_client_secret = 'mysuperprotectedsecret'
with patch.object(ClientHandler, 'get_client_dict', return_value = {
'op_metadata_url' : '%s/.well-known/open-id-configuration' % op_url,
'client_id' : test_client_id,
'client_secret' : test_client_secret
with patch.object(ClientHandler, 'get_client_dict', return_value={
'op_metadata_url': '%s/.well-known/open-id-configuration' % op_url,
'client_id': test_client_id,
'client_secret': test_client_secret
}) as get_client_dict:
response = self.client.post(url_for('register'), json = {
'op_url' : op_url,
'client_url' : client_url
response = self.client.post(url_for('register'), json={
'op_url': op_url,
'client_url': client_url
})
self.assertEqual(response.status_code, 200)
get_client_dict.reset()
Expand All @@ -138,32 +142,17 @@ def test_should_return_expected_keys(self):

expected_keys = {'op_metadata_url', 'client_id', 'client_secret'}

with patch.object(ClientHandler, 'get_client_dict', return_value = {
'op_metadata_url' : '%s/.well-known/open-id-configuration' % op_url,
'client_id' : test_client_id,
'client_secret' : test_client_secret
with patch.object(ClientHandler, 'get_client_dict', return_value={
'op_metadata_url': '%s/.well-known/open-id-configuration' % op_url,
'client_id': test_client_id,
'client_secret': test_client_secret
}) as get_client_dict:
response = self.client.post(url_for('register'), json = {
'op_url' : op_url,
'client_url' : client_url
response = self.client.post(url_for('register'), json={
'op_url': op_url,
'client_url': client_url
})
self.assertTrue(
expected_keys <= response.json.keys(),
'endpoint not returning expected keys'
)
get_client_dict.reset()















Loading