Skip to content

Commit

Permalink
capability check for user before importing series (#413)
Browse files Browse the repository at this point in the history
  • Loading branch information
ferishili authored Jan 13, 2025
1 parent ee4c2dc commit 0df4144
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 11 deletions.
2 changes: 1 addition & 1 deletion amd/build/block_manage_series.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion amd/build/block_manage_series.min.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion amd/src/block_manage_series.js
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ export const init = (contextid, ocinstanceid, createseries, series, numseriesall
fail: function(er) {
modal.destroy();
var message = jsstrings[11];
if (er.errorcode === 'importseries_alreadyexists') {
if (['importseries_alreadyexists', 'importseries_notallowed'].includes(er.errorcode)) {
message = er.message;
}
displayError(message);
Expand Down
7 changes: 6 additions & 1 deletion classes/external.php
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,13 @@ public static function import_series(int $contextid, int $ocinstanceid, string $
throw new moodle_exception('importseries_alreadyexists', 'block_opencast');
}

// Perform ACL change.
$apibridge = apibridge::get_instance($params['ocinstanceid']);
// Ensure the import series is allowed.
if (!$apibridge->can_user_import_arbitrary_series($params['seriesid'], $USER->id)) {
throw new moodle_exception('importseries_notallowed', 'block_opencast');
}

// Perform ACL change.
$result = $apibridge->import_series_to_course_with_acl_change($course->id, $params['seriesid'], $USER->id);

if ($result->error) {
Expand Down
39 changes: 39 additions & 0 deletions classes/local/apibridge.php
Original file line number Diff line number Diff line change
Expand Up @@ -3155,4 +3155,43 @@ public function can_start_workflow_massaction($courseid) {
$context = context_course::instance($courseid);
return has_capability('block/opencast:startworkflow', $context);
}

/**
* Checks if the user has the capability to import arbitrary series into a course.
* This method looks for the current series mapping records based on the series id, and checks if the user has
* the capability to import series in any of the currently mapped courses to the series.
* If there is no mapping record, it allows the user to import the series.
*
* @param string $seriesid The ID of the series to be imported.
* @param int $userid The ID of the user performing the import.
*
* @return bool True if the user is somehow capable to import the series to any mapped courses, false otherwise.
*/
public function can_user_import_arbitrary_series(string $seriesid, int $userid): bool {
// Step 1: Get current series mapping records.
$mappings = seriesmapping::get_records(['series' => $seriesid, 'ocinstanceid' => $this->ocinstanceid], 'courseid');

// Step 2: Check if the mapping is empty, then allow it to be imported.
// It makes sense to allow it to be imported, because it means the series is new and it has never been introduced
// into the Moodle Opencast world!
if (empty($mappings)) {
return true;
}

// Step 3: create a flag to hold the validation value.
$isallowed = false;

// Step 4: Loop through the series mapping records,
// to find out if the user is by any chance the capability to import series in any of the mapped courses.
foreach ($mappings as $mapping) {
$context = context_course::instance($mapping->get('courseid'));
if (has_capability('block/opencast:importseriesintocourse', $context, $userid)) {
$isallowed = true;
break;
}
}

// Finall, we return the result of the check.
return $isallowed;
}
}
1 change: 1 addition & 0 deletions lang/en/block_opencast.php
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@
$string['importmodedesc'] = 'In order to define an approach to import videos into a course, a mode should be seleted. The default mode is Duplicating Events in which a new series would be created and events will be avaible in the series by using a dupliaction workflow. <br /> ACL Change approach on the other hand will use the same seriesid among courses but series and events\' ACLs are changes to grant access from the course which imports the videos.<br /><strong>NOTE:</strong> At the moment, the selection of events in import wizards (course and manual) for "ACL Change" is NOT possible, due to avoiding further complications in terms of permissions in Opencast.';
$string['importseries'] = 'Import series';
$string['importseries_alreadyexists'] = 'The series you are trying to import is already present. Please choose a different series.';
$string['importseries_notallowed'] = 'Importing this series into this course is not allowed. Please select a different series or contact the system administrator for assistance.';
$string['importseries_succeeded'] = 'The series has been successfully imported.';
$string['importvideos_aclprocessingexplanation'] = 'The seriesid of the selected course will be used in this course and the series\' ACL as well as ACLs of its videos will be changed accordingly.';
$string['importvideos_errornotenabledorworking'] = 'The import videos feature is not enabled or not working';
Expand Down
64 changes: 57 additions & 7 deletions tests/behat/block_opencast_manageseries.feature
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ Feature: Manage series as Teacher
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
| Course 2 | C2 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| teacher1 | C2 | editingteacher |
# Role Manager is required for teachers to be able to import series into a course.
| teacher1 | C1 | manager |
And I setup the default settigns for opencast plugins
And the following config values are set as admin:
| config | value | plugin |
Expand All @@ -35,7 +39,8 @@ Feature: Manage series as Teacher

@javascript
Scenario: Teachers should be able to create a new series
When I click on "Go to overview..." "link"
When I am on the "C1" "Course" page logged in as "teacher1"
And I click on "Go to overview..." "link"
And I click on "Manage series" "link"
Then I should see "Test series"
When I click on "Create new series" "button"
Expand All @@ -50,7 +55,8 @@ Feature: Manage series as Teacher

@javascript
Scenario: Teachers should be able to edit an existing series
When I click on "Go to overview..." "link"
When I am on the "C1" "Course" page logged in as "teacher1"
And I click on "Go to overview..." "link"
And I click on "Manage series" "link"
Then I should see "Test series"
When I click on ".tabulator-row-odd i.fa-edit" "css_element"
Expand All @@ -67,15 +73,17 @@ Feature: Manage series as Teacher
Given the following config values are set as admin:
| config | value | plugin |
| maxseries_1 | 1 | block_opencast |
When I click on "Go to overview..." "link"
When I am on the "C1" "Course" page logged in as "teacher1"
And I click on "Go to overview..." "link"
And I click on "Manage series" "link"
Then I should not see "Create new series"
And I should not see "Import series"

@javascript
Scenario: Teachers should be able to select a different default series
Given I create a second series
When I click on "Go to overview..." "link"
When I am on the "C1" "Course" page logged in as "teacher1"
And I click on "Go to overview..." "link"
And I click on "Manage series" "link"
And I click on ".tabulator-row-even input[name=\"defaultseries\"]" "css_element"
Then I should see "Do you really want to use this series as new default series"
Expand All @@ -86,7 +94,8 @@ Feature: Manage series as Teacher
@javascript
Scenario: Teachers should be able to delete a series but should not be able to delete the default series
Given I create a second series
When I click on "Go to overview..." "link"
When I am on the "C1" "Course" page logged in as "teacher1"
And I click on "Go to overview..." "link"
And I click on "Manage series" "link"
And I click on ".tabulator-row-even i.fa-trash" "css_element"
Then I should see "Are you sure you want to delete this series"
Expand All @@ -100,7 +109,8 @@ Feature: Manage series as Teacher

@javascript
Scenario: Teachers should be able to import a series but should not be able to import a series twice
When I click on "Go to overview..." "link"
When I am on the "C1" "Course" page logged in as "teacher1"
And I click on "Go to overview..." "link"
And I click on "Manage series" "link"
And I click on "Import series" "button"
And I set the field "Series ID" to "1111-1111-1111-1111-1111"
Expand All @@ -115,7 +125,9 @@ Feature: Manage series as Teacher

@javascript
Scenario: When manually deleting a block, teacher will be asked to decide whether to delete seriesmapping in a confirmation.
When I open the action menu in "Opencast Videos" "block"
When I am on the "C1" "Course" page logged in as "teacher1"
And I turn editing mode on
And I open the action menu in "Opencast Videos" "block"
And I click on "Delete Opencast Videos block" "link"
Then I should see "Remove Opencast Block?"
When I click on "Delete block, but keep series mapping" "link"
Expand All @@ -132,3 +144,41 @@ Feature: Manage series as Teacher
And I click on "Go to overview..." "link"
And I click on "Manage series" "link"
Then I should see "No series is defined yet."

@javascript
Scenario: Import a series to a course is only possible when the teacher has the capability to do so in any of the mapped courses to a series
Given the following config values are set as admin:
| config | value | plugin |
| maxseries_1 | 2 | block_opencast |
And I am on "Course 2" course homepage with editing mode on
And I add the "Opencast Videos" block
And I click on "Go to overview..." "link"
And I click on "Manage series" "link"
And I click on "Import series" "button"
And I set the field "Series ID" to "1111-1111-1111-1111-1111"
When I click on "Import series" "button" in the ".modal" "css_element"
And I wait "1" seconds
Then I should see "The series has been successfully imported."
When I am on the "C1" "Course" page logged in as "teacher1"
And I click on "Go to overview..." "link"
And I click on "Manage series" "link"
And I click on "Import series" "button"
And I set the field "Series ID" to "1111-1111-1111-1111-1111"
When I click on "Import series" "button" in the ".modal" "css_element"
And I wait "1" seconds
Then I should see "Importing this series into this course is not allowed. Please select a different series or contact the system administrator for assistance."
When I am on the "C2" "Course" page logged in as "admin"
And I navigate to course participants
And I click on "Teacher 1's role assignments" "link"
And I type "Manager"
And I press the enter key
And I click on "Save changes" "link"
Then I should see "Manager" in the "Teacher 1" "table_row"
When I am on the "C2" "Course" page logged in as "teacher1"
And I click on "Go to overview..." "link"
And I click on "Manage series" "link"
And I click on "Import series" "button"
And I set the field "Series ID" to "1234-1234-1234-1234-1234"
When I click on "Import series" "button" in the ".modal" "css_element"
And I wait "1" seconds
Then I should see "The series has been successfully imported."

0 comments on commit 0df4144

Please sign in to comment.