Skip to content
This repository has been archived by the owner on Sep 5, 2023. It is now read-only.

lti changes #644

Open
wants to merge 61 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
7ec5396
lti changes
rupeshparab Mar 21, 2022
ee0dfd7
added illumidesk secret option
Abhi94N Mar 22, 2022
d07623c
Dockerfile changes
rupeshparab Mar 22, 2022
f30091c
add env variable
rupeshparab Mar 22, 2022
32db3a5
initialization of secrets manager
Abhi94N Mar 25, 2022
070ca4f
updated graderservice to add restart grader functionality
Abhi94N Mar 25, 2022
4554626
updated route to restart grader
Abhi94N Mar 25, 2022
2ad280f
added response code for route
Abhi94N Mar 25, 2022
938df6a
updated formgrader secretsmanager version to a valid one
Abhi94N Mar 25, 2022
b8944e5
graderservice restart grader timeout 10 seconds
Abhi94N Mar 26, 2022
48a6467
grader service sleep changed
Abhi94N Mar 29, 2022
7ac98ac
updated to jupyterhub ltiauthenticator
Abhi94N Mar 29, 2022
abe0606
updated jinja2 and markupsafe version
Abhi94N Mar 29, 2022
47bf382
remove markup package
Abhi94N Mar 29, 2022
089e1c3
set jinja version to 3.0.3
Abhi94N Mar 29, 2022
508d95d
removed markup safe
Abhi94N Mar 29, 2022
28d73e9
updated jinja2 and packages dependent on jinja2
Abhi94N Mar 29, 2022
96390e1
fixed jinja version
Abhi94N Mar 29, 2022
6a7c7a1
update jedi version
Abhi94N Mar 29, 2022
5bfdada
jinja 3.1.1
Abhi94N Mar 29, 2022
0216198
oauthlib 3.1.1
Abhi94N Mar 29, 2022
40f79ca
revert jinja2 to 3.0.3
Abhi94N Mar 29, 2022
980b972
updated flask to version 2.1.0
Abhi94N Mar 29, 2022
cee4464
revert flask version
Abhi94N Mar 29, 2022
e2aceec
flask version 1.1.1
Abhi94N Mar 29, 2022
db33df4
update requirements
Abhi94N Mar 29, 2022
784dd48
update requirements
Abhi94N Mar 29, 2022
5d3a3f4
update test location in makefile
Abhi94N Mar 29, 2022
8a4c151
removed asyncnbgrader test
Abhi94N Apr 1, 2022
972352e
add async_test back
Abhi94N Apr 3, 2022
aa9d7da
uses secretmanager package to fetch secret values
Abhi94N Apr 7, 2022
e1fdbb5
fix role addition issue
rupeshparab Apr 12, 2022
98d951e
update markup safe
Abhi94N Apr 12, 2022
29cb562
update jinja2 version
Abhi94N Apr 12, 2022
fb09de6
updated flask to version 2.1.0
Abhi94N Apr 12, 2022
0405223
updated jinja2
Abhi94N Apr 12, 2022
e2fb9a7
update jinja2 for async_nbgrader
Abhi94N Apr 12, 2022
92db213
updated jinja2 to semver 2.10>=jinja2<3.1.0
Abhi94N Apr 12, 2022
56d5cbb
updated nbconvert version
Abhi94N Apr 12, 2022
9e6533a
jinja2 version downgrade to 3.1.0
Abhi94N Apr 12, 2022
7ba436a
updated flask to 2.1.0
Abhi94N Apr 12, 2022
13d4ad2
revert nbconvert
Abhi94N Apr 12, 2022
c365961
update werkzeug
Abhi94N Apr 12, 2022
a4691ea
update jinja2 to the latest version
Abhi94N Apr 12, 2022
a533e56
jinja 3.1
Abhi94N Apr 12, 2022
08463b3
nbconvert version 6.4.3
Abhi94N Apr 12, 2022
9da1fb6
reverted requirements txt
Abhi94N Apr 12, 2022
7c53d06
updates ltiauthenticator to use pypi version
Abhi94N Apr 12, 2022
83856ec
matched kubernetes version
Abhi94N Apr 12, 2022
b336d3f
update requirements.txt
Abhi94N Apr 12, 2022
a39211c
fix build
rupeshparab Apr 14, 2022
819dbb7
updated graderservice.py
Abhi94N Apr 14, 2022
6f05a41
updated secrets manager with restart grader route
Abhi94N Apr 14, 2022
839a1a8
tests for secrets and rollow restart route
Abhi94N Apr 14, 2022
d29cbd7
merge secrets pr to include secretsarn
Abhi94N Apr 15, 2022
17ea6c3
add default course hook for auth0
rupeshparab Apr 20, 2022
1d8a951
Merge branch 'lti_changes' of github.com:IllumiDesk/illumidesk into l…
rupeshparab Apr 20, 2022
9fbb70e
fix requirements
rupeshparab Apr 20, 2022
1351cc1
update default course name
rupeshparab Apr 21, 2022
6c0ce3f
add user to default course
rupeshparab Apr 22, 2022
3abcc7f
deployment fixes
rupeshparab May 5, 2022
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
13 changes: 2 additions & 11 deletions src/graderservice/graderservice/graderservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@
"ILLUMIDESK_NB_EXCHANGE_MNT_ROOT", "/illumidesk-nb-exchange"
)
GRADER_PVC = os.environ.get("GRADER_PVC", "grader-setup-pvc")
GRADER_EXCHANGE_SHARED_PVC = os.environ.get(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has the removal of GRADER_EXCHANGE_SHARED_PVC been tested? I was still having issues after I removed the deployment. That being said I was testing it without efs access points as we didn't need that in the Oregon cluster. I can try again with a new image and approve this afterward. Let me know if you have a new image, if not I'll fetch this PR and create the image and once tested, approve this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have created a new image of this with pr-71 tag

"GRADER_SHARED_PVC", "exchange-shared-volume"
)

