Skip to content

Commit

Permalink
initial upload visibility control, fixes #187
Browse files Browse the repository at this point in the history
  • Loading branch information
ferishili committed Jan 18, 2022
1 parent 49c3f70 commit bc1a8d3
Show file tree
Hide file tree
Showing 12 changed files with 568 additions and 61 deletions.
15 changes: 14 additions & 1 deletion addvideo.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,21 @@
$options->chunkupload_presenter = isset($chunkuploadpresenter) ? $chunkuploadpresenter : '';
$options->chunkupload_presentation = isset($chunkuploadpresentation) ? $chunkuploadpresentation : '';

// Prepare the visibility object.
$visibility = new \stdClass();
$visibility->initialvisibilitystatus = $data->initialvisibilitystatus;
$visibility->initialvisibilitygroups = !empty($data->initialvisibilitygroups) ?
json_encode($data->initialvisibilitygroups) : null;
// Check if the scheduled visibility is set.
if (isset($data->enableschedulingchangevisibility) && $data->enableschedulingchangevisibility) {
$visibility->scheduledvisibilitytime = $data->scheduledvisibilitytime;
$visibility->scheduledvisibilitystatus = $data->scheduledvisibilitystatus;
$visibility->scheduledvisibilitygroups = !empty($data->scheduledvisibilitygroups) ?
json_encode($data->scheduledvisibilitygroups) : null;
}

// Update all upload jobs.
\block_opencast\local\upload_helper::save_upload_jobs($ocinstanceid, $courseid, $coursecontext, $options);
\block_opencast\local\upload_helper::save_upload_jobs($ocinstanceid, $courseid, $coursecontext, $options, $visibility);
redirect($redirecturl, get_string('uploadjobssaved', 'block_opencast'), null, \core\output\notification::NOTIFY_SUCCESS);
}

