openedx.core.djangoapps.user_api.accounts package

Contents

openedx.core.djangoapps.user_api.accounts package#

Submodules#

openedx.core.djangoapps.user_api.accounts.api module#

Programmatic integration point for User API Accounts sub-application

openedx.core.djangoapps.user_api.accounts.api.get_account_settings(request, usernames=None, configuration=None, view=None)#

Returns account information for a user serialized as JSON.

Note

If request.user.username != username, this method will return differing amounts of information based on who request.user is and the privacy settings of the user associated with username.

Parameters:
  • request (Request) – The request object with account information about the requesting user. Only the user with username username or users with “is_staff” privileges can get full account information. Other users will get the account fields that the user has elected to share.

  • usernames (list) – Optional list of usernames for the desired account information. If not specified, request.user.username is assumed.

  • configuration (dict) – an optional configuration specifying which fields in the account can be shared, and the default visibility settings. If not present, the setting value with key ACCOUNT_VISIBILITY_CONFIGURATION is used.

  • view (str) – An optional string allowing “is_staff” users and users requesting their own account information to get just the fields that are shared with everyone. If view is “shared”, only shared account information will be returned, regardless of request.user.

Returns:

A list of users account details.

Raises:
openedx.core.djangoapps.user_api.accounts.api.get_confirm_email_validation_error(confirm_email, email)#

Get the built-in validation error message for when the confirmation email is invalid in some way.

Parameters:
  • confirm_email – The proposed confirmation email (unicode).

  • email – The email to match (unicode).

  • default – THe message to default to in case of no error.

Returns:

Validation error message.

openedx.core.djangoapps.user_api.accounts.api.get_country_validation_error(country)#

Get the built-in validation error message for when the country is invalid in some way.

Parameters:

country – The proposed country.

Returns:

Validation error message.

openedx.core.djangoapps.user_api.accounts.api.get_email_existence_validation_error(email)#

Get the built-in validation error message for when the email has an existence conflict.

Parameters:
  • email – The proposed email (unicode).

  • default – The message to default to in case of no error.

Returns:

Validation error message.

openedx.core.djangoapps.user_api.accounts.api.get_email_validation_error(email)#

Get the built-in validation error message for when the email is invalid in some way.

Parameters:
  • email – The proposed email (unicode).

  • default – The message to default to in case of no error.

Returns:

Validation error message.

openedx.core.djangoapps.user_api.accounts.api.get_name_validation_error(name)#

Get the built-in validation error message for when the user’s real name is invalid in some way (we wonder how).

Parameters:

name – The proposed user’s real name.

Returns:

Validation error message.

openedx.core.djangoapps.user_api.accounts.api.get_password_validation_error(password, username=None, email=None, reset_password_page=False)#

Get the built-in validation error message for when the password is invalid in some way.

Parameters:
  • password – The proposed password (unicode).

  • username – The username associated with the user’s account (unicode).

  • email – The email associated with the user’s account (unicode).

  • reset_password_page – The flag that determines the validation page (bool).

Returns:

Validation error message.

openedx.core.djangoapps.user_api.accounts.api.get_profile_images(user_profile, user, request=None)#

Returns metadata about a user’s profile image.

The output is a dict that looks like:

{

“has_image”: False, “image_url_full”: “http://testserver/static/default_500.png”, “image_url_large”: “http://testserver/static/default_120.png”, “image_url_medium”: “http://testserver/static/default_50.png”, “image_url_small”: “http://testserver/static/default_30.png”,

}

openedx.core.djangoapps.user_api.accounts.api.get_secondary_email_validation_error(email)#

Get the built-in validation error message for when the email is invalid in some way.

Parameters:

email (str) – The proposed email (unicode).

Returns:

Validation error message.

Return type:

(str)

openedx.core.djangoapps.user_api.accounts.api.get_username_existence_validation_error(username)#

Get the built-in validation error message for when the username has an existence conflict.

Parameters:
  • username – The proposed username (unicode).

  • default – The message to default to in case of no error.

Returns:

Validation error message.

openedx.core.djangoapps.user_api.accounts.api.get_username_validation_error(username)#

Get the built-in validation error message for when the username is invalid in some way.

Parameters:
  • username – The proposed username (unicode).

  • default – The message to default to in case of no error.

Returns:

Validation error message.

openedx.core.djangoapps.user_api.accounts.api.update_account_settings(requesting_user, update, username=None)#

Update user account information.

Note

It is up to the caller of this method to enforce the contract that this method is only called with the user who made the request.

Parameters:
  • requesting_user (User) – The user requesting to modify account information. Only the user with username ‘username’ has permissions to modify account information.

  • update (dict) – The updated account field values.

  • username (str) – Optional username specifying which account should be updated. If not specified, requesting_user.username is assumed.