# user UI and GID to use within the grader container
NB_UID = os.environ.get("NB_UID", 10001)
Expand Down Expand Up @@ -184,7 +181,7 @@ def _create_nbgrader_files(self):
grader_home_nbconfig_content = NBGRADER_HOME_CONFIG_TEMPLATE.format(
grader_name=self.grader_name,
course_id=self.course_id,
db_url=f"postgresql://{nbgrader_db_user}:{nbgrader_db_password}@{nbgrader_db_host}:5432/{self.org_name}_{self.course_id}",
db_url=f"postgresql://{nbgrader_db_user}:{nbgrader_db_password}@{nbgrader_db_host}:5432/{nbgrader_db_name}",
)
grader_nbconfig_path.write_text(grader_home_nbconfig_content)
# Write the nbgrader_config.py file at grader home directory
Expand Down Expand Up @@ -278,7 +275,7 @@ def _create_deployment_object(self):
),
client.V1VolumeMount(
mount_path="/srv/nbgrader/exchange",
name=GRADER_EXCHANGE_SHARED_PVC,
name=GRADER_PVC,
sub_path=sub_path_exchange,
),
],
Expand All @@ -298,12 +295,6 @@ def _create_deployment_object(self):
claim_name=GRADER_PVC
),
),
client.V1Volume(
name=GRADER_EXCHANGE_SHARED_PVC,
persistent_volume_claim=client.V1PersistentVolumeClaimVolumeSource(
claim_name=GRADER_EXCHANGE_SHARED_PVC
),
),
],
),
)
Expand Down
63 changes: 26 additions & 37 deletions src/illumidesk/illumidesk/apis/nbgrader_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
from nbgrader.api import Course
from nbgrader.api import Gradebook
from nbgrader.api import InvalidEntry
from sqlalchemy_utils import create_database
from sqlalchemy_utils import database_exists

from illumidesk.authenticators.utils import LTIUtils

Expand All @@ -18,24 +16,23 @@
nbgrader_db_port = os.environ.get("POSTGRES_NBGRADER_PORT") or 5432
nbgrader_db_password = os.environ.get("POSTGRES_NBGRADER_PASSWORD")
nbgrader_db_user = os.environ.get("POSTGRES_NBGRADER_USER")
nbgrader_db_name = os.environ.get("POSTGRES_NBGRADER_DATABASE")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If database does not exist, I am getting the following error

[W 2022-04-01 23:08:55.292 JupyterHub base:1256] Rolling back session due to database error (psycopg2.OperationalError) FATAL: database "tea_course" does not exist

mnt_root = os.environ.get("ILLUMIDESK_MNT_ROOT", "/illumidesk-courses")

org_name = os.environ.get("ORGANIZATION_NAME") or "my-org"

if not org_name:
raise EnvironmentError("ORGANIZATION_NAME env-var is not set")

CAMPUS_ID = os.environ.get("CAMPUS_ID")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the database does exist in rds instance like in the case of illumidesk_next_20220201 database, I get the following error