Expand Down
102 changes: 102 additions & 0 deletions classes/local/addvideo_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public function definition() {
$mform = $this->_form;

$mform->addElement('header', 'metadata', get_string('metadata', 'block_opencast'));
$mform->setExpanded('metadata', true);

$explanation = \html_writer::tag('p', get_string('metadataexplanation', 'block_opencast'));
$mform->addElement('html', $explanation);
Expand Down Expand Up @@ -150,9 +151,105 @@ public function definition() {
$mform->addElement('date_time_selector', 'startDate', get_string('date', 'block_opencast'));
$mform->setAdvanced('startDate');

// Event Visibility configuration.
$mform->closeHeaderBefore('visibility_header');

$mform->addElement('header', 'visibility_header', get_string('visibilityheader', 'block_opencast'));
$mform->setExpanded('visibility_header', true);

$explanation = \html_writer::tag('p', get_string('visibilityheaderexplanation', 'block_opencast'));
$mform->addElement('html', $explanation);

// Check if the teacher should be allowed to restrict the episode to course groups.
$controlgroupsenabled = get_config('block_opencast', 'aclcontrolgroup_' . $ocinstanceid);
// If group restriction is generally enabled, check if there are roles which allow group visibility.
if ($controlgroupsenabled) {
$roles = $apibridge->getroles(0);
$groupvisibilityallowed = false;
foreach ($roles as $role) {
if (strpos($role->rolename, '[COURSEGROUPID]') >= 0) {
$groupvisibilityallowed = true;
break;
}
}
$groups = groups_get_all_groups($this->_customdata['courseid']);
} else {
$groupvisibilityallowed = false;
}

// Initial visibility.
$intialvisibilityradioarray = array();
$intialvisibilityradioarray[] = $mform->addElement('radio', 'initialvisibilitystatus',
get_string('initialvisibilitystatus', 'block_opencast'), get_string('visibility_hide', 'block_opencast'), 0);
$intialvisibilityradioarray[] = $mform->addElement('radio', 'initialvisibilitystatus',
'', get_string('visibility_show', 'block_opencast'), 1);
if ($groupvisibilityallowed) {
$attributes = array();
if (empty($groups)) {
$attributes = array('disabled' => true);
}
$radioarray[] = $mform->addElement('radio', 'initialvisibilitystatus',
'', get_string('visibility_group', 'block_opencast'), 2, $attributes);
}
$mform->setDefault('initialvisibilitystatus', \block_opencast_renderer::HIDDEN);
$mform->setType('initialvisibilitystatus', PARAM_INT);

// Load existing groups.
if ($groupvisibilityallowed) {
$options = [];
foreach ($groups as $group) {
$options[$group->id] = $group->name;
}
$select = $mform->addElement('select', 'initialvisibilitygroups', get_string('groups'), $options);
$select->setMultiple(true);
$mform->hideIf('initialvisibilitygroups', 'initialvisibilitystatus', 'neq', 2);
}

// Provide a checkbox to enable changing the visibility for later.
$mform->addElement('checkbox', 'enableschedulingchangevisibility',
get_string('enableschedulingchangevisibility', 'block_opencast'),
get_string('enableschedulingchangevisibilitydesc', 'block_opencast'));
$mform->hideIf('scheduledvisibilitytime', 'enableschedulingchangevisibility', 'notchecked');
$mform->hideIf('scheduledvisibilitystatus', 'enableschedulingchangevisibility', 'notchecked');

// Scheduled visibility.
$mform->addElement('date_time_selector', 'scheduledvisibilitytime',
get_string('scheduledvisibilitytime', 'block_opencast'));
$mform->addHelpButton('scheduledvisibilitytime', 'scheduledvisibilitytimehi', 'block_opencast');
$recommendedtimespan = strtotime('+ 21 minutes', strtotime('now'));
$mform->setDefault('scheduledvisibilitytime', $recommendedtimespan);

$radioarray = array();
$radioarray[] = $mform->addElement('radio', 'scheduledvisibilitystatus',
get_string('scheduledvisibilitystatus', 'block_opencast'), get_string('visibility_hide', 'block_opencast'), 0);
$radioarray[] = $mform->addElement('radio', 'scheduledvisibilitystatus', '',
get_string('visibility_show', 'block_opencast'), 1);
if ($groupvisibilityallowed) {
$attributes = array();
if (empty($groups)) {
$attributes = array('disabled' => true);
}
$radioarray[] = $mform->addElement('radio', 'scheduledvisibilitystatus',
'', get_string('visibility_group', 'block_opencast'), 2, $attributes);
}
$mform->setDefault('scheduledvisibilitystatus', \block_opencast_renderer::VISIBLE);
$mform->setType('scheduledvisibilitystatus', PARAM_INT);

// Load existing groups.
if ($groupvisibilityallowed) {
$options = [];
foreach ($groups as $group) {
$options[$group->id] = $group->name;
}
$select = $mform->addElement('select', 'scheduledvisibilitygroups', get_string('groups'), $options);
$select->setMultiple(true);
$mform->hideIf('scheduledvisibilitygroups', 'scheduledvisibilitystatus', 'neq', 2);
}

$mform->closeHeaderBefore('upload_filepicker');

$mform->addElement('header', 'upload_filepicker', get_string('upload', 'block_opencast'));
$mform->setExpanded('upload_filepicker', true);

$explanation = \html_writer::tag('p', get_string('uploadexplanation', 'block_opencast'));
$mform->addElement('html', $explanation);
Expand Down Expand Up @@ -264,6 +361,11 @@ public function validation($data, $files) {
$errors['presentation_already_uploaded'] = get_string('emptyvideouploaderror', 'block_opencast');
}

if (isset($data['enableschedulingchangevisibility']) && $data['enableschedulingchangevisibility'] &&
$data['scheduledvisibilitytime'] < strtotime('+ 20 minutes', strtotime('now'))) {
$errors['scheduledvisibilitytime'] = get_string('scheduledvisibilitytimeerror', 'block_opencast');
}

return $errors;
}

Expand Down
28 changes: 23 additions & 5 deletions classes/local/apibridge.php
Original file line number Diff line number Diff line change
Expand Up @@ -1047,12 +1047,14 @@ public function create_event($job) {

$event = new \block_opencast\local\event();

$roles = $this->getroles();
foreach ($roles as $role) {
foreach ($role->actions as $action) {
$event->add_acl(true, $action, self::replace_placeholders($role->rolename, $job->courseid, null, $job->userid)[0]);
}
// Get initial visibility object.
$initialvisibility = visibility_helper::get_initial_visibility($job);

// Add the event roles from visibility object.
foreach ($initialvisibility->roles as $acl) {
$event->add_acl($acl->allow, $acl->action, $acl->role);
}

// Applying the media types to the event.
$validstoredfile = true;
if ($job->presenter_fileid) {
Expand Down Expand Up @@ -1101,6 +1103,22 @@ public function create_event($job) {
throw new \moodle_exception('serverconnectionerror', 'tool_opencast');
}

// Check if the group visibility is initialy set.
if (!empty($initialvisibility->groups)) {
$res = json_decode($result);
// Store group access based on event identifier.
$this->store_group_access($res->identifier, $initialvisibility->groups);
}

// Check if the visibility job is set and it has no scheduled time.
if (!empty($initialvisibility->visibilityjob) &&
empty($initialvisibility->visibilityjob->scheduledvisibilitytime)) {
$visibilityjob = $initialvisibility->visibilityjob;
// Change the status to complete, since the job finishes here.
$status = visibility_helper::STATUS_DONE;
visibility_helper::change_job_status($visibilityjob, $status);
}

return $result;
}

Expand Down
106 changes: 53 additions & 53 deletions classes/local/ingest_uploader.php
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ public static function create_event($job) {
case self::STATUS_INGEST_ADDING_ACL_ATTACHMENT:
try {

$aclxml = self::create_acl_xml($apibridge->getroles(), $job);
$initialvisibility = visibility_helper::get_initial_visibility($job);
$aclxml = self::create_acl_xml($initialvisibility->roles, $job);

if (version_compare(phpversion(), '8', '>=')) {
$file = new \CURLStringFile($aclxml, 'xacml-episode.xml', 'text/xml');
Expand Down Expand Up @@ -312,58 +313,57 @@ protected static function create_acl_xml($roles, $job) {
$root->setAttributeNode(new \DOMAttr('xmlns', 'urn:oasis:names:tc:xacml:2.0:policy:schema:os'));
$dom->appendChild($root);

foreach ($roles as $role) {
foreach ($role->actions as $roleaction) {
$rolename = apibridge::replace_placeholders($role->rolename, $job->courseid, null, $job->userid)[0];

$el = $dom->createElement('RULE');
$el->setAttributeNode(new \DOMAttr('RuleId', $rolename . '_' . $roleaction . '_PERMIT'));
$el->setAttributeNode(new \DOMAttr('Effect', 'Permit'));
$root->appendChild($el);

$target = $dom->createElement('Target');
$el->appendChild($target);

$actions = $dom->createElement('Actions');
$target->appendChild($actions);

$action = $dom->createElement('Action');
$actions->appendChild($action);

$actionmatch = $dom->createElement('ActionMatch');
$actionmatch->setAttributeNode(new \DOMAttr('MatchId', 'urn:oasis:names:tc:xacml:1.0:function:string-equal'));
$action->appendChild($actionmatch);

$attributevalue = $dom->createElement('AttributeValue', $roleaction);
$attributevalue->setAttributeNode(new \DOMAttr('DataType', 'http://www.w3.org/2001/XMLSchema#string'));
$actionmatch->appendChild($attributevalue);

$actionattributedesignator = $dom->createElement('ActionAttributeDesignator');
$actionattributedesignator->setAttributeNode(new \DOMAttr('AttributeId',
'urn:oasis:names:tc:xacml:1.0:action:action-id'));
$actionattributedesignator->setAttributeNode(new \DOMAttr('DataType',
'http://www.w3.org/2001/XMLSchema#string'));
$actionmatch->appendChild($actionattributedesignator);

$condition = $dom->createElement('Condition');
$el->appendChild($condition);

$apply = $dom->createElement('Apply');
$apply->setAttributeNode(new \DOMAttr('FunctionId',
'urn:oasis:names:tc:xacml:1.0:function:string-is-in'));
$condition->appendChild($apply);

$attributevalue = $dom->createElement('AttributeValue', $rolename);
$attributevalue->setAttributeNode(new \DOMAttr('DataType', 'http://www.w3.org/2001/XMLSchema#string'));
$apply->appendChild($attributevalue);

$subjectattributedesignator = $dom->createElement('SubjectAttributeDesignator');
$subjectattributedesignator->setAttributeNode(new \DOMAttr('AttributeId',
'urn:oasis:names:tc:xacml:2.0:subject:role'));
$subjectattributedesignator->setAttributeNode(new \DOMAttr('DataType',
'http://www.w3.org/2001/XMLSchema#string'));
$apply->appendChild($subjectattributedesignator);
}
foreach ($roles as $acl) {
$rolename = $acl->role;
$roleaction = $acl->action;

$el = $dom->createElement('RULE');
$el->setAttributeNode(new \DOMAttr('RuleId', $rolename . '_' . $roleaction . '_PERMIT'));
$el->setAttributeNode(new \DOMAttr('Effect', 'Permit'));
$root->appendChild($el);

$target = $dom->createElement('Target');
$el->appendChild($target);

$actions = $dom->createElement('Actions');
$target->appendChild($actions);

$action = $dom->createElement('Action');
$actions->appendChild($action);

$actionmatch = $dom->createElement('ActionMatch');
$actionmatch->setAttributeNode(new \DOMAttr('MatchId', 'urn:oasis:names:tc:xacml:1.0:function:string-equal'));
$action->appendChild($actionmatch);

$attributevalue = $dom->createElement('AttributeValue', $roleaction);
$attributevalue->setAttributeNode(new \DOMAttr('DataType', 'http://www.w3.org/2001/XMLSchema#string'));
$actionmatch->appendChild($attributevalue);

$actionattributedesignator = $dom->createElement('ActionAttributeDesignator');
$actionattributedesignator->setAttributeNode(new \DOMAttr('AttributeId',
'urn:oasis:names:tc:xacml:1.0:action:action-id'));
$actionattributedesignator->setAttributeNode(new \DOMAttr('DataType',
'http://www.w3.org/2001/XMLSchema#string'));
$actionmatch->appendChild($actionattributedesignator);

$condition = $dom->createElement('Condition');
$el->appendChild($condition);

$apply = $dom->createElement('Apply');
$apply->setAttributeNode(new \DOMAttr('FunctionId',
'urn:oasis:names:tc:xacml:1.0:function:string-is-in'));
$condition->appendChild($apply);

$attributevalue = $dom->createElement('AttributeValue', $rolename);
$attributevalue->setAttributeNode(new \DOMAttr('DataType', 'http://www.w3.org/2001/XMLSchema#string'));
$apply->appendChild($attributevalue);

$subjectattributedesignator = $dom->createElement('SubjectAttributeDesignator');
$subjectattributedesignator->setAttributeNode(new \DOMAttr('AttributeId',
'urn:oasis:names:tc:xacml:2.0:subject:role'));
$subjectattributedesignator->setAttributeNode(new \DOMAttr('DataType',
'http://www.w3.org/2001/XMLSchema#string'));
$apply->appendChild($subjectattributedesignator);
}

// Add deny rule.
Expand Down
9 changes: 8 additions & 1 deletion classes/local/upload_helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,9 @@ public static function get_upload_jobs($ocinstanceid, $courseid) {
* @param int $courseid Course id
* @param object $coursecontext Course context
* @param object $options Options
* @param object $visibility Visibility object
*/
public static function save_upload_jobs($ocinstanceid, $courseid, $coursecontext, $options) {
public static function save_upload_jobs($ocinstanceid, $courseid, $coursecontext, $options, $visibility = null) {
global $DB, $USER;

// Find the current files for the jobs.
Expand Down Expand Up @@ -218,6 +219,12 @@ public static function save_upload_jobs($ocinstanceid, $courseid, $coursecontext
$options->uploadjobid = $uploadjobid;
$DB->insert_record('block_opencast_metadata', $options);

// Check if visibility object is set, then we insert the visibility records.
if (!empty($visibility)) {
$visibility->uploadjobid = $uploadjobid;
visibility_helper::save_visibility_job($visibility);
}

// Delete all jobs with status ready to transfer, where file is missing.
$sql = "SELECT uj.id " .
"FROM {block_opencast_uploadjob} uj " .
Expand Down

0 comments on commit bc1a8d3

Please sign in to comment.