Raises:
  • errors.UserNotFound – no user with username username exists (or requesting_user.username if username is not specified)

  • errors.UserNotAuthorized – the requesting_user does not have access to change the account associated with username

  • errors.AccountValidationError – the update was not attempted because validation errors were found with the supplied update

  • errors.AccountUpdateError – the update could not be completed. Note that if multiple fields are updated at the same time, some parts of the update may have been successful, even if an errors.AccountUpdateError is returned; in particular, the user account (not including e-mail address) may have successfully been updated, but then the e-mail change request, which is processed last, may throw an error.

  • errors.UserAPIInternalError – the operation failed due to an unexpected error.

openedx.core.djangoapps.user_api.accounts.forms module#

Django forms for accounts

class openedx.core.djangoapps.user_api.accounts.forms.RetirementQueueDeletionForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None, bound_field_class=None)#

Bases: Form

Admin form to facilitate learner retirement cancellation

base_fields = {'cancel_retirement': <django.forms.fields.BooleanField object>}#
declared_fields = {'cancel_retirement': <django.forms.fields.BooleanField object>}#
property media#

Return all media required to render the widgets on this form.

save(retirement)#

When the form is POSTed we double-check the retirment status and perform the necessary steps to cancel the retirement request.

openedx.core.djangoapps.user_api.accounts.forms.extract_extended_profile_fields_data(extended_profile: list[dict] | None) tuple[dict, dict]#

Extract extended profile fields data from extended_profile structure.

Parameters:

extended_profile (list[dict] | None) – List of field data dictionaries with keys field_name and field_value

Returns:

A tuple containing (extended_profile_fields_data, field_errors)
  • extended_profile_fields_data (dict): Extracted custom fields data

  • field_errors (dict): Dictionary of validation errors, if any

Return type:

tuple

openedx.core.djangoapps.user_api.accounts.forms.get_extended_profile_form(extended_profile_fields_data: dict, user: User) tuple[Form | None, dict]#

Get and validate an extended profile form instance.

Parameters:
  • extended_profile_fields_data (dict) – Extended profile field data to

  • form (populate the)

  • user (User) – User instance to associate with the

  • profile (extended)

Returns:

A tuple containing (extended_profile_form, field_errors)
  • extended_profile_form (forms.Form | None): The validated form instance, or None if no extended profile form is configured, creation fails, or form validation fails.

  • field_errors (dict): Dictionary of validation errors, if any

Return type:

tuple

openedx.core.djangoapps.user_api.accounts.forms.validate_and_get_extended_profile_form(extended_profile_data: list, user: User) tuple[Form | None, dict]#

Validate and return an extended profile form instance.

This function orchestrates the extraction and validation of extended profile data.

Parameters:
  • extended_profile_data (list) – The raw extended_profile data from the API request

  • user (User) – The user instance for whom the extended profile is being validated

Returns:

A tuple containing (validated_form, field_errors)
  • validated_form (forms.Form | None): The validated form instance, or None if validation fails or no extended profile is configured

  • field_errors (dict): Dictionary of validation errors, if any

Return type:

tuple

openedx.core.djangoapps.user_api.accounts.image_helpers module#

Helper functions for the accounts API.

openedx.core.djangoapps.user_api.accounts.image_helpers.get_profile_image_names(username)#

Returns a dict containing the filenames for a complete set of profile images, keyed by pixel size.

openedx.core.djangoapps.user_api.accounts.image_helpers.get_profile_image_storage()#

Returns an instance of the configured storage backend for profile images.

This function prioritizes different settings in the following order to determine which storage class to use:

  1. Use ‘profile_image’ storage from Django’s STORAGES if defined (Django 4.2+).

  2. If not available, check the legacy PROFILE_IMAGE_BACKEND setting.

  3. If still undefined, fall back to Django’s default_storage.

Note

  • Starting in Django 5+, DEFAULT_FILE_STORAGE and the STORAGES setting are mutually exclusive. Only one of them should be used to avoid ImproperlyConfigured errors.

Returns:

An instance of the configured storage backend for handling profile images.

Raises:

ImportError – If the specified storage class cannot be imported.

openedx.core.djangoapps.user_api.accounts.image_helpers.get_profile_image_urls_for_user(user, request=None)#

Return a dict {size:url} for each profile image for a given user. .. rubric:: Notes

  • this function does not determine whether the set of profile images

exists, only what the URLs will be if they do exist. It is assumed that callers will use _get_default_profile_image_urls instead to provide a set of urls that point to placeholder images, when there are no user- submitted images.

  • based on the value of django.conf.settings.PROFILE_IMAGE_BACKEND,

the URL may be relative, and in that case the caller is responsible for constructing the full URL if needed.

Parameters:

user (django.contrib.auth.User) – the user for whom we are getting urls.

Returns:

url} for each image.

Return type:

