diff --git a/docs/docs/rights_engine.md b/docs/docs/rights_engine.md index 74142e09080771a9d4a3208f23f686581280402d..22bd1e1360e69ab05dda08859b409a0415478857 100644 --- a/docs/docs/rights_engine.md +++ b/docs/docs/rights_engine.md @@ -82,3 +82,29 @@ Response (HTTP 200) ```js {"message": "xAPI statements successfully stored in LRS", "data": ["6411d628e31a30251d6391f0"]} ``` + +### Anonymized xAPI proxy endpoint + +In addition to the aforementioned endpoint for regular xAPI statements, the rights engine offers an endpoint to submit anonymized statements which are not directly associated with a user. +This works by supplying a "TAN", an arbitrary string sequence, instead of the usual user account information. +Providers have to keep a list / matching of TANs and users, since the rights engine has no way of knowing which user a given TAN belongs to. + +The endpoint is available at `[BASE_URL]/xapi/statements` and accepts valid xAPI statements that contain a TAN in the user object. + +#### Example + +```console +$ curl -i -X POST http://localhost:9001/xapi/tanStatements --data '{ "actor": {"objectType": "Agent", "tan": "u4gueb983fnklerg"}, "timestamp": "2022-03-18T18:07:32+01:00", "context": { "platform": "Moodle", "contextActivities": { "category": { "objectType": "Activity", "definition": { "type": "https://xapi.elearn.rwth-aachen.de/definitions/lms/activities/lms", "name": { "de": "moosltest" } }, "id": "https://moosltest.it-services.ruhr-uni-bochum.de" }, "grouping": [ { "objectType": "Activity", "definition": { "type": "https://xapi.elearn.rwth-aachen.de/definitions/lms/activities/course", "name": { "de": "Structured Query Language" } }, "id": "https://moosltest.it-services.ruhr-uni-bochum.de/course/view.php?id=2" }, { "objectType": "Activity", "id": "https://moosltest.it-services.ruhr-uni-bochum.de/mod/quiz/view.php?id=2", "definition": { "type": "https://xapi.elearn.rwth-aachen.de/definitions/lms/activities/quiz", "name": { "de": "SQL-Test" } } } ] }, "extensions": { "https://xapi.elearn.rwth-aachen.de/definitions/lms/activities/course/extensions/roles": "student", "https://xapi.elearn.rwth-aachen.de/definitions/lms/activities/quiz_attempt/extensions/timestart": 1647610537, "https://xapi.elearn.rwth-aachen.de/definitions/lms/activities/quiz_attempt/extensions/timefinish": 1647623252 } }, "verb": { "id": "https://xapi.elearn.rwth-aachen.de/definitions/lms/verbs/accessed" }, "object": { "objectType": "Activity", "id": "https://xapi.elearn.rwth-aachen.de/definitions/lms/activities/course", "definition": { "type": "https://xapi.elearn.rwth-aachen.de/definitions/lms/activities/quiz_attempt", "name": { "de": "SQL-Test" } } }, "result": { "score": { "raw": 0 } } }' -H "Content-Type: application/json" -H "Authorization: Basic ff9b69722ad9fcf3c77cf7a54b31da6c651f546101ded46f03e53a8f008a66de" +``` + +Error response when the endpoint is used without a TAN (HTTP 400) + +```js +{"message": "xAPI statements couldn't be stored in LRS", "data": [{"valid": false, "reason": "TAN missing in statement"}] +``` + +The other responses are analogous to the non-anonymized endpoint. + +Users can associate anonymized data to their account by using the merge tool included in the frontend. +For data to be associated, a user has to give a correct TAN and provider. +In order to prevent abuse by brute-forcing TANs, this tool is rate-limited per user. \ No newline at end of file diff --git a/src/frontend/src/app/merge-data/merge-data.component.html b/src/frontend/src/app/merge-data/merge-data.component.html index 9c7fa9ae56b839e8045fca15c1af09054e25f553..c1ed11ae748d8f2bacb96fce242265719fa39e7d 100644 --- a/src/frontend/src/app/merge-data/merge-data.component.html +++ b/src/frontend/src/app/merge-data/merge-data.component.html @@ -2,25 +2,27 @@ <mat-card style='margin: 8px;'> <mat-card-title i18n="Merge Data | Header entry @@mergeDataHeader"> Merge Data - </mat-card-title> - <mat-card-content> - - <form [formGroup]="mergeForm" (ngSubmit)="submit()"> - <mat-form-field> - <mat-label>Provider</mat-label> - <mat-select formControlName="provider"> - <mat-option *ngFor="let provider of providers" [value]="provider.id">{{ provider.name }}</mat-option> - </mat-select> - </mat-form-field> - <br> - <mat-form-field> - <mat-label>TAN</mat-label> - <input matInput formControlName="tan"> - </mat-form-field> - <br> - <button type="submit" mat-raised-button i18n="Merge Data | Header entry @@mergeDataHeader">Merge Data</button> - </form> - </mat-card-content> + </mat-card-title> + <mat-card-subtitle i18n="@@mergeDataDescription"> + This tool enables you to associate data which has been anonymized by use of a TAN to your account. All entries which match the given TAN and provider will be assigned. + </mat-card-subtitle> + <mat-card-content> + <form [formGroup]="mergeForm" (ngSubmit)="submit()"> + <mat-form-field> + <mat-label>Provider</mat-label> + <mat-select formControlName="provider"> + <mat-option *ngFor="let provider of providers" [value]="provider.id">{{ provider.name }}</mat-option> + </mat-select> + </mat-form-field> + <br> + <mat-form-field> + <mat-label>TAN</mat-label> + <input matInput formControlName="tan"> + </mat-form-field> + <br> + <button type="submit" mat-raised-button i18n="Merge Data | Header entry @@mergeDataHeader">Merge Data</button> + </form> + </mat-card-content> </mat-card> </div> diff --git a/src/frontend/src/locale/messages.de.xlf b/src/frontend/src/locale/messages.de.xlf index e2d8dc375a4febaef3b47139c27b80ea66677ac6..0f8c52018b81756db7b52a8e650774927a9a4777 100644 --- a/src/frontend/src/locale/messages.de.xlf +++ b/src/frontend/src/locale/messages.de.xlf @@ -274,6 +274,15 @@ <note priority="1" from="description"> Header entry </note> <note priority="1" from="meaning">Merge Data </note> </trans-unit> + <trans-unit id="mergeDataDescription" datatype="html"> + <source>This tool enables you to associate data which has been anonymized by use of a TAN to your account. All entries which match the given TAN and provider will be assigned.</source> + <target>Dieses Werkzeug ermöglicht es, Daten, welche mittels einer TAN anonymisiert sind, zum aktuellen Nutzer zuzuordnen. Alle Einträge, welche auf die angegebene TAN und den angegebenen Provider zutreffen, werden zugeordnet.</target> + <context-group purpose="location"> + <context context-type="sourcefile">src/app/merge-data/merge-data.component.html</context> + <context context-type="linenumber">7</context> + </context-group> + </trans-unit> + <trans-unit id="profileProfileDropDown" datatype="html"> <source>Profile</source> <target>Profil</target> diff --git a/src/frontend/src/locale/messages.xlf b/src/frontend/src/locale/messages.xlf index 197fba2c6314644d2cd41f3282ad13ad1a7e4c23..f70d4948c3e0b8c1805050c7b506fd8fd58b7d64 100644 --- a/src/frontend/src/locale/messages.xlf +++ b/src/frontend/src/locale/messages.xlf @@ -1124,6 +1124,13 @@ <note priority="1" from="description"> Header entry </note> <note priority="1" from="meaning">Merge Data </note> </trans-unit> + <trans-unit id="mergeDataDescription" datatype="html"> + <source>This tool enables you to associate data which has been anonymized by use of a TAN to your account. All entries which match the given TAN and provider will be assigned.</source> + <context-group purpose="location"> + <context context-type="sourcefile">src/app/merge-data/merge-data.component.html</context> + <context context-type="linenumber">7</context> + </context-group> + </trans-unit> <trans-unit id="applicationTokens" datatype="html"> <source>Application Tokens</source> <context-group purpose="location">