Example #1
0
 /**
  * Do the job.
  */
 public function execute()
 {
     global $DB;
     $oidcconfig = get_config('auth_oidc');
     if (empty($oidcconfig)) {
         throw new \moodle_exception('erroracpauthoidcnotconfig', 'local_o365');
     }
     $spresource = \local_o365\rest\sharepoint::get_resource();
     if (empty($spresource)) {
         throw new \moodle_exception('erroracplocalo365notconfig', 'local_o365');
     }
     $httpclient = new \local_o365\httpclient();
     $clientdata = new \local_o365\oauth2\clientdata($oidcconfig->clientid, $oidcconfig->clientsecret, $oidcconfig->authendpoint, $oidcconfig->tokenendpoint);
     $sptoken = \local_o365\oauth2\systemtoken::instance(null, $spresource, $clientdata, $httpclient);
     if (empty($sptoken)) {
         throw new \moodle_exception('erroracpnosptoken', 'local_o365');
     }
     $sharepoint = new \local_o365\rest\sharepoint($sptoken, $httpclient);
     $sharepoint->set_site('');
     $moodlesiteuri = $sharepoint->get_moodle_parent_site_uri();
     if ($sharepoint->site_exists($moodlesiteuri) === false) {
         $moodlesitename = get_string('acp_parentsite_name', 'local_o365');
         $moodlesitedesc = get_string('acp_parentsite_desc', 'local_o365');
         $frontpagerec = $DB->get_record('course', ['id' => SITEID], 'id,shortname');
         if (!empty($frontpagerec) && !empty($frontpagerec->shortname)) {
             $moodlesitename = $frontpagerec->shortname;
         }
         $result = $sharepoint->create_site($moodlesitename, $moodlesiteuri, $moodlesitedesc);
         mtrace('Created parent site');
     }
     $courses = $DB->get_recordset('course');
     $successes = [];
     $failures = [];
     foreach ($courses as $course) {
         if ($course->id == SITEID) {
             continue;
         }
         try {
             $sharepoint->create_course_site($course);
             $successes[] = $course->id;
             mtrace('Created course subsite for course ' . $course->id);
         } catch (\Exception $e) {
             $failures[$course->id] = $e->getMessage();
         }
     }
     set_config('sharepoint_initialized', '1', 'local_o365');
 }
Example #2
0
 /**
  * Sync Sharepoint course site access when a role was assigned or unassigned for a user.
  *
  * @param int $roleid The ID of the role that was assigned/unassigned.
  * @param int $userid The ID of the user that it was assigned to or unassigned from.
  * @param int $contextid The ID of the context the role was assigned/unassigned in.
  * @return bool Success/Failure.
  */
 public static function sync_spsite_access_for_roleassign_change($roleid, $userid, $contextid)
 {
     global $DB;
     $requiredcap = \local_o365\rest\sharepoint::get_course_site_required_capability();
     // Check if the role affected the required capability.
     $rolecapsql = "SELECT *\n                         FROM {role_capabilities}\n                        WHERE roleid = ? AND capability = ?";
     $capassignrec = $DB->get_record_sql($rolecapsql, [$roleid, $requiredcap]);
     if (empty($capassignrec) || $capassignrec->permission == CAP_INHERIT) {
         // Role doesn't affect required capability. Doesn't concern us.
         return false;
     }
     $context = \context::instance_by_id($contextid, IGNORE_MISSING);
     if (empty($context)) {
         // Invalid context, stop here.
         return false;
     }
     if ($context->contextlevel == CONTEXT_COURSE) {
         $courseid = $context->instanceid;
         $user = $DB->get_record('user', ['id' => $userid]);
         if (empty($user)) {
             // Bad userid.
             return false;
         }
         $userupn = \local_o365\rest\azuread::get_muser_upn($user);
         if (empty($userupn)) {
             // No user UPN, can't continue.
             return false;
         }
         $spgroupsql = 'SELECT *
                          FROM {local_o365_coursespsite} site
                          JOIN {local_o365_spgroupdata} grp ON grp.coursespsiteid = site.id
                         WHERE site.courseid = ? AND grp.permtype = ?';
         $spgrouprec = $DB->get_record_sql($spgroupsql, [$courseid, 'contribute']);
         if (empty($spgrouprec)) {
             // No sharepoint group, can't fix that here.
             return false;
         }
         // If the context is a course context we can change SP access now.
         $sharepoint = static::construct_sharepoint_api_with_system_user();
         if (empty($sharepoint)) {
             // O365 not configured.
             return false;
         }
         $hascap = has_capability($requiredcap, $context, $user);
         if ($hascap === true) {
             // Add to group.
             $sharepoint->add_user_to_group($userupn, $spgrouprec->groupid, $user->id);
         } else {
             // Remove from group.
             $sharepoint->remove_user_from_group($userupn, $spgrouprec->groupid, $user->id);
         }
         return true;
     } else {
         if ($context->get_course_context(false) == false) {
             // If the context is higher than a course, we have to run a sync in cron.
             $spaccesssync = new \local_o365\task\sharepointaccesssync();
             $spaccesssync->set_custom_data(['roleid' => $roleid, 'userid' => $userid, 'contextid' => $contextid]);
             \core\task\manager::queue_adhoc_task($spaccesssync);
             return true;
         }
     }
 }
