async def setup_course_hook( authenticator: Authenticator, handler: RequestHandler, authentication: Dict[str, str] ) -> Dict[str, str]: """ Calls the microservice to setup up a new course in case it does not exist. The data needed is received from auth_state within authentication object. This function assumes that the required k/v's in the auth_state dictionary are available, since the Authenticator(s) validates the data beforehand. This function requires `Authenticator.enable_auth_state = True` and is intended to be used as a post_auth_hook. Args: authenticator: the JupyterHub Authenticator object handler: the JupyterHub handler object authentication: the authentication object returned by the authenticator class Returns: authentication (Required): updated authentication object """ lti_utils = LTIUtils() jupyterhub_api = JupyterHubAPI() # normalize the name and course_id strings in authentication dictionary course_id = lti_utils.normalize_string(authentication['auth_state']['course_id']) nb_service = NbGraderServiceHelper(course_id) username = lti_utils.normalize_string(authentication['name']) lms_user_id = authentication['auth_state']['lms_user_id'] user_role = authentication['auth_state']['user_role'] # register the user (it doesn't matter if it is a student or instructor) with her/his lms_user_id in nbgrader nb_service.add_user_to_nbgrader_gradebook(username, lms_user_id) # TODO: verify the logic to simplify groups creation and membership if user_is_a_student(user_role): # assign the user to 'nbgrader-<course_id>' group in jupyterhub and gradebook await jupyterhub_api.add_student_to_jupyterhub_group(course_id, username) elif user_is_an_instructor(user_role): # assign the user in 'formgrade-<course_id>' group await jupyterhub_api.add_instructor_to_jupyterhub_group(course_id, username) # launch the new (?) grader-notebook as a service setup_response = await register_new_service(org_name=ORG_NAME, course_id=course_id) return authentication
def test_user_is_a_student_method_returns_false_when_instructor_role(): result = user_is_a_student('Instructor') assert result is False
def test_user_is_a_student_method_ignores_case(): result = user_is_a_student('learner') assert result is True result = user_is_a_student('LeArNeR') assert result is True
def test_user_is_a_student_method_returns_false_when_role_not_supported(): result = user_is_a_student('Unknown') assert result is False
def test_user_is_a_student_method_returns_true_when_learner_role(): result = user_is_a_student('Learner') assert result is True
def test_user_is_a_student_method_raises_an_error_with_missing_value(): with pytest.raises(ValueError): user_is_a_student('')
def test_user_is_a_student_method_ignores_case(): result = user_is_a_student("learner") assert result is True result = user_is_a_student("LeArNeR") assert result is True
async def setup_course_hook_lti11( handler: RequestHandler, authentication: Dict[str, str], ) -> Dict[str, str]: """ Calls the microservice to setup up a new course in case it does not exist when receiving LTI 1.1 launch requests. The data needed is received from auth_state within authentication object. This function assumes that the required k/v's in the auth_state dictionary are available, since the Authenticator(s) validates the data beforehand. This function requires `Authenticator.enable_auth_state = True` and is intended to be used as a post_auth_hook. Args: handler: the JupyterHub handler object authentication: the authentication object returned by the authenticator class Returns: authentication (Required): updated authentication object """ lti_utils = LTIUtils() jupyterhub_api = JupyterHubAPI() # normalize the name and course_id strings in authentication dictionary username = authentication["name"] lms_user_id = authentication["auth_state"]["user_id"] user_role = authentication["auth_state"]["roles"].split(",")[0] course_id = lti_utils.normalize_string( authentication["auth_state"]["context_label"]) nb_service = NbGraderServiceHelper(course_id, True) # register the user (it doesn't matter if it is a student or instructor) with her/his lms_user_id in nbgrader nb_service.add_user_to_nbgrader_gradebook(username, lms_user_id) # TODO: verify the logic to simplify groups creation and membership if user_is_a_student(user_role): try: # assign the user to 'nbgrader-<course_id>' group in jupyterhub and gradebook await jupyterhub_api.add_student_to_jupyterhub_group( course_id, username) except AddJupyterHubUserException as e: logger.error( "An error when adding student username: %s to course_id: %s with exception %s", (username, course_id, e), ) elif user_is_an_instructor(user_role): try: # assign the user in 'formgrade-<course_id>' group await jupyterhub_api.add_instructor_to_jupyterhub_group( course_id, username) except AddJupyterHubUserException as e: logger.error( "An error when adding instructor username: %s to course_id: %s with exception %s", (username, course_id, e), ) # launch the new grader-notebook as a service try: _ = await register_new_service(org_name=ORG_NAME, course_id=course_id) except Exception as e: logger.error( "Unable to launch the shared grader notebook with exception %s", e) return authentication