dictionary of {size_display_name

openedx.core.djangoapps.user_api.accounts.image_helpers.set_has_profile_image(username, is_uploaded, upload_dt=None)#

System (not user-facing) API call used to store whether the user has uploaded a profile image, and if so, when. Used by profile_image API.

Parameters:
  • username (django.contrib.auth.User.username) – references the user who uploaded an image.

  • is_uploaded (bool) – whether or not the user has an uploaded profile image.

  • upload_dt (datetime.datetime) – If is_uploaded is True, this should contain the server-side date+time of the upload. If is_uploaded is False, the parameter is optional and will be ignored.

Raises:
  • ValueError – is_uploaded was True, but no upload datetime was supplied.

  • UserNotFound – no user with username username exists.

openedx.core.djangoapps.user_api.accounts.permissions module#

Permissions classes for User accounts API views.

class openedx.core.djangoapps.user_api.accounts.permissions.CanCancelUserRetirement#

Bases: BasePermission

Grants access to cancel retirement if the requesting user is a superuser, or has the explicit permission to cancel retirement of a User account.

has_permission(request, view)#

Return True if permission is granted, False otherwise.

class openedx.core.djangoapps.user_api.accounts.permissions.CanDeactivateUser#

Bases: BasePermission

Grants access to AccountDeactivationView if the requesting user is a superuser or has the explicit permission to deactivate a User account.

has_permission(request, view)#

Return True if permission is granted, False otherwise.

class openedx.core.djangoapps.user_api.accounts.permissions.CanGetAccountInfo#

Bases: BasePermission

Grants access to AccountViewSet if the requesting user is a superuser/staff and requesting to get account info based on non-public information.

has_permission(request, view)#

Return True if permission is granted, False otherwise.

class openedx.core.djangoapps.user_api.accounts.permissions.CanReplaceUsername#

Bases: BasePermission

Grants access to the Username Replacement API for the service user.

has_permission(request, view)#

Return True if permission is granted, False otherwise.

class openedx.core.djangoapps.user_api.accounts.permissions.CanRetireUser#

Bases: BasePermission

Grants access to the various retirement API endpoints if the requesting user is a superuser, the RETIREMENT_SERVICE_USERNAME, or has the explicit permission to retire a User account.

has_permission(request, view)#

Return True if permission is granted, False otherwise.

openedx.core.djangoapps.user_api.accounts.serializers module#

Django REST Framework serializers for the User API Accounts sub-application

class openedx.core.djangoapps.user_api.accounts.serializers.AccountLegacyProfileSerializer(*args, **kwargs)#

Bases: HyperlinkedModelSerializer, ReadOnlyFieldsSerializerMixin

Class that serializes the portion of UserProfile model needed for account information.

class Meta#

Bases: object

explicit_read_only_fields = ('profile_image', 'requires_parental_consent')#
fields = ('name', 'gender', 'goals', 'year_of_birth', 'level_of_education', 'country', 'state', 'social_links', 'mailing_address', 'bio', 'profile_image', 'requires_parental_consent', 'language_proficiencies', 'phone_number', 'city')#
model#

alias of UserProfile

read_only_fields = ()#
static convert_empty_to_None(value)#

Helper method to convert empty string to None (other values pass through).

static get_profile_image(user_profile, user, request=None)#

Returns metadata about a user’s profile image.

Returns a boolean representing whether the user requires parental controls.

transform_bio(user_profile, value)#

Converts empty string to None, to indicate not set. Replaced by to_representation in version 3.

transform_country(user_profile, value)#

Converts empty string to None, to indicate not set. Replaced by to_representation in version 3.

transform_gender(user_profile, value)#

Converts empty string to None, to indicate not set. Replaced by to_representation in version 3.

transform_level_of_education(user_profile, value)#

Converts empty string to None, to indicate not set. Replaced by to_representation in version 3.

transform_phone_number(user_profile, value)#

Converts empty string to None, to indicate not set. Replaced by to_representation in version 3.

update(instance, validated_data)#

Update the profile, including nested fields.

Raises: errors.AccountValidationError: the update was not attempted because validation errors were found with

the supplied update

validate_bio(new_bio)#

Enforce maximum length for bio.

validate_language_proficiencies(value)#

Enforce all languages are unique.

validate_name(new_name)#

Enforce minimum length for name.

Enforce only one entry for a particular social platform.

class openedx.core.djangoapps.user_api.accounts.serializers.AccountUserSerializer(*args, **kwargs)#

Bases: HyperlinkedModelSerializer, ReadOnlyFieldsSerializerMixin

Class that serializes the portion of User model needed for account information.

class Meta#

Bases: object

explicit_read_only_fields = ()#
fields = ('username', 'email', 'date_joined', 'is_active', 'password_toggle_history')#
model#

alias of User

read_only_fields = ('username', 'email', 'date_joined', 'is_active', 'password_toggle_history')#
class openedx.core.djangoapps.user_api.accounts.serializers.LanguageProficiencySerializer(*args, **kwargs)#

Bases: ModelSerializer

Class that serializes the LanguageProficiency model for account information.

class Meta#

Bases: object

fields = ('code',)#
model#

alias of LanguageProficiency

get_identity(data)#

This is used in bulk updates to determine the identity of an object. The default is to use the id of an object, but we want to override that and consider the language code to be the canonical identity of a LanguageProficiency model.

class openedx.core.djangoapps.user_api.accounts.serializers.PendingNameChangeSerializer(*args, **kwargs)#

Bases: Serializer

Serialize the PendingNameChange model

class Meta#

Bases: object

fields = ('new_name',)#
model#

alias of PendingNameChange

validate_new_name(new_name)#
class openedx.core.djangoapps.user_api.accounts.serializers.PhoneNumberSerializer(*args, **kwargs)#

Bases: BaseSerializer

Class to serialize phone number into a digit only representation.

This serializer removes all non-numeric characters from the phone number, allowing ‘+’ only at the beginning of the number.

to_internal_value(data)#

Remove all non-numeric characters from the phone number.

Parameters:

data (str) – The input phone number string.

Returns:

The cleaned phone number string containing only digits,

with an optional ‘+’ at the beginning.

Return type:

str or None

class openedx.core.djangoapps.user_api.accounts.serializers.RetirementStateSerializer(*args, **kwargs)#

Bases: ModelSerializer

Serialize a small subset of RetirementState data for use in RetirementStatus APIs

class Meta#

Bases: object

fields = ('id', 'state_name', 'state_execution_order')#
model#

alias of RetirementState

class openedx.core.djangoapps.user_api.accounts.serializers.RetirementUserProfileSerializer(*args, **kwargs)#

Bases: ModelSerializer

Serialize a small subset of UserProfile data for use in RetirementStatus APIs

class Meta#

Bases: object

fields = ('id', 'name')#
model#

alias of UserProfile

class openedx.core.djangoapps.user_api.accounts.serializers.RetirementUserSerializer(*args, **kwargs)#

Bases: ModelSerializer

Serialize a small subset of User data for use in RetirementStatus APIs

class Meta#

Bases: object

fields = ('id', 'username', 'email', 'profile')#
model#

alias of User

class openedx.core.djangoapps.user_api.accounts.serializers.SocialLinkSerializer(*args, **kwargs)#

Bases: ModelSerializer

Class that serializes the SocialLink model for the UserProfile object.

class Meta#

Bases: object

fields = ('platform', 'social_link')#
model#

alias of SocialLink

validate_platform(platform)#

Validate that the platform value is one of (facebook, x or linkedin)

class openedx.core.djangoapps.user_api.accounts.serializers.UserAccountDisableHistorySerializer(*args, **kwargs)#

Bases: ModelSerializer

Class that serializes User account disable history

class Meta#

Bases: object

fields = ('created', 'comment', 'disabled', 'created_by')#
model#

alias of UserPasswordToggleHistory

get_created_by(user_password_toggle_history)#
class openedx.core.djangoapps.user_api.accounts.serializers.UserReadOnlySerializer(*args, **kwargs)#

Bases: Serializer

Class that serializes the User model and UserProfile model together.

to_representation(user)#

Overwrite to_native to handle custom logic since we are serializing three models as one here :param user: User object :return: Dict serialized account

class openedx.core.djangoapps.user_api.accounts.serializers.UserRetirementPartnerReportSerializer(*args, **kwargs)#

Bases: Serializer

Perform serialization for the UserRetirementPartnerReportingStatus model

create(validated_data)#
update(instance, validated_data)#
class openedx.core.djangoapps.user_api.accounts.serializers.UserRetirementStatusSerializer(*args, **kwargs)#

Bases: ModelSerializer

Perform serialization for the RetirementStatus model

class Meta#

Bases: object

exclude = ['responses']#
model#

alias of UserRetirementStatus

class openedx.core.djangoapps.user_api.accounts.serializers.UserSearchEmailSerializer(*args, **kwargs)#

Bases: ModelSerializer

Perform serialization for the User model used in accounts/search_emails endpoint.

class Meta#

Bases: object

fields = ('email', 'id', 'username')#
model#

alias of User

openedx.core.djangoapps.user_api.accounts.serializers.get_extended_profile(user_profile: UserProfile) list[dict[str, str]]#

Retrieve extended user profile fields for API serialization.

This function extracts custom profile fields that extend beyond the standard UserProfile model. It prefers data from a custom extended profile model (when configured), and only uses the user_profile.meta JSON field when no such model is configured. The returned data is filtered to include only fields specified in the extended_profile_fields site configuration.

The function supports two data sources: 1. Custom model: If the PROFILE_EXTENSION_FORM setting points to a form with a

Meta.model, data is retrieved from that model using model_to_dict(). If a model is configured but the user does not yet have a corresponding record, this function returns an empty mapping for extended profile fields (it does not fall back to user_profile.meta in that case).

  1. Fallback: JSON data stored in UserProfile.meta field, used only when no

    custom extended profile model is configured.

Parameters:

user_profile (UserProfile) – The user profile instance to get extended fields from.

Returns:

A list of dictionaries, each containing:
  • field_name: The name of the extended profile field

  • field_value: The value of the field (converted to string)

Return type:

list[dict[str, str]]

openedx.core.djangoapps.user_api.accounts.serializers.get_profile_visibility(user_profile, user, configuration)#

Returns the visibility level for the specified user profile.

openedx.core.djangoapps.user_api.accounts.signals module#

Django Signal related functionality for user_api accounts

openedx.core.djangoapps.user_api.accounts.signals.get_redacted_social_auth_uid(pk)#

Return the redacted uid for a UserSocialAuth record.

This must match the format used in redact_and_delete_social_auth.

openedx.core.djangoapps.user_api.accounts.signals.redact_social_auth_pii_before_deletion(sender, instance, **kwargs)#

Safety-net signal handler that redacts PII on any UserSocialAuth before deletion.

Records deleted via redact_and_delete_social_auth will already be redacted; this handler is a fallback for any missed deletion path.

openedx.core.djangoapps.user_api.accounts.utils module#

Utility methods for the account settings.

openedx.core.djangoapps.user_api.accounts.utils.create_retirement_request_and_deactivate_account(user)#

Adds user to retirement queue, unlinks social auth accounts, changes user passwords and delete tokens and activation keys

Given a user’s social link, returns a safe absolute url for the social link.

Returns: - An empty string if new_social_link is empty. - A formatted URL if new_social_link is a username. - Returns new_social_link if it is a valid URL. - None for unparseable inputs.

openedx.core.djangoapps.user_api.accounts.utils.handle_retirement_cancellation(retirement, email_address=None)#

Do the following in order to cancel retirement for a given user:

  1. Load the user record using the retired email address -and- change the email address back.

  2. Reset users password so they can request a password reset and log in again.

  3. No need to delete the accompanying “permanent” retirement request record - it gets done via Django signal.

openedx.core.djangoapps.user_api.accounts.utils.is_secondary_email_feature_enabled()#

Checks to see if the django-waffle switch for enabling the secondary email feature is active

Returns:

Boolean value representing switch status

openedx.core.djangoapps.user_api.accounts.utils.redact_and_delete_social_auth(user_id, skip_delete=False)#

Redact PII from all UserSocialAuth records for the given user, then delete them.

Downstream copies of data may use soft-deletes, and redacting before deleting ensures PII for retired users (or future retirements) is not retained.

skip_delete should only be set to True when called from the pre_delete signal handler, where deletion is already in progress.

openedx.core.djangoapps.user_api.accounts.utils.retrieve_last_sitewide_block_completed(user)#

Completion utility From a given User object retrieve the last course block marked as ‘completed’ and construct a URL

Parameters:

user – obj(User)

Returns:

block_lms_url

openedx.core.djangoapps.user_api.accounts.utils.username_suffix_generator(suffix_length=4)#

Generates a random, alternating number and letter string for the purpose of appending to non-unique usernames. Alternating is less likey to produce a significant/meaningful substring like an offensive word. Whether the suffix starts with a letter or number is also randomized.

Given a new social link for a user, ensure that the link takes one of the following forms:

  1. A valid url that comes from the correct social site.

  2. A valid username.

  3. A blank value.

openedx.core.djangoapps.user_api.accounts.views module#

An API for retrieving user account information.

For additional information and historical context, see: https://openedx.atlassian.net/wiki/display/TNL/User+API

class openedx.core.djangoapps.user_api.accounts.views.AccountDeactivationView(**kwargs)#

Bases: APIView

Account deactivation viewset. Currently only supports POST requests. Only admins can deactivate accounts.

permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>, <class 'openedx.core.djangoapps.user_api.accounts.permissions.CanDeactivateUser'>)#
post(request, username)#