Rolling back session due to database error (psycopg2.errors.UndefinedColumn) column course.campus_id does not exist LINE 1: ...urse.id AS course_id, course.name AS course_name, course.cam..

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the database does exist in rds instance like in the case of illumidesk_next_20220201 database, I get the following error

Rolling back session due to database error (psycopg2.errors.UndefinedColumn) column course.campus_id does not exist LINE 1: ...urse.id AS course_id, course.name AS course_name, course.cam..

if not CAMPUS_ID:
raise EnvironmentError("CAMPUS_ID env-var is not set")

def nbgrader_format_db_url(course_id: str) -> str:
def nbgrader_format_db_url() -> str:
"""
Returns the nbgrader database url with the format: <org_name>_<course-id>

Args:
course_id: the course id (usually associated with the course label) from which the launch was initiated.
Returns the nbgrader database url
"""
course_id = LTIUtils().normalize_string(course_id)
database_name = f"{org_name}_{course_id}"
return f"postgresql://{nbgrader_db_user}:{nbgrader_db_password}@{nbgrader_db_host}:{nbgrader_db_port}/{database_name}"
return f"postgresql://{nbgrader_db_user}:{nbgrader_db_password}@{nbgrader_db_host}:{nbgrader_db_port}/{nbgrader_db_name}"


class NbGraderServiceHelper:
Expand All @@ -51,7 +48,7 @@ class NbGraderServiceHelper:
database_name: the database name
"""

def __init__(self, course_id: str, check_database_exists: bool = False):
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So what I'm understanding here is that all courses will be in one database instead of a database-specific for each org_course. This assumes that the database exists by default.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, the DB will be common and will be maintained by the migrations in admin-dashboard code base

Copy link

@Abhi94N Abhi94N Apr 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we may need to add back the check_databse_exist boolean value in case the database does not exist

def __init__(self, course_id: str):
if not course_id:
raise ValueError("course_id missing")

Expand All @@ -62,56 +59,48 @@ def __init__(self, course_id: str, check_database_exists: bool = False):
self.uid = int(os.environ.get("NB_GRADER_UID") or "10001")
self.gid = int(os.environ.get("NB_GRADER_GID") or "100")

self.db_url = nbgrader_format_db_url(course_id)
self.database_name = f"{org_name}_{self.course_id}"
if check_database_exists:
self.create_database_if_not_exists()

def create_database_if_not_exists(self) -> None:
"""Creates a new database if it doesn't exist"""
conn_uri = nbgrader_format_db_url(self.course_id)

if not database_exists(conn_uri):
logger.debug("db not exist, create database")
create_database(conn_uri)
self.db_url = nbgrader_format_db_url()

def add_user_to_nbgrader_gradebook(self, username: str, lms_user_id: str) -> None:
def add_user_to_nbgrader_gradebook(self, email: str, external_user_id: str, source: str, source_type: str, role: str) -> None:
"""
Adds a user to the nbgrader gradebook database for the course.

Args:
username: The user's username
lms_user_id: The user's id on the LMS
email: The user's email
external_user_id: The user's id on the external system
source: source from where user was authenticated
source_type: source_type
Raises:
InvalidEntry: when there was an error adding the user to the database
"""
if not username:
raise ValueError("username missing")
if not lms_user_id:
raise ValueError("lms_user_id missing")
if not email:
raise ValueError("email missing")
if not external_user_id:
raise ValueError("external_user_id missing")

with Gradebook(self.db_url, course_id=self.course_id) as gb:
with Gradebook(self.db_url, course_id=self.course_id, campus_id=CAMPUS_ID) as gb:
try:
gb.update_or_create_student(username, lms_user_id=lms_user_id)
user = gb.update_or_create_user_by_email(email, role=role, external_user_id=external_user_id, source=source, source_type=source_type)
logger.debug(
"Added user %s with lms_user_id %s to gradebook"
% (username, lms_user_id)
"Added user %s with external_user_id %s to gradebook"
% (email, external_user_id)
)
return user.to_dict()
except InvalidEntry as e:
logger.debug("Error during adding student to gradebook: %s" % e)

def update_course(self, **kwargs) -> None:
"""
Updates the course in nbgrader database
"""
with Gradebook(self.db_url, course_id=self.course_id) as gb:
with Gradebook(self.db_url, course_id=self.course_id, campus_id=CAMPUS_ID) as gb:
gb.update_course(self.course_id, **kwargs)