Example #3
0
 /**
  * Get listing for a course folder.
  *
  * @param string $path Folder path.
  * @return array List of $list array and $path array.
  */
 protected function get_listing_course($path = '')
 {
     global $USER, $OUTPUT;
     $list = [];
     $breadcrumb = [['name' => $this->name, 'path' => '/'], ['name' => 'Courses', 'path' => '/courses/']];
     $reqcap = \local_o365\rest\sharepoint::get_course_site_required_capability();
     $courses = get_user_capability_course($reqcap, $USER->id, true, 'shortname');
     // Reindex courses array using course id.
     $coursesbyid = [];
     foreach ($courses as $i => $course) {
         $coursesbyid[$course->id] = $course;
         unset($courses[$i]);
     }
     unset($courses);
     if ($path === '/') {
         // Show available courses.
         foreach ($coursesbyid as $course) {
             $list[] = ['title' => $course->shortname, 'path' => '/courses/' . $course->id, 'thumbnail' => $OUTPUT->pix_url(file_folder_icon(90))->out(false), 'children' => []];
         }
     } else {
         $pathtrimmed = trim($path, '/');
         $pathparts = explode('/', $pathtrimmed);
         if (!is_numeric($pathparts[0])) {
             throw new \moodle_exception('errorbadpath', 'repository_office365');
         }
         $courseid = (int) $pathparts[0];
         unset($pathparts[0]);
         $relpath = !empty($pathparts) ? implode('/', $pathparts) : '';
         if (isset($coursesbyid[$courseid])) {
             if ($this->path_is_upload($path) === false) {
                 $sharepointclient = $this->get_sharepoint_apiclient();
                 if (!empty($sharepointclient)) {
                     $parentsiteuri = $sharepointclient->get_course_subsite_uri($coursesbyid[$courseid]->id);
                     $sharepointclient->set_site($parentsiteuri);
                     try {
                         $fullpath = !empty($relpath) ? '/' . $relpath : '/';
                         $contents = $sharepointclient->get_files($fullpath);
                         $list = $this->contents_api_response_to_list($contents, $path, 'sharepoint', $parentsiteuri);
                     } catch (\Exception $e) {
                         $list = [];
                     }
                 }
             }
             $curpath = '/courses/' . $courseid;
             $breadcrumb[] = ['name' => $coursesbyid[$courseid]->shortname, 'path' => $curpath];
             foreach ($pathparts as $pathpart) {
                 if (!empty($pathpart)) {
                     $curpath .= '/' . $pathpart;
                     $breadcrumb[] = ['name' => $pathpart, 'path' => $curpath];
                 }
             }
         }
     }
     return [$list, $breadcrumb];
 }