POST /api/user/v1/accounts/{username}/deactivate/

Marks the user as having no password set for deactivation purposes.

class openedx.core.djangoapps.user_api.accounts.views.AccountRetirementPartnerReportView(**kwargs)#

Bases: ViewSet

Provides API endpoints for managing partner reporting of retired users.

DELETION_COMPLETED_KEY = 'deletion_completed'#
ORGS_CONFIG_FIELD_HEADINGS_KEY = 'field_headings'#
ORGS_CONFIG_KEY = 'orgs_config'#
ORGS_CONFIG_ORG_KEY = 'org'#
ORIGINAL_EMAIL_KEY = 'original_email'#
ORIGINAL_NAME_KEY = 'original_name'#
STUDENT_ID_KEY = 'student_id'#
basename = None#
description = None#
detail = None#
name = None#
parser_classes = (<class 'rest_framework.parsers.JSONParser'>,)#
permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>, <class 'openedx.core.djangoapps.user_api.accounts.permissions.CanRetireUser'>)#
retirement_partner_cleanup(request)#

POST /api/user/v1/accounts/retirement_partner_report_cleanup/

[{‘original_username’: ‘user1’}, {‘original_username’: ‘user2’}, …]

Deletes UserRetirementPartnerReportingStatus objects for a list of users that have been reported on.

