Files
edx-platform/openedx/core/djangoapps/credentials/utils.py
2024-09-04 14:01:45 -04:00

123 lines
3.7 KiB
Python

"""Helper functions for working with Credentials."""
import logging
from typing import Dict, List
from urllib.parse import urljoin
import requests
from django.contrib.auth import get_user_model
from edx_rest_api_client.auth import SuppliedJwtAuth
from openedx.core.djangoapps.credentials.models import CredentialsApiConfig
from openedx.core.djangoapps.oauth_dispatch.jwt import create_jwt_for_user
from openedx.core.lib.edx_api_utils import get_api_data
log = logging.getLogger(__name__)
User = get_user_model()
def get_credentials_records_url(program_uuid=None):
"""
Returns a URL for a given records page (or general records list if given no UUID).
May return None if this feature is disabled.
Arguments:
program_uuid (str): Optional program uuid to link for a program records URL
"""
base_url = CredentialsApiConfig.current().public_records_url
if base_url is None:
return None
if program_uuid:
# Credentials expects Program UUIDs without dashes so we remove them here
stripped_program_uuid = program_uuid.replace("-", "")
return urljoin(base_url, f"programs/{stripped_program_uuid}")
return base_url
def get_credentials_api_client(user) -> requests.Session:
"""
Returns an authenticated Credentials API client.
Arguments:
user (User): The user to authenticate as when requesting credentials.
"""
scopes = ["email", "profile", "user_id"]
jwt = create_jwt_for_user(user, scopes=scopes)
client = requests.Session()
client.auth = SuppliedJwtAuth(jwt)
return client
def get_credentials_api_base_url(org=None):
"""
Returns a credentials API base URL.
Arguments:
org (str): Optional organization to look up the site config for, rather than the current request
"""
if org is None:
url = CredentialsApiConfig.current().internal_api_url # by current request
else:
url = CredentialsApiConfig.get_internal_api_url_for_org(org) # by org
return url
def get_credentials(
user: User,
program_uuid: str = None,
credential_type: str = None,
raise_on_error: bool = False,
) -> List[Dict]:
"""
Given a user, get credentials earned from the credentials service.
Arguments:
user (User): The user to authenticate as when requesting credentials.
Keyword Arguments:
program_uuid (str): UUID of the program whose credential to retrieve.
credential_type (str): Which type of credentials to return (course-run or program)
raise_on_error (bool): Reraise errors back to the caller, instead if returning empty results.
Returns:
list of dict, representing credentials returned by the Credentials
service.
"""
credential_configuration = CredentialsApiConfig.current()
querystring = {
"username": user.username,
"status": "awarded",
"only_visible": "True",
}
if program_uuid:
querystring["program_uuid"] = program_uuid
if credential_type:
querystring["type"] = credential_type
# Bypass caching for staff users, who may be generating credentials and
# want to see them displayed immediately.
use_cache = credential_configuration.is_cache_enabled and not user.is_staff
cache_key = f"{credential_configuration.CACHE_KEY}.{user.username}" if use_cache else None
if cache_key and program_uuid:
cache_key = f"{cache_key}.{program_uuid}"
api_client = get_credentials_api_client(user)
base_api_url = get_credentials_api_base_url()
return get_api_data(
credential_configuration,
"credentials",
api_client=api_client,
base_api_url=base_api_url,
querystring=querystring,
cache_key=cache_key,
raise_on_error=raise_on_error,
)