Skip to content
This repository has been archived by the owner on May 9, 2022. It is now read-only.

Commit

Permalink
Consentire avvio in modalità headless (con login automatico) - Rimoss…
Browse files Browse the repository at this point in the history
…a necessità di inviare anche la password. Invio di un'asserzione di fallimento nel caso in cui l'utente non esiste
  • Loading branch information
lussoluca committed Aug 10, 2018
1 parent 7186fc2 commit decd029
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 31 deletions.
85 changes: 54 additions & 31 deletions testenv/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
SIGN_ALG, SPID_LEVELS, spid_error_table)
from testenv.spid import SpidPolicy, SpidServer, ac_factory
from testenv.users import JsonUserManager
from testenv.users import AutoLoginJsonUserManager
from testenv.utils import get_spid_error, prettify_xml

try:
Expand Down Expand Up @@ -89,6 +90,7 @@ def __init__(self, app, config, *args, **kwargs):
# bind Flask app
self.app = app
self.user_manager = JsonUserManager(config=config)
self.auto_login_user_manager = AutoLoginJsonUserManager(config=config)
# setup
self._config = config
self.app.secret_key = 'sosecret'
Expand Down Expand Up @@ -534,12 +536,12 @@ def single_sign_on_service(self):
session['relay_state'] = relay_state

if "auto_login" in saml_msg:
username, password = saml_msg['auto_login'].split('$$')
return self._auto_login(username, password), 200
username = saml_msg['auto_login']
return self._auto_login(username), 200

return redirect(url_for('login'))

def _auto_login(self, username, password):
def _auto_login(self, username):
"""
Returns an AuthnResponse for the specific username bypassing the login form
"""
Expand All @@ -560,17 +562,24 @@ def from_session(key):
spid_level = authn_context.authn_context_class_ref[0].text

# verify user credentials
user_id, user = self.user_manager.get(
user_id, user = self.auto_login_user_manager.get(
username,
password,
'', # no need for password with auto_login_user_manager
sp_id
)
if user_id is not None:
# setup response
http_args, response, identity = self._setup_response(user, user_id, spid_level, message, destination,
sp_id, relay_state)
http_args, response, identity = self._setup_success_response(user, user_id, spid_level, message, destination,
sp_id, relay_state)

# Return response
# return response
return http_args['data']
else:
# setup response
http_args = self._setup_failed_response(authn_request, destination, relay_state)

# return response
del self.ticket[key]
return http_args['data']

@property
Expand Down Expand Up @@ -669,7 +678,10 @@ def get_destination(self, req, sp_id):
)
return destination

def _setup_response(self, user, user_id, spid_level, message, destination, sp_id, relay_state):
def _setup_success_response(self, user, user_id, spid_level, message, destination, sp_id, relay_state):
"""
Build and return a successful response
"""
identity = user['attrs'].copy()
AUTHN = {
"class_ref": spid_level,
Expand Down Expand Up @@ -756,6 +768,33 @@ def _setup_response(self, user, user_id, spid_level, message, destination, sp_id

return http_args, response, identity

def _setup_failed_response(self, authn_request, destination, relay_state):
"""
Build and return a failed response
"""
error_response = self.server.create_error_response(
in_response_to=authn_request.message.id,
destination=destination,
info=get_spid_error(
AUTH_NO_CONSENT
)
)
self.app.logger.debug(
'Error response: \n{}'.format(
prettify_xml(str(error_response))
)
)
http_args = self.server.apply_binding(
BINDING_HTTP_POST,
error_response,
destination,
response=True,
sign=True,
relay_state=relay_state
)

return http_args

def login(self):
"""
Login endpoint (verify user credentials)
Expand Down Expand Up @@ -804,8 +843,8 @@ def from_session(key):
)
if user_id is not None:
# setup response
http_args, response, identity = self._setup_response(user, user_id, spid_level, message,
destination, sp_id, relay_state)
http_args, response, identity = self._setup_success_response(user, user_id, spid_level, message,
destination, sp_id, relay_state)

# Setup confirmation page data
self.responses[key] = http_args['data']
Expand All @@ -823,26 +862,10 @@ def from_session(key):
)
return rendered_response, 200
elif 'delete' in request.form:
error_response = self.server.create_error_response(
in_response_to=authn_request.message.id,
destination=destination,
info=get_spid_error(
AUTH_NO_CONSENT
)
)
self.app.logger.debug(
'Error response: \n{}'.format(
prettify_xml(str(error_response))
)
)
http_args = self.server.apply_binding(
BINDING_HTTP_POST,
error_response,
destination,
response=True,
sign=True,
relay_state=relay_state
)
# setup response
http_args = self._setup_failed_response(authn_request, destination, relay_state)

# return response
del self.ticket[key]
return http_args['data'], 200
return render_template('403.html'), 403
Expand Down
16 changes: 16 additions & 0 deletions testenv/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,19 @@ def add(self, uid, pwd, sp_id=None, extra={}):

def all(self):
return self.users


class AutoLoginJsonUserManager(JsonUserManager):
"""
User manager class that bypass the password check
"""
def __init__(self, *args, **kwargs):
super(AutoLoginJsonUserManager, self).__init__(*args, **kwargs)

def get(self, uid, pwd, sp_id):
for user, _attrs in self.users.items():
if user == uid:
if _attrs['sp'] is not None and _attrs['sp'] != sp_id:
return None, None
return user, self.users[user]
return None, None

0 comments on commit decd029

Please sign in to comment.