retirement_partner_report(request)#

POST /api/user/v1/accounts/retirement_partner_report/

Returns the list of UserRetirementPartnerReportingStatus users that are not already being processed and updates their status to indicate they are currently being processed.

retirement_partner_status_create(request)#

PUT /api/user/v1/accounts/retirement_partner_report/

``` {

‘username’: ‘user_to_retire’

}#

Creates a UserRetirementPartnerReportingStatus object for the given user as part of the retirement pipeline.

serializer_class#

alias of UserRetirementStatusSerializer

suffix = None#
class openedx.core.djangoapps.user_api.accounts.views.AccountRetirementStatusView(**kwargs)#

Bases: ViewSet

Provides API endpoints for managing the user retirement process.

basename = None#
cleanup(request)#

POST /api/user/v1/accounts/retirement_cleanup/

``` {

‘usernames’: [‘user1’, ‘user2’, …], ‘redacted_username’: ‘Value to store in username field’, ‘redacted_email’: ‘Value to store in email field’, ‘redacted_name’: ‘Value to store in name field’

}#

Redacts and then deletes a batch of retirement requests by username.

description = None#
detail = None#
name = None#
parser_classes = (<class 'rest_framework.parsers.JSONParser'>,)#
partial_update(request)#

PATCH /api/user/v1/accounts/update_retirement_status/

