def saml_auth(): """ SAML Authentication Endpoint. Authenticate user through SAML. If error, set message in session so that frontend can get the message through /session call """ if not current_app.config.get('SAML_LOGIN_ENABLED'): abort( 403, title="Not Logged In", message= "Please use a valid way to log in. You are not able to use CWL login based on the current settings." ) url = "/app/#/lti" if sess.get('LTI') else "/" error_message = None auth = get_saml_auth_response(request) errors = auth.get_errors() if len(errors) > 0: current_app.logger.debug("SAML IdP returned errors: %s" % (errors)) error_message = "Login Failed." elif not auth.is_authenticated(): current_app.logger.debug("SAML IdP not logged in") error_message = "Login Failed." else: attributes = auth.get_attributes() unique_identifier = attributes.get( current_app.config.get('SAML_UNIQUE_IDENTIFIER')) current_app.logger.debug("SAML IdP responded with attributes:%s" % (attributes)) if not unique_identifier or (isinstance(unique_identifier, list) and len(unique_identifier) == 0): current_app.logger.error( "SAML idP did not return the unique_identifier " + current_app.config.get('SAML_UNIQUE_IDENTIFIER') + " within its attributes") error_message = "Login Failed. Expecting " + current_app.config.get( 'SAML_UNIQUE_IDENTIFIER') + " to be set." else: # set unique_identifier to first item in list if unique_identifier is an array if isinstance(unique_identifier, list): unique_identifier = unique_identifier[0] thirdpartyuser = ThirdPartyUser.query. \ filter_by( unique_identifier=unique_identifier, third_party_type=ThirdPartyType.saml ) \ .one_or_none() sess['SAML_NAME_ID'] = auth.get_nameid() sess['SAML_SESSION_INDEX'] = auth.get_session_index() if not thirdpartyuser: thirdpartyuser = ThirdPartyUser( unique_identifier=unique_identifier, third_party_type=ThirdPartyType.saml, params=attributes) thirdpartyuser.generate_or_link_user_account() db.session.add(thirdpartyuser) db.session.commit() elif not thirdpartyuser.user: thirdpartyuser.generate_or_link_user_account() db.session.commit() authenticate(thirdpartyuser.user, login_method=thirdpartyuser.third_party_type.value) thirdpartyuser.params = attributes if sess.get('LTI') and sess.get('lti_create_user_link'): lti_user = LTIUser.query.get_or_404(sess['lti_user']) lti_user.compair_user_id = thirdpartyuser.user_id lti_user.upgrade_system_role() lti_user.update_user_profile() sess.pop('lti_create_user_link') else: thirdpartyuser.upgrade_system_role() thirdpartyuser.update_user_profile() if sess.get('LTI') and sess.get('lti_context') and sess.get( 'lti_user_resource_link'): lti_context = LTIContext.query.get_or_404(sess['lti_context']) lti_user_resource_link = LTIUserResourceLink.query.get_or_404( sess['lti_user_resource_link']) lti_context.update_enrolment( thirdpartyuser.user_id, lti_user_resource_link.course_role) db.session.commit() sess['SAML_LOGIN'] = True if error_message is not None: sess['THIRD_PARTY_AUTH_ERROR_TYPE'] = 'SAML' sess['THIRD_PARTY_AUTH_ERROR_MSG'] = error_message return redirect(url)
def cas_auth(): """ CAS Authentication Endpoint. Authenticate user through CAS. If error, set message in session so that frontend can get the message through /session call """ if not current_app.config.get('CAS_LOGIN_ENABLED'): abort( 403, title="Log In Failed", message= "Please try an alternate way of logging in. The CWL login has been disabled by your system administrator." ) url = "/app/#/lti" if sess.get('LTI') else "/" error_message = None ticket = request.args.get("ticket") # check if token isn't present if not ticket: error_message = "No token in request" else: validation_response = validate_cas_ticket(ticket) if not validation_response.success: current_app.logger.debug( "CAS Server did NOT validate ticket:%s and included this response:%s" % (ticket, validation_response.response)) error_message = "Login Failed. CAS ticket was invalid." elif not validation_response.user: current_app.logger.debug( "CAS Server responded with valid ticket but no user") error_message = "Login Failed. Expecting CAS username to be set." else: current_app.logger.debug( "CAS Server responded with user:%s and attributes:%s" % (validation_response.user, validation_response.attributes)) username = validation_response.user thirdpartyuser = ThirdPartyUser.query. \ filter_by( unique_identifier=username, third_party_type=ThirdPartyType.cas ) \ .one_or_none() if not thirdpartyuser: thirdpartyuser = ThirdPartyUser( unique_identifier=username, third_party_type=ThirdPartyType.cas, params=validation_response.attributes) thirdpartyuser.generate_or_link_user_account() db.session.add(thirdpartyuser) db.session.commit() elif not thirdpartyuser.user: thirdpartyuser.generate_or_link_user_account() db.session.commit() authenticate(thirdpartyuser.user, login_method=thirdpartyuser.third_party_type.value) thirdpartyuser.params = validation_response.attributes if sess.get('LTI') and sess.get('lti_create_user_link'): lti_user = LTIUser.query.get_or_404(sess['lti_user']) lti_user.compair_user_id = thirdpartyuser.user_id lti_user.upgrade_system_role() lti_user.update_user_profile() sess.pop('lti_create_user_link') else: thirdpartyuser.upgrade_system_role() thirdpartyuser.update_user_profile() if sess.get('LTI') and sess.get('lti_context') and sess.get( 'lti_user_resource_link'): lti_context = LTIContext.query.get_or_404(sess['lti_context']) lti_user_resource_link = LTIUserResourceLink.query.get_or_404( sess['lti_user_resource_link']) lti_context.update_enrolment( thirdpartyuser.user_id, lti_user_resource_link.course_role) db.session.commit() sess['CAS_LOGIN'] = True if error_message is not None: sess['THIRD_PARTY_AUTH_ERROR_TYPE'] = 'CAS' sess['THIRD_PARTY_AUTH_ERROR_MSG'] = error_message return redirect(url)