Example #4
0
 /**
  * Check if a given URL is a valid SharePoint site.
  */
 public function mode_checksharepointsite()
 {
     $data = new \stdClass();
     $success = false;
     $uncleanurl = required_param('site', PARAM_TEXT);
     $clientdata = \local_o365\oauth2\clientdata::instance_from_oidc();
     $httpclient = new \local_o365\httpclient();
     $data->result = \local_o365\rest\sharepoint::validate_site($uncleanurl, $clientdata, $httpclient);
     $success = true;
     echo $this->ajax_response($data, $success);
 }
/**
 * Looks for links pointing to Office 365 Video content and processes them.
 *
 * @param $link HTML tag containing a link
 * @return string HTML content after processing.
 */
function filter_oembed_o365videocallback($link)
{
    if (empty($link[3])) {
        return $link[0];
    }
    $link[3] = preg_replace("/&/", "&", $link[3]);
    $values = array();
    parse_str($link[3], $values);
    if (empty($values['chid']) || empty($values['vid'])) {
        return $link[0];
    }
    if (!\local_o365\rest\sharepoint::is_configured()) {
        \local_o365\utils::debug('filter_oembed share point is not configured', 'filter_oembed_o365videocallback');
        return $link[0];
    }
    try {
        $spresource = \local_o365\rest\sharepoint::get_resource();
        if (!empty($spresource)) {
            $httpclient = new \local_o365\httpclient();
            $clientdata = \local_o365\oauth2\clientdata::instance_from_oidc();
            $sptoken = \local_o365\oauth2\systemtoken::instance(null, $spresource, $clientdata, $httpclient);
            if (!empty($sptoken)) {
                $sharepoint = new \local_o365\rest\sharepoint($sptoken, $httpclient);
                // Retrieve api url for video service.
                $url = $sharepoint->videoservice_discover();
                if (!empty($url)) {
                    $sharepoint->override_resource($url);
                    $width = 640;
                    if (!empty($values['width'])) {
                        $width = $values['width'];
                    }
                    $height = 360;
                    if (!empty($values['height'])) {
                        $height = $values['height'];
                    }
                    // Retrieve embed code.
                    return $sharepoint->get_video_embed_code($values['chid'], $values['vid'], $width, $height);
                }
            }
        }
    } catch (\Exception $e) {
        \local_o365\utils::debug('filter_oembed share point execption: ' . $e->getMessage(), 'filter_oembed_o365videocallback');
    }
    return $link[0];
}
Example #6
0
 /**
  * Test create_course_site method.
  */
 public function test_create_course_site()
 {
     global $DB;
     $requiredcapability = \local_o365\rest\sharepoint::get_course_site_required_capability();
     $course = $this->getDataGenerator()->create_course();
     $role = $this->getDataGenerator()->create_role(['archetype' => 'editingteacher']);
     $coursecontext = \context_course::instance($course->id);
     $user1 = $this->getDataGenerator()->create_user(['auth' => 'oidc']);
     $user2 = $this->getDataGenerator()->create_user(['auth' => 'oidc']);
     $aaduserdata = (object) ['type' => 'user', 'subtype' => '', 'objectid' => '', 'moodleid' => $user1->id, 'o365name' => '*****@*****.**', 'timecreated' => time(), 'timemodified' => time()];
     $aaduserdata->id = $DB->insert_record('local_o365_objects', $aaduserdata);
     $result = $this->getDataGenerator()->role_assign($role, $user1->id, $coursecontext);
     $httpclient = new \local_o365\tests\mockhttpclient();
     $httpresponses = ['', $this->get_response_create_site($course->fullname, $course->shortname, $course->summary), $this->get_response_create_group('testgroup', 'testgroup'), $this->get_response_assign_group_permission(), $this->get_response_add_user_to_group($aaduserdata->userupn)];
     $httpclient->set_responses($httpresponses);
     $apiclient = new \local_o365\rest\sharepoint($this->get_mock_token(), $httpclient);
     $apiclient->create_course_site($course->id);
     $coursespsite = $DB->get_record('local_o365_coursespsite', ['courseid' => $course->id]);
     $this->assertNotEmpty($coursespsite);
     $this->assertEquals('/moodle/' . $course->shortname, $coursespsite->siteurl);
     $spgroupdata = $DB->get_records('local_o365_spgroupdata', ['coursespsiteid' => $coursespsite->id]);
     $this->assertNotEmpty($spgroupdata);
 }
 /**
  * Do the job.
  */
 public function execute()
 {
     global $DB;
     // API Setup.
     try {
         $spresource = \local_o365\rest\sharepoint::get_resource();
         if (empty($spresource)) {
             throw new \moodle_exception('erroracplocalo365notconfig', 'local_o365');
         }
         $httpclient = new \local_o365\httpclient();
         $clientdata = \local_o365\oauth2\clientdata::instance_from_oidc();
         $sptoken = \local_o365\oauth2\systemtoken::instance(null, $spresource, $clientdata, $httpclient);
         if (empty($sptoken)) {
             throw new \moodle_exception('erroracpnosptoken', 'local_o365');
         }
         $sharepoint = new \local_o365\rest\sharepoint($sptoken, $httpclient);
     } catch (\Exception $e) {
         $errmsg = 'ERROR: Problem initializing SharePoint API. Reason: ' . $e->getMessage();
         mtrace($errmsg);
         \local_o365\utils::debug($errmsg, 'local_o365\\task\\sharepointinit::execute');
         set_config('sharepoint_initialized', 'error', 'local_o365');
         return false;
     }
     // Create parent site(s).
     try {
         mtrace('Creating parent site for Moodle...');
         $moodlesiteuri = $sharepoint->get_moodle_parent_site_uri();
         $sitelevels = explode('/', $moodlesiteuri);
         $currentparentsite = '';
         foreach ($sitelevels as $partialurl) {
             $sharepoint->set_site($currentparentsite);
             if ($sharepoint->site_exists($currentparentsite . '/' . $partialurl) === false) {
                 $moodlesitename = get_string('acp_parentsite_name', 'local_o365');
                 $moodlesitedesc = get_string('acp_parentsite_desc', 'local_o365');
                 $frontpagerec = $DB->get_record('course', ['id' => SITEID], 'id,shortname');
                 if (!empty($frontpagerec) && !empty($frontpagerec->shortname)) {
                     $moodlesitename = $frontpagerec->shortname;
                 }
                 mtrace('Setting parent site to "' . $currentparentsite . '", creating subsite "' . $partialurl . '"');
                 $result = $sharepoint->create_site($moodlesitename, $partialurl, $moodlesitedesc);
                 $currentparentsite .= '/' . $partialurl;
                 mtrace('Created parent site "' . $currentparentsite . '"');
             } else {
                 $currentparentsite .= '/' . $partialurl;
                 mtrace('Parent site "' . $currentparentsite . '" already exists.');
             }
         }
         mtrace('Finished creating Moodle parent site.');
     } catch (\Exception $e) {
         $errmsg = 'ERROR: Problem creating parent site. Reason: ' . $e->getMessage();
         mtrace($errmsg);
         \local_o365\utils::debug($errmsg, 'local_o365\\task\\sharepointinit::execute');
         set_config('sharepoint_initialized', 'error', 'local_o365');
         return false;
     }
     // Create course sites.
     mtrace('Creating course subsites in "' . $moodlesiteuri . '"');
     $sharepoint->set_site($moodlesiteuri);
     $courses = $DB->get_recordset('course');
     $successes = [];
     $failures = [];
     foreach ($courses as $course) {
         if ($course->id == SITEID) {
             continue;
         }
         try {
             $sharepoint->create_course_site($course);
             $successes[] = $course->id;
             mtrace('Created course subsite for course ' . $course->id);
         } catch (\Exception $e) {
             mtrace('Encountered error creating course subsite for course ' . $course->id);
             $failures[$course->id] = $e->getMessage();
         }
     }
     if (!empty($failures)) {
         $errmsg = 'ERROR: Encountered problems creating course sites.';
         mtrace($errmsg . ' See logs.');
         \local_o365\utils::debug($errmsg, 'local_o365\\task\\sharepointinit::execute', $failures);
         set_config('sharepoint_initialized', 'error', 'local_o365');
     } else {
         set_config('sharepoint_initialized', '1', 'local_o365');
         mtrace('SharePoint successfully initialized.');
         return true;
     }
 }
 /**
  * Create a course subsite.
  *
  * @param \stdClass $course A course record to create the subsite from.
  * @return \stdClass An association record.
  */
 public function create_course_subsite($course)
 {
     return parent::create_course_subsite($course);
 }
 /**
  * Do the job.
  */
 public function execute()
 {
     $reqcap = \local_o365\rest\sharepoint::get_course_site_required_capability();
     $oidcconfig = get_config('auth_oidc');
     if (!empty($oidcconfig)) {
         $spresource = \local_o365\rest\sharepoint::get_resource();
         if (!empty($spresource)) {
             $httpclient = new \local_o365\httpclient();
             $clientdata = new \local_o365\oauth2\clientdata($oidcconfig->clientid, $oidcconfig->clientsecret, $oidcconfig->authendpoint, $oidcconfig->tokenendpoint);
             $sptoken = \local_o365\oauth2\systemtoken::instance(null, $spresource, $clientdata, $httpclient);
             if (!empty($sptoken)) {
                 $sharepoint = new \local_o365\rest\sharepoint($sptoken, $httpclient);
             }
         }
     }
     if (empty($sharepoint)) {
         throw new \moodle_exception('errorcreatingsharepointclient', 'local_o365');
     }
     $opdata = $this->get_custom_data();
     if ($opdata->userid !== '*' && $opdata->roleid !== '*' && !empty($opdata->contextid)) {
         // Single user role assign/unassign.
         $this->do_role_assignmentchange($opdata->roleid, $opdata->userid, $opdata->contextid, $reqcap, $sharepoint);
     } else {
         if ($opdata->userid === '*' && $opdata->roleid !== '*') {
             // Capability update.
             $this->do_role_capabilitychange($opdata->roleid, $reqcap, $sharepoint);
         } else {
             if ($opdata->roleid === '*' && $opdata->userid === '*') {
                 // Role deleted.
                 $this->do_role_delete($reqcap, $sharepoint);
             }
         }
     }
 }
 /**
  * Get content for a connected user.
  *
  * @return string Block content.
  */
 protected function get_content_connected()
 {
     global $PAGE, $DB;
     $o365config = get_config('local_o365');
     $html = '';
     $langconnected = get_string('o365connected', 'block_microsoft');
     $html .= '<h5>' . $langconnected . '</h5>';
     $outlookurl = new \moodle_url('/local/o365/ucp.php?action=calendar');
     $outlookstr = get_string('linkoutlook', 'block_microsoft');
     $sharepointstr = get_string('linksharepoint', 'block_microsoft');
     $prefsurl = new \moodle_url('/local/o365/ucp.php');
     $prefsstr = get_string('linkprefs', 'block_microsoft');
     $connecturl = new \moodle_url('/local/o365/ucp.php', ['action' => 'aadlogin']);
     $connectstr = get_string('linkconnection', 'block_microsoft');
     $items = [];
     if ($PAGE->context instanceof \context_course && $PAGE->context->instanceid !== SITEID) {
         if (!empty($o365config->sharepointlink)) {
             $coursespsite = $DB->get_record('local_o365_coursespsite', ['courseid' => $PAGE->context->instanceid]);
             if (!empty($coursespsite)) {
                 $spsite = \local_o365\rest\sharepoint::get_resource();
                 if (!empty($spsite)) {
                     $spurl = $spsite . '/' . $coursespsite->siteurl;
                     $spattrs = ['class' => 'servicelink block_microsoft_sharepoint', 'target' => '_blank'];
                     $items[] = html_writer::link($spurl, $sharepointstr, $spattrs);
                     $items[] = '<hr/>';
                 }
             }
         }
     }
     $items[] = $this->render_onenote();
     $items[] = \html_writer::link($outlookurl, $outlookstr, ['class' => 'servicelink block_microsoft_outlook']);
     $items[] = \html_writer::link($prefsurl, $prefsstr, ['class' => 'servicelink block_microsoft_preferences']);
     $items[] = \html_writer::link($connecturl, $connectstr, ['class' => 'servicelink block_microsoft_connection']);
     $html .= \html_writer::alist($items);
     return $html;
 }
 /**
  * Get content for a connected user.
  *
  * @return string Block content.
  */
 protected function get_content_connected()
 {
     global $PAGE, $DB, $CFG, $SESSION, $USER, $OUTPUT;
     $o365config = get_config('local_o365');
     $html = '';
     $aadsync = get_config('local_o365', 'aadsync');
     $aadsync = array_flip(explode(',', $aadsync));
     // Only profile sync once for each session.
     if (empty($SESSION->block_microsoft_profilesync) && isset($aadsync['photosynconlogin'])) {
         $PAGE->requires->jquery();
         $PAGE->requires->js('/blocks/microsoft/js/microsoft.js');
         $PAGE->requires->js_init_call('microsoft_update_profile', array($CFG->wwwroot));
     }
     $user = $DB->get_record('user', array('id' => $USER->id));
     $langconnected = get_string('o365connected', 'block_microsoft', $user);
     $html .= '<h5>' . $langconnected . '</h5>';
     if (!empty($user->picture)) {
         $html .= '<div class="profilepicture">';
         $html .= $OUTPUT->user_picture($user, array('size' => 100, 'class' => 'block_microsoft_profile'));
         $html .= '</div>';
     }
     $outlookurl = new \moodle_url('/local/o365/ucp.php?action=calendar');
     $outlookstr = get_string('linkoutlook', 'block_microsoft');
     $sharepointstr = get_string('linksharepoint', 'block_microsoft');
     $prefsurl = new \moodle_url('/local/o365/ucp.php');
     $prefsstr = get_string('linkprefs', 'block_microsoft');
     $connecturl = new \moodle_url('/local/o365/ucp.php', ['action' => 'aadlogin']);
     $connectstr = get_string('linkconnection', 'block_microsoft');
     $items = [];
     if ($PAGE->context instanceof \context_course && $PAGE->context->instanceid !== SITEID) {
         if (!empty($o365config->sharepointlink)) {
             $coursespsite = $DB->get_record('local_o365_coursespsite', ['courseid' => $PAGE->context->instanceid]);
             if (!empty($coursespsite)) {
                 $spsite = \local_o365\rest\sharepoint::get_resource();
                 if (!empty($spsite)) {
                     $spurl = $spsite . '/' . $coursespsite->siteurl;
                     $spattrs = ['class' => 'servicelink block_microsoft_sharepoint', 'target' => '_blank'];
                     $items[] = html_writer::link($spurl, $sharepointstr, $spattrs);
                     $items[] = '<hr/>';
                 }
             }
         }
     }
     $items[] = $this->render_onenote();
     $items[] = \html_writer::link($outlookurl, $outlookstr, ['class' => 'servicelink block_microsoft_outlook']);
     $items[] = \html_writer::link($prefsurl, $prefsstr, ['class' => 'servicelink block_microsoft_preferences']);
     $items[] = \html_writer::link($connecturl, $connectstr, ['class' => 'servicelink block_microsoft_connection']);
     $downloadlinks = $this->get_content_o365download();
     foreach ($downloadlinks as $link) {
         $items[] = $link;
     }
     $html .= \html_writer::alist($items);
     return $html;
 }