``` {

‘username’: ‘user_to_retire’, ‘new_state’: ‘LOCKING_COMPLETE’, ‘response’: ‘User account locked and logged out.’

}#

Updates the RetirementStatus row for the given user to the new status, and append any messages to the message log.

Note that this implementation DOES NOT use the “merge patch” implementation seen in AccountViewSet. The content type for this request is ‘application/json’.

permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>, <class 'openedx.core.djangoapps.user_api.accounts.permissions.CanRetireUser'>)#
retirement_queue(request)#

GET /api/user/v1/accounts/retirement_queue/ {‘cool_off_days’: 7, ‘states’: [‘PENDING’, ‘COMPLETE’], ‘limit’: 500}

Returns the list of RetirementStatus users in the given states that were created in the retirement queue at least cool_off_days ago.

retirements_by_status_and_date(request)#

GET /api/user/v1/accounts/retirements_by_status_and_date/ ?start_date=2018-09-05&end_date=2018-09-07&state=COMPLETE

Returns a list of UserRetirementStatusSerializer serialized RetirementStatus rows in the given state that were created in the retirement queue between the dates given. Date range is inclusive, so to get one day you would set both dates to that day.

retrieve(request, username)#

GET /api/user/v1/accounts/{username}/retirement_status/ Returns the RetirementStatus of a given user, or 404 if that row doesn’t exist.

serializer_class#

alias of UserRetirementStatusSerializer

suffix = None#
class openedx.core.djangoapps.user_api.accounts.views.AccountRetirementView(**kwargs)#

Bases: ViewSet

Provides API endpoint for retiring a user.

basename = None#
static clear_pii_from_certificate_records(user)#

Calls a utility function in the certificates Django app responsible for removing PII (name) from any certificate records associated with the learner being retired.

static clear_pii_from_userprofile(user)#

For the given user, sets all of the user’s profile fields to some retired value. This also deletes all SocialLink objects associated with this user’s profile.

static delete_users_country_cache(user)#
static delete_users_profile_images(user)#
description = None#
detail = None#
name = None#
parser_classes = (<class 'rest_framework.parsers.JSONParser'>,)#
permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>, <class 'openedx.core.djangoapps.user_api.accounts.permissions.CanRetireUser'>)#
post(request)#

POST /api/user/v1/accounts/retire/

``` {

‘username’: ‘user_to_retire’

}#

Retires the user with the given username. This includes retiring this username, the associated email address, and any other PII associated with this user.

static retire_entitlement_support_detail(user)#

Updates all CourseEntitleSupportDetail records for the given user to have an empty comments field.

suffix = None#
class openedx.core.djangoapps.user_api.accounts.views.AccountViewSet(**kwargs)#

Bases: ViewSet

View or update a user’s account information.

account_user_get_responses = {200: {'properties': {'username': {'type': 'string'}}, 'type': 'object'}, 401: ''}#
authentication_classes = (<class 'edx_rest_framework_extensions.auth.jwt.authentication.JwtAuthentication'>, <class 'openedx.core.lib.api.authentication.BearerAuthenticationAllowInactiveUser'>, <class 'edx_rest_framework_extensions.auth.session.authentication.SessionAuthenticationAllowInactiveUser'>)#
basename = None#
description = None#
detail = None#
get(request)#

Return an authenticated user’s username

Example Requests

GET /api/user/v1/me[?view=shared]

list(request)#

Return a list of user details objects

Example Requests

GET /api/user/v1/accounts?usernames={username1,username2}[?view=shared]

GET /api/user/v1/accounts?email={user_email} (staff only)

GET /api/user/v1/accounts?lms_user_id={user_email} (staff only)

Responses

If no user exists with the specified username, or email, an HTTP 404 “Not Found” response is returned.

If the user makes the request for her own account, or makes a request for another account and has “is_staff” access, an HTTP 200 “OK” response is returned.

The response consists of a list of one or more user objects, in the same format as is returned for GET /user/v1/accounts/{username}.

name = None#
parser_classes = (<class 'rest_framework.parsers.JSONParser'>, <class 'openedx.core.lib.api.parsers.MergePatchParser'>)#
partial_update(request, username)#

Update user account or profile information

Example Requests

Content-Type: application/merge-patch+json

PATCH /api/user/v1/accounts/{username}

**Request Body

