diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4d35ddd0..7b8ba72f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -11,10 +11,8 @@ Change Log .. There should always be an "Unreleased" section for changes pending release. - - Unreleased -__________ +----------- @@ -24,8 +22,8 @@ __________ Added ~~~~~ -* Adds event ``CONTENT_OBJECT_ASSOCIATIONS_CHANGED`` -* Adds ``ContentObjectChangedData``, which inherits from ContentObjectData and adds an optional list of string ``changes``. +* Added new ``LIBRARY_COLLECTION_CREATED``, ``LIBRARY_COLLECTION_UPDATED``, ``LIBRARY_COLLECTION_DELETED``, + and ``CONTENT_OBJECT_ASSOCIATIONS_CHANGED`` events in content_authoring. Deprecated ~~~~~~~~~~ @@ -37,9 +35,9 @@ Deprecated --------------------- Added -~~~~~ +~~~~~~~ -* Added new ``LIBRARY_COLLECTION_CREATED``, ``LIBRARY_COLLECTION_UPDATED`` and ``LIBRARY_COLLECTION_DELETED`` events in content_authoring. +* Added new IDV events ``LEARNER_CREDIT_COURSE_ENROLLMENT_REVOKED``, ``IDV_ATTEMPT_CREATED``, ``IDV_ATTEMPT_PENDING``, ``IDV_ATTEMPT_APPROVED``, and ``IDV_ATTEMPT_DENIED`` in learning. [9.12.0] - 2024-07-31 --------------------- diff --git a/openedx_events/event_bus/avro/tests/schemas/org+openedx+learning+idv_attempt+approved+v1_schema.avsc b/openedx_events/event_bus/avro/tests/schemas/org+openedx+learning+idv_attempt+approved+v1_schema.avsc new file mode 100644 index 00000000..e6a186ae --- /dev/null +++ b/openedx_events/event_bus/avro/tests/schemas/org+openedx+learning+idv_attempt+approved+v1_schema.avsc @@ -0,0 +1,79 @@ +{ + "name": "CloudEvent", + "type": "record", + "doc": "Avro Event Format for CloudEvents created with openedx_events/schema", + "fields": [ + { + "name": "idv_attempt", + "type": { + "name": "VerificationAttemptData", + "type": "record", + "fields": [ + { + "name": "attempt_id", + "type": "long" + }, + { + "name": "user", + "type": { + "name": "UserData", + "type": "record", + "fields": [ + { + "name": "id", + "type": "long" + }, + { + "name": "is_active", + "type": "boolean" + }, + { + "name": "pii", + "type": { + "name": "UserPersonalData", + "type": "record", + "fields": [ + { + "name": "username", + "type": "string" + }, + { + "name": "email", + "type": "string" + }, + { + "name": "name", + "type": "string" + } + ] + } + } + ] + } + }, + { + "name": "status", + "type": "string" + }, + { + "name": "name", + "type": [ + "null", + "string" + ], + "default": null + }, + { + "name": "expiration_date", + "type": [ + "null", + "string" + ], + "default": null + } + ] + } + } + ], + "namespace": "org.openedx.learning.idv_attempt.approved.v1" +} \ No newline at end of file diff --git a/openedx_events/event_bus/avro/tests/schemas/org+openedx+learning+idv_attempt+created+v1_schema.avsc b/openedx_events/event_bus/avro/tests/schemas/org+openedx+learning+idv_attempt+created+v1_schema.avsc new file mode 100644 index 00000000..665f18ad --- /dev/null +++ b/openedx_events/event_bus/avro/tests/schemas/org+openedx+learning+idv_attempt+created+v1_schema.avsc @@ -0,0 +1,79 @@ +{ + "name": "CloudEvent", + "type": "record", + "doc": "Avro Event Format for CloudEvents created with openedx_events/schema", + "fields": [ + { + "name": "idv_attempt", + "type": { + "name": "VerificationAttemptData", + "type": "record", + "fields": [ + { + "name": "attempt_id", + "type": "long" + }, + { + "name": "user", + "type": { + "name": "UserData", + "type": "record", + "fields": [ + { + "name": "id", + "type": "long" + }, + { + "name": "is_active", + "type": "boolean" + }, + { + "name": "pii", + "type": { + "name": "UserPersonalData", + "type": "record", + "fields": [ + { + "name": "username", + "type": "string" + }, + { + "name": "email", + "type": "string" + }, + { + "name": "name", + "type": "string" + } + ] + } + } + ] + } + }, + { + "name": "status", + "type": "string" + }, + { + "name": "name", + "type": [ + "null", + "string" + ], + "default": null + }, + { + "name": "expiration_date", + "type": [ + "null", + "string" + ], + "default": null + } + ] + } + } + ], + "namespace": "org.openedx.learning.idv_attempt.created.v1" +} \ No newline at end of file diff --git a/openedx_events/event_bus/avro/tests/schemas/org+openedx+learning+idv_attempt+denied+v1_schema.avsc b/openedx_events/event_bus/avro/tests/schemas/org+openedx+learning+idv_attempt+denied+v1_schema.avsc new file mode 100644 index 00000000..4059bcf4 --- /dev/null +++ b/openedx_events/event_bus/avro/tests/schemas/org+openedx+learning+idv_attempt+denied+v1_schema.avsc @@ -0,0 +1,79 @@ +{ + "name": "CloudEvent", + "type": "record", + "doc": "Avro Event Format for CloudEvents created with openedx_events/schema", + "fields": [ + { + "name": "idv_attempt", + "type": { + "name": "VerificationAttemptData", + "type": "record", + "fields": [ + { + "name": "attempt_id", + "type": "long" + }, + { + "name": "user", + "type": { + "name": "UserData", + "type": "record", + "fields": [ + { + "name": "id", + "type": "long" + }, + { + "name": "is_active", + "type": "boolean" + }, + { + "name": "pii", + "type": { + "name": "UserPersonalData", + "type": "record", + "fields": [ + { + "name": "username", + "type": "string" + }, + { + "name": "email", + "type": "string" + }, + { + "name": "name", + "type": "string" + } + ] + } + } + ] + } + }, + { + "name": "status", + "type": "string" + }, + { + "name": "name", + "type": [ + "null", + "string" + ], + "default": null + }, + { + "name": "expiration_date", + "type": [ + "null", + "string" + ], + "default": null + } + ] + } + } + ], + "namespace": "org.openedx.learning.idv_attempt.denied.v1" +} \ No newline at end of file diff --git a/openedx_events/event_bus/avro/tests/schemas/org+openedx+learning+idv_attempt+pending+v1_schema.avsc b/openedx_events/event_bus/avro/tests/schemas/org+openedx+learning+idv_attempt+pending+v1_schema.avsc new file mode 100644 index 00000000..6e3d639b --- /dev/null +++ b/openedx_events/event_bus/avro/tests/schemas/org+openedx+learning+idv_attempt+pending+v1_schema.avsc @@ -0,0 +1,79 @@ +{ + "name": "CloudEvent", + "type": "record", + "doc": "Avro Event Format for CloudEvents created with openedx_events/schema", + "fields": [ + { + "name": "idv_attempt", + "type": { + "name": "VerificationAttemptData", + "type": "record", + "fields": [ + { + "name": "attempt_id", + "type": "long" + }, + { + "name": "user", + "type": { + "name": "UserData", + "type": "record", + "fields": [ + { + "name": "id", + "type": "long" + }, + { + "name": "is_active", + "type": "boolean" + }, + { + "name": "pii", + "type": { + "name": "UserPersonalData", + "type": "record", + "fields": [ + { + "name": "username", + "type": "string" + }, + { + "name": "email", + "type": "string" + }, + { + "name": "name", + "type": "string" + } + ] + } + } + ] + } + }, + { + "name": "status", + "type": "string" + }, + { + "name": "name", + "type": [ + "null", + "string" + ], + "default": null + }, + { + "name": "expiration_date", + "type": [ + "null", + "string" + ], + "default": null + } + ] + } + } + ], + "namespace": "org.openedx.learning.idv_attempt.pending.v1" +} \ No newline at end of file diff --git a/openedx_events/learning/data.py b/openedx_events/learning/data.py index ba22df9a..962dda35 100644 --- a/openedx_events/learning/data.py +++ b/openedx_events/learning/data.py @@ -589,3 +589,23 @@ class BadgeData: uuid = attr.ib(type=str) user = attr.ib(type=UserData) template = attr.ib(type=BadgeTemplateData) + + +@attr.s(frozen=True) +class VerificationAttemptData: + """ + Attributes defined for the Open edX IDV attempt data object. + + Arguments: + attempt_id (int): the id of the verification attempt + user (User): the user (usually a learner) performing the verification attempt. + status (string): the status of the verification attempt. + name (string): the name being ID verified. Defaults to None. + expiration_datetime (datetime, optional): When the verification attempt expires. Defaults to None. + """ + + attempt_id = attr.ib(type=int) + user = attr.ib(type=UserData) + status = attr.ib(type=str) + name = attr.ib(type=str, default=None) + expiration_date = attr.ib(type=datetime, default=None) diff --git a/openedx_events/learning/signals.py b/openedx_events/learning/signals.py index d3970066..68fd2118 100644 --- a/openedx_events/learning/signals.py +++ b/openedx_events/learning/signals.py @@ -25,6 +25,7 @@ ProgramCertificateData, UserData, UserNotificationData, + VerificationAttemptData, XBlockSkillVerificationData, ) from openedx_events.tooling import OpenEdxPublicSignal @@ -401,3 +402,51 @@ "badge": BadgeData, } ) + + +# .. event_type: org.openedx.learning.idv_attempt.created.v1 +# .. event_name: IDV_ATTEMPT_CREATED +# .. event_description: Emitted when an IDV attempt is created +# .. event_data: VerificationAttemptData +IDV_ATTEMPT_CREATED = OpenEdxPublicSignal( + event_type="org.openedx.learning.idv_attempt.created.v1", + data={ + "idv_attempt": VerificationAttemptData, + } +) + + +# .. event_type: org.openedx.learning.idv_attempt.pending.v1 +# .. event_name: IDV_ATTEMPT_PENDING +# .. event_description: Emitted when an IDV attempt is marked as pending +# .. event_data: VerificationAttemptData +IDV_ATTEMPT_PENDING = OpenEdxPublicSignal( + event_type="org.openedx.learning.idv_attempt.pending.v1", + data={ + "idv_attempt": VerificationAttemptData, + } +) + + +# .. event_type: org.openedx.learning.idv_attempt.approved.v1 +# .. event_name: IDV_ATTEMPT_APPROVED +# .. event_description: Emitted when an IDV attempt is approved +# .. event_data: VerificationAttemptData +IDV_ATTEMPT_APPROVED = OpenEdxPublicSignal( + event_type="org.openedx.learning.idv_attempt.approved.v1", + data={ + "idv_attempt": VerificationAttemptData, + } +) + + +# .. event_type: org.openedx.learning.idv_attempt.denied.v1 +# .. event_name: IDV_ATTEMPT_DENIED +# .. event_description: Emitted when an IDV attempt is denied +# .. event_data: VerificationAttemptData +IDV_ATTEMPT_DENIED = OpenEdxPublicSignal( + event_type="org.openedx.learning.idv_attempt.denied.v1", + data={ + "idv_attempt": VerificationAttemptData, + } +)