def get_course(self) -> Course:
"""
Gets the course model instance
"""
with Gradebook(self.db_url, course_id=self.course_id) as gb:
with Gradebook(self.db_url, course_id=self.course_id, campus_id=CAMPUS_ID) as gb:
course = gb.check_course(self.course_id)
logger.debug(f"course got from db:{course}")
return course
Expand All @@ -131,7 +120,7 @@ def register_assignment(self, assignment_name: str, **kwargs: dict) -> Assignmen
"Assignment name normalized %s to save in gradebook" % assignment_name
)
assignment = None
with Gradebook(self.db_url, course_id=self.course_id) as gb:
with Gradebook(self.db_url, course_id=self.course_id, campus_id=CAMPUS_ID) as gb:
try:
assignment = gb.update_or_create_assignment(assignment_name, **kwargs)
logger.debug("Added assignment %s to gradebook" % assignment_name)
Expand Down
94 changes: 75 additions & 19 deletions src/illumidesk/illumidesk/authenticators/authenticator.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ async def setup_course_hook_lti11(
jupyterhub_api = JupyterHubAPI()

# normalize the name and course_id strings in authentication dictionary
username = authentication["name"]
name = authentication["name"]
lms_user_id = authentication["auth_state"]["user_id"]
user_role = authentication["auth_state"]["roles"].split(",")[0]
course_id = lti_utils.normalize_string(
Expand All @@ -69,25 +69,28 @@ async def setup_course_hook_lti11(
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)
role = "STUDENT"
if not user_is_a_student(user_role) and user_is_an_instructor(user_role):
role = "INSTRUCTOR"
nb_service.add_user_to_nbgrader_gradebook(name, lms_user_id, role)
# TODO: verify the logic to simplify groups creation and membership
if user_is_a_student(user_role):
if role == "STUDENT":
try:
# assign the user to 'nbgrader-<course_id>' group in jupyterhub and gradebook
await jupyterhub_api.add_student_to_jupyterhub_group(course_id, username)
await jupyterhub_api.add_student_to_jupyterhub_group(course_id, lms_user_id)
except AddJupyterHubUserException as e:
logger.error(
"An error when adding student username: %s to course_id: %s with exception %s",
(username, course_id, e),
"An error when adding student user_id: %s to course_id: %s with exception %s",
(lms_user_id, course_id, e),
)
elif user_is_an_instructor(user_role):
elif role == "INSTRUCTOR":
try:
# assign the user in 'formgrade-<course_id>' group
await jupyterhub_api.add_instructor_to_jupyterhub_group(course_id, username)
await jupyterhub_api.add_instructor_to_jupyterhub_group(course_id, lms_user_id)
except AddJupyterHubUserException as e:
logger.error(
"An error when adding instructor username: %s to course_id: %s with exception %s",
(username, course_id, e),
"An error when adding instructor user_id: %s to course_id: %s with exception %s",
(lms_user_id, course_id, e),
)

# launch the new grader-notebook as a service
Expand Down Expand Up @@ -128,30 +131,33 @@ async def setup_course_hook(
# 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, True)
username = lti_utils.normalize_string(authentication["name"])
lms_user_id = authentication["auth_state"]["lms_user_id"]
email = authentication["auth_state"]["email"]
user_role = authentication["auth_state"]["user_role"]
source = authentication["auth_state"]["source"]
source_type = authentication["auth_state"]["source_type"]

# 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)
user = nb_service.add_user_to_nbgrader_gradebook(email, lms_user_id, source, source_type)
authentication["name"] = 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)
await jupyterhub_api.add_student_to_jupyterhub_group(course_id, user["id"])
except AddJupyterHubUserException as e:
logger.error(
"An error when adding student username: %s to course_id: %s with exception %s",
(username, course_id, e),
"An error when adding student user_id: %s to course_id: %s with exception %s",
(lms_user_id, 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)
await jupyterhub_api.add_instructor_to_jupyterhub_group(course_id, user["id"])
except AddJupyterHubUserException as e:
logger.error(
"An error when adding instructor username: %s to course_id: %s with exception %s",
(username, course_id, e),
"An error when adding instructor user_id: %s to course_id: %s with exception %s",
(lms_user_id, course_id, e),
)

# launch the new grader-notebook as a service
Expand All @@ -163,6 +169,48 @@ async def setup_course_hook(
return authentication


async def setup_user_hook_auth0(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would the custom authenticator also need it's own Class that inherits from Oauthenticator in order to decode jwt claims?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should not be needed, this method is more list a post auth hook

authenticator: Authenticator,
handler: RequestHandler,
authentication: Dict[str, str],
) -> Dict[str, str]:
"""
Calls the microservice to create a new user 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()

# 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, True)
oauth_user = authentication["auth_state"]["oauth_user"] or {}

lms_user_id = oauth_user.get("user_id") or oauth_user.get("username") or oauth_user.get("sub")
email = oauth_user.get("email") or oauth_user.get("sub")
# user_role = authentication["auth_state"]["user_role"]
source = "auth0"
source_type = "generic-oauth"

# register the user (it doesn't matter if it is a student or instructor) with her/his lms_user_id in nbgrader
user = nb_service.add_user_to_nbgrader_gradebook(email, lms_user_id, source, source_type)
authentication["name"] = user["id"]
return authentication


class LTI13Authenticator(OAuthenticator):
"""Custom authenticator used with LTI 1.3 requests"""

Expand Down Expand Up @@ -235,7 +283,9 @@ async def authenticate( # noqa: C901
course_id = lti_utils.normalize_string(course_id)
self.log.debug("Normalized course label is %s" % course_id)
username = ""
email = ""
if "email" in jwt_decoded and jwt_decoded["email"]:
email = jwt_decoded["email"]
username = lti_utils.email_to_username(jwt_decoded["email"])
elif "name" in jwt_decoded and jwt_decoded["name"]:
username = jwt_decoded["name"]
Expand Down Expand Up @@ -294,6 +344,7 @@ async def authenticate( # noqa: C901
await process_resource_link_lti_13(self.log, course_id, jwt_decoded)

lms_user_id = jwt_decoded["sub"] if "sub" in jwt_decoded else username
lms_id = (jwt_decoded.get("https://purl.imsglobal.org/spec/lti/claim/tool_platform") or {}).get("guid")

# ensure the username is normalized
self.log.debug("username is %s" % username)
Expand All @@ -303,14 +354,19 @@ async def authenticate( # noqa: C901
# ensure the user name is normalized
username_normalized = lti_utils.normalize_string(username)
self.log.debug("Assigned username is: %s" % username_normalized)
self.log.debug("Assigned id is: %s for username %s" % (lms_user_id, username))

return {
"name": username_normalized,
"name": email or lms_user_id,
"auth_state": {
"course_id": course_id,
"user_role": user_role,
"lms_user_id": lms_user_id,
"username": username,
"email": email or lms_user_id,
"launch_return_url": launch_return_url,
"source": lms_id,
"source_type": "lti13"
}, # noqa: E231
}

Expand Down
2 changes: 1 addition & 1 deletion src/illumidesk/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ matplotlib-inline==0.1.2 # via ipython
mistune==0.8.4 # via nbconvert
nbconvert==5.6.1 # via jupyter, nbgrader, notebook
nbformat==5.1.3 # via ipywidgets, nbconvert, nbgrader, notebook
nbgrader==0.6.2 # via illumidesk (setup.py)
git+ssh://git@github.com/IllumiDesk/illumidesk-next.git@feature/refactor-modals-lti#subdirectory=packages/nbgrader # via illumidesk (setup.py)
notebook==6.4.1 # via jupyter, nbgrader, widgetsnbextension
oauthenticator==14.2.0 # via illumidesk (setup.py)
oauthlib==3.1.0 # via illumidesk (setup.py), jupyterhub, jupyterhub-ltiauthenticator, requests-oauthlib
Expand Down
2 changes: 1 addition & 1 deletion src/illumidesk/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"jupyterhub-kubespawner==0.14.1",
"jupyterhub-ltiauthenticator@git+git://github.com/jupyterhub/ltiauthenticator.git@71d86a9da2562df4bdcc9f374af834a172ac52d5",
"jwcrypto==0.8",
"nbgrader==0.6.2",
"git+ssh://git@github.com/IllumiDesk/illumidesk-next.git@feature/refactor-modals-lti#subdirectory=packages/nbgrader",
"oauthlib==3.1",
"oauthenticator>=0.13.0",
"pem==20.1.0",
Expand Down
2 changes: 1 addition & 1 deletion src/illumidesk/tests/illumidesk/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
@pytest.fixture(scope="module")
def auth_state_dict():
authenticator_auth_state = {
"name": "student1",
"name": "185d6c59731a553009ca9b59ca3a885100000",
"auth_state": {
"course_id": "intro101",
"lms_user_id": "185d6c59731a553009ca9b59ca3a885100000",
Expand Down