{

“level_of_education”: “m”, “extended_profile”:

[

{“field_name”: “favorite_beatle”, “field_value”: {“name”: “ringo”}}, {“field_name”: “conlangs_spoken”, “field_value”:[“Láadan”, “Rikchik”, “Lojban”]}

]

}

Notes regarding `social_links`

Requested updates to social_links are automatically merged with previously set links. That is, any newly introduced platforms are add to the previous list. Updated links to pre-existing platforms replace their values in the previous list. Pre-existing platforms can be removed by setting the value of the social_link to an empty string (“”).

Response Values for PATCH

Users can only modify their own account information. If the requesting user does not have the specified username and has staff access, the request returns an HTTP 403 “Forbidden” response. If the requesting user does not have staff access, the request returns an HTTP 404 “Not Found” response to avoid revealing the existence of the account.

If no user exists with the specified username, an HTTP 404 “Not Found” response is returned.

If “application/merge-patch+json” is not the specified content type, a 415 “Unsupported Media Type” response is returned.

If validation errors prevent the update, this method returns a 400 “Bad Request” response that includes a “field_errors” field that lists all error messages. This will happen if an attempt is made to edit any read-only fields.

If a failure at the time of the update prevents the update, a 400 “Bad Request” error is returned. The JSON collection contains specific errors.

If the update is successful, updated user account data is returned.

permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>, <class 'openedx.core.djangoapps.user_api.accounts.permissions.CanGetAccountInfo'>)#
retrieve(request, username)#

Retrieve a single detailed user object

Example Requests

GET /api/user/v1/accounts/{username}/

Response

If no user exists with the specified username, or email, an HTTP 404 “Not Found” response is returned.

If the user makes the request for her own account, or makes a request for another account and has “is_staff” access, an HTTP 200 “OK” response is returned. The response contains the following values.

  • id: numerical lms user id in db

  • bio: null or textual representation of user biographical information (“about me”).

  • country: An ISO 3166 country code or null.

  • date_joined: The date the account was created, in the string format provided by datetime. For example, “2014-08-26T17:52:11Z”.

  • last_login: The latest date the user logged in, in the string datetime format.

  • email: Email address for the user. New email addresses must be confirmed via a confirmation email, so GET does not reflect the change until the address has been confirmed.

  • secondary_email: A secondary email address for the user. Unlike the email field, GET will reflect the latest update to this field even if changes have yet to be confirmed.

  • verified_name: Approved verified name of the learner present in name affirmation plugin

  • extended_profile: A list of objects with the keys field_name and field_value, returning any populated extended_profile_fields configured in the Site Configuration

  • gender: One of the following values:
    • null

    • “f”

    • “m”

    • “o”

  • goals: The textual representation of the user’s goals, or null.

  • is_active: Boolean representation of whether a user is active.

  • language: The user’s preferred language, or null.

  • language_proficiencies: Array of language preferences. Each preference is a JSON object with the following keys:
    • “code”: string ISO 639-1 language code e.g. “en”.

  • level_of_education: One of the following values:
    • “p”: PhD or Doctorate

    • “m”: Master’s or professional degree

    • “b”: Bachelor’s degree

    • “a”: Associate’s degree

    • “hs”: Secondary/high school

    • “jhs”: Junior secondary/junior high/middle school

    • “el”: Elementary/primary school

    • “none”: None

    • “o”: Other

    • null: The user did not enter a value

  • mailing_address: The textual representation of the user’s mailing address, or null.

  • name: The full name of the user.

  • profile_image: A JSON representation of a user’s profile image information. This representation has the following keys.
    • “has_image”: Boolean indicating whether the user has a profile image.

    • “image_url_*”: Absolute URL to various sizes of a user’s profile image, where ‘*’ matches a representation of the corresponding image size, such as ‘small’, ‘medium’, ‘large’, and ‘full’. These are configurable via PROFILE_IMAGE_SIZES_MAP.

  • requires_parental_consent: True if the user is a minor requiring parental consent.

  • social_links: Array of social links, sorted alphabetically by “platform”. Each preference is a JSON object with the following keys:
    • “platform”: A particular social platform, ex: ‘facebook’

    • “social_link”: The link to the user’s profile on the particular platform

  • username: The username associated with the account.

  • year_of_birth: The year the user was born, as an integer, or null.

  • account_privacy: The user’s setting for sharing her personal profile. Possible values are “all_users”, “private”, or “custom”. If “custom”, the user has selectively chosen a subset of shareable fields to make visible to others via the User Preferences API.

  • phone_number: The phone number for the user. String of numbers with an optional + sign at the start.

  • pending_name_change: If the user has an active name change request, returns the requested name.

For all text fields, plain text instead of HTML is supported. The data is stored exactly as specified. Clients must HTML escape rendered values to avoid script injections.

If a user who does not have “is_staff” access requests account information for a different user, only a subset of these fields is returned. The returned fields depend on the ACCOUNT_VISIBILITY_CONFIGURATION configuration setting and the visibility preference of the user for whom data is requested.

A user can view which account fields they have shared with other users by requesting their own username and providing the “view=shared” URL parameter.

search_emails(request)#

Return information about users associated with a list of email addresses

Example Requests

POST /api/user/v1/accounts/search_emails

{

“emails”: [”edx@example.com”, “staff@example.com”]

}

Response

If no emails key is present in the request, or the user does not have “is_staff” access, an HTTP 404 “Not Found” response is returned.

If the has “is_staff” access, an HTTP 200 “OK” response is returned. The response contains the following values.

[
{

“username”: “edx”, “email”: “edx@example.com”, “id”: 3,

}, {

“username”: “staff”, “email”: “staff@example.com”, “id”: 8,

}

]

suffix = None#
class openedx.core.djangoapps.user_api.accounts.views.CancelAccountRetirementStatusView(**kwargs)#

Bases: ViewSet

Provides API endpoints for canceling retirement process for a user’s account.

basename = None#
cancel_retirement(request)#

POST /api/user/v1/accounts/cancel_retirement/

Cancels the retirement for a user’s account. This also handles the top level error handling, and permissions.

description = None#
detail = None#
name = None#
permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>, <class 'openedx.core.djangoapps.user_api.accounts.permissions.CanCancelUserRetirement'>)#
suffix = None#
class openedx.core.djangoapps.user_api.accounts.views.DeactivateLogoutView(**kwargs)#

Bases: APIView

POST /api/user/v1/accounts/deactivate_logout/ {

“password”: “example_password”,

}

POST Parameters

A POST request must include the following parameter.

  • password: Required. The current password of the user being deactivated.

POST Response Values

If the request does not specify a username or submits a username for a non-existent user, the request returns an HTTP 404 “Not Found” response.

If a user who is not a superuser tries to deactivate a user, the request returns an HTTP 403 “Forbidden” response.

If the specified user is successfully deactivated, the request returns an HTTP 204 “No Content” response.

If an unanticipated error occurs, the request returns an HTTP 500 “Internal Server Error” response.

Allows an LMS user to take the following actions: - Change the user’s password permanently to Django’s unusable password - Log the user out - Create a row in the retirement table for that user

authentication_classes = (<class 'edx_rest_framework_extensions.auth.jwt.authentication.JwtAuthentication'>, <class 'rest_framework.authentication.SessionAuthentication'>, <class 'openedx.core.lib.api.authentication.BearerAuthentication'>)#
permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
post(request)#

POST /api/user/v1/accounts/deactivate_logout/

Marks the user as having no password set for deactivation purposes, and logs the user out.

class openedx.core.djangoapps.user_api.accounts.views.LMSAccountRetirementView(**kwargs)#

Bases: ViewSet

Provides an API endpoint for retiring a user in the LMS.

basename = None#
description = None#
detail = None#
name = None#
parser_classes = (<class 'rest_framework.parsers.JSONParser'>,)#
permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>, <class 'openedx.core.djangoapps.user_api.accounts.permissions.CanRetireUser'>)#
post(request)#

POST /api/user/v1/accounts/retire_misc/

``` {

‘username’: ‘user_to_retire’

}#

Retires the user with the given username in the LMS.

suffix = None#
class openedx.core.djangoapps.user_api.accounts.views.NameChangeView(**kwargs)#

Bases: ViewSet

Viewset to manage profile name change requests.

basename = None#
confirm(request, username)#

POST /api/user/v1/account/name_change/{username}/confirm

Confirm a name change request for the specified user, and update their profile name.

create(request)#

POST /api/user/v1/accounts/name_change/

Request a profile name change. This creates a PendingNameChange to be verified later, rather than updating the user’s profile name directly.

Example request:
{

“name”: “Jon Doe”

}

description = None#
detail = None#
name = None#
permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
suffix = None#
class openedx.core.djangoapps.user_api.accounts.views.UsernameReplacementView(**kwargs)#

Bases: APIView

WARNING: This API is only meant to be used as part of a larger job that updates usernames across all services. DO NOT run this alone or users will not match across the system and things will be broken.

API will receive a list of current usernames and their requested new username. If their new username is taken, it will randomly assign a new username.

This API will be called first, before calling the APIs in other services as this one handles the checks on the usernames provided.

permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>, <class 'openedx.core.djangoapps.user_api.accounts.permissions.CanReplaceUsername'>)#
post(request)#

POST /api/user/v1/accounts/replace_usernames/ ``` {

“username_mappings”: [

{“current_username_1”: “desired_username_1”}, {“current_username_2”: “desired_username_2”}

]

}#

POST Parameters

A POST request must include the following parameter.

  • username_mappings: Required. A list of objects that map the current username (key) to the desired username (value)

POST Response Values

As long as data validation passes, the request will return a 200 with a new mapping of old usernames (key) to new username (value)

``` {

“successful_replacements”: [

{“old_username_1”: “new_username_1”}

], “failed_replacements”: [

{“old_username_2”: “new_username_2”}

]

}#

openedx.core.djangoapps.user_api.accounts.views.request_requires_username(function)#

Requires that a username key containing a truthy value exists in the request.data attribute of the decorated function.

Module contents#

Account constants