Skip to content
Snippets Groups Projects
Commit 86821134 authored by Rasmus Fuhse's avatar Rasmus Fuhse
Browse files

work on 4.6 FilesystemPlugin

parent 34e2bdf9
No related branches found
No related tags found
No related merge requests found
<?php <?php
require_once __DIR__."/classes/OAuth.class.php"; require_once __DIR__."/classes/OAuth.class.php";
require_once __DIR__."/classes/OwncloudFolder.class.php"; require_once __DIR__."/classes/OwncloudFile.php";
require_once __DIR__."/classes/OwncloudFolder.php";
class OwnCloudPlugin extends StudIPPlugin implements FilesystemPlugin { class OwnCloudPlugin extends StudIPPlugin implements FilesystemPlugin {
...@@ -14,6 +15,7 @@ class OwnCloudPlugin extends StudIPPlugin implements FilesystemPlugin { ...@@ -14,6 +15,7 @@ class OwnCloudPlugin extends StudIPPlugin implements FilesystemPlugin {
public function getFolder($folder_id = null) public function getFolder($folder_id = null)
{ {
Navigation::activateItem('/files/my_files');
if ($folder_id[0] === "/") { if ($folder_id[0] === "/") {
$folder_id = substr($folder_id, 1); $folder_id = substr($folder_id, 1);
} }
...@@ -80,7 +82,7 @@ class OwnCloudPlugin extends StudIPPlugin implements FilesystemPlugin { ...@@ -80,7 +82,7 @@ class OwnCloudPlugin extends StudIPPlugin implements FilesystemPlugin {
if (!$this->isFile($file_id)) { if (!$this->isFile($file_id)) {
return null; return null;
} }
$folder_path = explode("/", $file_id); $folder_path = explode("/", $file_id);
$filename = rawurldecode(array_pop($folder_path)); $filename = rawurldecode(array_pop($folder_path));
$folder_id = implode("/", $folder_path); $folder_id = implode("/", $folder_path);
...@@ -96,11 +98,13 @@ class OwnCloudPlugin extends StudIPPlugin implements FilesystemPlugin { ...@@ -96,11 +98,13 @@ class OwnCloudPlugin extends StudIPPlugin implements FilesystemPlugin {
), $this->getPluginId()); ), $this->getPluginId());
foreach ($folder->getFiles() as $file_info) { foreach ($folder->getFiles() as $file_info) {
if ($file_info->name === $filename) { if (($file_info->getFilename() === $file_id)
|| ($file_info->getFilename() === rawurldecode($file_id))) {
$info = $file_info; $info = $file_info;
break; break;
} }
} }
return $info;
$file = new FileRef(); $file = new FileRef();
$file->id = $file_id; $file->id = $file_id;
...@@ -112,7 +116,7 @@ class OwnCloudPlugin extends StudIPPlugin implements FilesystemPlugin { ...@@ -112,7 +116,7 @@ class OwnCloudPlugin extends StudIPPlugin implements FilesystemPlugin {
$file->mkdate = $info->chdate; $file->mkdate = $info->chdate;
$file->chdate = $info->chdate; $file->chdate = $info->chdate;
$file->content_terms_of_use_id = 'UNDEF_LICENSE'; $file->content_terms_of_use_id = 'UNDEF_LICENSE';
if ($with_blob) { if ($with_blob) {
$url = Config::get()->OWNCLOUD_ENDPOINT ?: UserConfig::get($GLOBALS['user']->id)->OWNCLOUD_ENDPOINT_USER; $url = Config::get()->OWNCLOUD_ENDPOINT ?: UserConfig::get($GLOBALS['user']->id)->OWNCLOUD_ENDPOINT_USER;
if ($url[strlen($url) - 1] !== "/") { if ($url[strlen($url) - 1] !== "/") {
......
<?php
class OwncloudFile implements FileType
{
public $data = [];
protected $foldertype = null;
public function __construct($data, $foldertype)
{
$this->data = $data;
$this->foldertype = $foldertype;
}
/**
* Returns the name of the icon shape that shall be used with the FileType implementation.
*
* @param string $role role of icon
* @return Icon icon for the FileType implementation.
*/
public function getIcon($role)
{
$shape = FileManager::getIconNameForMimeType(
$this->data['mime_type']
);
return Icon::create($shape, $role);
}
/**
* Returns the id of the file which is most likely the id of the FileRef object
* within the FileType object.
* @return mixed
*/
public function getId()
{
return $this->data['id'];
}
/**
* Filename of the FileType-object.
* @return mixed
*/
public function getFilename()
{
return $this->data['name'];
}
/**
* The user_id in Stud.IP if the author has Stud.IP account. If it has none, return null.
* @return mixed|null
*/
public function getUserId()
{
return $this->data['user_id'];
}
/**
* Return the name of the author as a string.
* @return string|null
*/
public function getUserName()
{
return get_fullname($this->data['user_id']);
}
/**
* @returns The User object representing the author.
*/
public function getUser()
{
return new User($this->data['user_id']);
}
/**
* Returns the size of the file in bytes. If this is null, the file doesn't exist
* physically - is probably only a weblink or a request for libraries.
* @return integer|null
*/
public function getSize()
{
return $this->data['size'];
}
/**
* Returns the URL to download the file. May be sendfile.php?... or an external link.
* @return string|null
*/
public function getDownloadURL()
{
return $this->data['download_url'];
}
/**
* Returns the number of downloads this file already has. Returns null if information is not available.
* @return integer|null
*/
public function getDownloads()
{
return 0;
}
/**
* Returns the (real) file system path for the file.
* This is only relevant for FileType implementations storing real files
* on the server disk. Other implementations shall just return
* an empty string.
*
* @returns The file system path for the file or an empty string if the
* file doesn't have a path in the file system.
*/
public function getPath() : string
{
return "";
}
/**
* Returns the UNIX-Timestamp of the last change or null if this information is unknown.
* @return integer|null
*/
public function getLastChangeDate()
{
return $this->data['chdate'];
}
/**
* Returns the UNIX-timestamp of creation of that file
* @return integer|null
*/
public function getMakeDate()
{
return $this->data['chdate'];
}
/**
* Returns the description of that FileType object.
* @return string|null
*/
public function getDescription()
{
return $this->data['description'];
}
/**
* Returns the mime-type of that FileType-object.
* @return string
*/
public function getMimeType()
{
return $this->data['mime_type'];
}
/**
* @return ContentTermsOfUse
*/
public function getTermsOfUse()
{
return ContentTermsOfUse::findDefault();
}
/**
* Returns an instance of ActionMenu.
* @return ActionMenu|null
*/
public function getActionmenu()
{
$actionMenu = ActionMenu::get();
$actionMenu->addLink(
URLHelper::getURL("dispatch.php/file/details/{$this->getId()}", [
'to_plugin' => "OwnCloudPlugin",
'from_plugin' => "OwnCloudPlugin",
'file_navigation' => 1
]),
_('Info'),
Icon::create('info-circle', Icon::ROLE_CLICKABLE, ['size' => 20]),
['data-dialog' => ''],
'file-display-info'
);
if ($current_action === 'flat') {
if (Navigation::hasItem('/course/files') && Navigation::getItem('/course/files')->isActive()) {
$actionMenu->addLink(
URLHelper::getURL('dispatch.php/course/files/index/' . $this->fileref->folder_id),
_('Ordner öffnen'),
Icon::create('folder-empty', Icon::ROLE_CLICKABLE, ['size' => 20])
);
} elseif (Navigation::hasItem('/files_dashboard/files') && Navigation::getItem('/files_dashboard/files')->isActive()) {
$actionMenu->addLink(
URLHelper::getURL('dispatch.php/files/index/' . $this->fileref->folder_id),
_('Ordner öffnen'),
Icon::create('folder-empty', Icon::ROLE_CLICKABLE, ['size' => 20])
);
}
}
if ($this->isEditable($GLOBALS['user']->id)) {
$actionMenu->addLink(
URLHelper::getURL('dispatch.php/file/edit/' . $this->fileref->id),
_('Datei bearbeiten'),
Icon::create('edit', Icon::ROLE_CLICKABLE, ['size' => 20]),
['data-dialog' => ''],
'file-edit'
);
$actionMenu->addLink(
URLHelper::getURL('dispatch.php/file/update/' . $this->fileref->id),
_('Datei aktualisieren'),
Icon::create('refresh', Icon::ROLE_CLICKABLE, ['size' => 20]),
['data-dialog' => ''],
'file-update'
);
}
if ($this->isWritable($GLOBALS['user']->id)) {
$actionMenu->addLink(
URLHelper::getURL('dispatch.php/file/choose_destination/move/' . $this->fileref->id),
_('Datei verschieben'),
Icon::create('file+move_right', Icon::ROLE_CLICKABLE, ['size' => 20]),
['data-dialog' => 'size=auto'],
'file-move'
);
}
if ($this->isDownloadable($GLOBALS['user']->id) && $GLOBALS['user']->id !== 'nobody') {
$actionMenu->addLink(
URLHelper::getURL('dispatch.php/file/choose_destination/copy/' . $this->fileref->id),
_('Datei kopieren'),
Icon::create('file+add', Icon::ROLE_CLICKABLE, ['size' => 20]),
['data-dialog' => 'size=auto'],
'file-copy'
);
$actionMenu->addLink(
$this->getDownloadURL('force_download'),
_('Link kopieren'),
Icon::create('group'),
['class' => 'copyable-link'],
'link-to-clipboard'
);
}
if (Context::isCourse() && Feedback::isActivated()) {
if (Feedback::hasCreatePerm(Context::getId())) {
$actionMenu->addLink(
URLHelper::getURL('dispatch.php/course/feedback/create_form/'. $this->fileref->id . '/FileRef'),
_('Neues Feedback-Element'),
Icon::create('star+add', Icon::ROLE_CLICKABLE, ['size' => 20]),
['data-dialog' => '1']
);
}
}
if ($this->isWritable($GLOBALS['user']->id)) {
$actionMenu->addButton(
'delete',
_('Datei löschen'),
Icon::create('trash', Icon::ROLE_CLICKABLE, ['size' => 20]),
[
'formaction' => URLHelper::getURL("dispatch.php/file/delete/{$this->getId()}", $flat_view ? ['from_flat_view' => 1] : []),
'data-confirm' => sprintf(_('Soll die Datei "%s" wirklich gelöscht werden?'), $this->getFilename()),
]
);
}
NotificationCenter::postNotification("FileActionMenuWillRender", $actionMenu, $this);
return $actionMenu;
}
/**
* Returns a list of Stud.IP button objects that represent actions
* that shall be visible for the file type in the info dialog.
*
* @param array $extra_link_params An optional array of URL parameters
* that should be added to Button URLs, if reasonable. The parameter
* names are the keys of the array while their values are also the
* array item values.
*
* @returns Interactable[] A list of Stud.IP buttons (LinkButton or Button).
*/
public function getInfoDialogButtons(array $extra_link_params = []) : array
{
return [];
}
/**
* Deletes that file.
* @return bool : true on success
*/
public function delete()
{
return $this->foldertype->deleteFile($this->getId());
}
/**
* Returns the FolderTyp of the parent folder.
* @return FolderType
*/
public function getFolderType()
{
return $this->foldertype;
}
/**
* Determines whether the file is visible for a user.
*
* @param string $user_id The user for which the visibility of the file
* shall be determined.
*
* @return boolean True, if the user is permitted to see the file, false otherwise.
*/
public function isVisible($user_id = null)
{
return true;
}
/**
* Determines if a user may download the file.
* @param string $user_id The user who wishes to download the file.
* @return boolean True, if the user is permitted to download the file, false otherwise.
*/
public function isDownloadable($user_id = null)
{
return true;
}
/**
* Determines if a user may edit the file.
* @param string $user_id The user who wishes to edit the file.
* @return boolean True, if the user is permitted to edit the file, false otherwise.
*/
public function isEditable($user_id = null)
{
return true;
}
/**
* Determines if a user may write to the file.
* @param string $user_id The user who wishes to write to the file.
* @return boolean True, if the user is permitted to write to the file, false otherwise.
*/
public function isWritable($user_id = null)
{
return true;
}
/**
* Returns an object of the class StandardFile or a derived class.
* @return StandardFile
*/
public function convertToStandardFile()
{
//TODO
}
/**
* Returns the content for that additional column, if it exists. You can return null a string
* or a Flexi_Template as the content.
* @param string $column_index
* @return null|string|Flexi_Template
*/
public function getContentForAdditionalColumn($column_index)
{
return null;
}
/**
* Returns an integer that marks the value the content of the given column should be
* ordered by.
* @param string $column_index
* @return integer : order value
*/
public function getAdditionalColumnOrderWeigh($column_index)
{
return 0;
}
/**
* Generates a Flexi_Template containing additional information that are
* displayes in the information dialog of a file.
*
* @param bool $include_downloadable_infos Whether to include information
* like file previews that can be downloaded (true) or to not
* include them (false). Defaults to false.
*
* @returns Flexi_Template|null Either a Flexi_Template containing
* additional information or null if no such information shall be
* displayed in the information dialog.
*/
public function getInfoTemplate(bool $include_downloadable_infos = false)
{
return null;
}
}
...@@ -41,7 +41,7 @@ class OwncloudFolder extends VirtualFolderType { ...@@ -41,7 +41,7 @@ class OwncloudFolder extends VirtualFolderType {
public function store() public function store()
{ {
$old_id = $this->parent_id . '/' . rawurlencode($this->name); $old_id = $this->parent_id . '/' . rawurlencode($this->name);
if ($this->getId() != $old_id) { if ($this->getId() != $old_id) {
...@@ -50,7 +50,7 @@ class OwncloudFolder extends VirtualFolderType { ...@@ -50,7 +50,7 @@ class OwncloudFolder extends VirtualFolderType {
$header = array(); $header = array();
$header[] = self::getAuthHeader(); $header[] = self::getAuthHeader();
$header[] = "Destination: ". $webdav . $this->id; $header[] = "Destination: ". $webdav . $this->id;
$r = curl_init(); $r = curl_init();
curl_setopt($r, CURLOPT_CUSTOMREQUEST, "MOVE"); curl_setopt($r, CURLOPT_CUSTOMREQUEST, "MOVE");
curl_setopt($r, CURLOPT_URL, $webdav . $old_id); curl_setopt($r, CURLOPT_URL, $webdav . $old_id);
...@@ -100,11 +100,11 @@ class OwncloudFolder extends VirtualFolderType { ...@@ -100,11 +100,11 @@ class OwncloudFolder extends VirtualFolderType {
return ($status >= 200) && ($status < 300); return ($status >= 200) && ($status < 300);
} }
public function createFile($filedata) public function addFile(FileType $file, $user_id = null)
{ {
$webdav = $this->getWebDavURL(); $webdav = $this->getWebDavURL();
if ($this->fileExists($filedata['name'])) { if ($this->fileExists($file->getFilename())) {
if (strpos($filedata['name'], ".")) { if (strpos($filedata['name'], ".")) {
$end = substr($filedata['name'], strpos($filedata['name'], ".")); $end = substr($filedata['name'], strpos($filedata['name'], "."));
$name_raw = substr($filedata['name'], 0, strpos($filedata['name'], ".")); $name_raw = substr($filedata['name'], 0, strpos($filedata['name'], "."));
...@@ -117,14 +117,19 @@ class OwncloudFolder extends VirtualFolderType { ...@@ -117,14 +117,19 @@ class OwncloudFolder extends VirtualFolderType {
$new_name = $name_raw."(".$i.").".$end; $new_name = $name_raw."(".$i.").".$end;
} while ($this->fileExists($new_name)); } while ($this->fileExists($new_name));
$filedata['name'] = $new_name; $filedata['name'] = $new_name;
$file->data['name'] = $new_name;
} }
$file_ref_id = $this->id . (mb_strlen($this->id) ? '/' : '') . rawurlencode($filedata['name']);
$file_ref_id = $this->id . (mb_strlen($this->id) ? '/' : '') . rawurlencode($file->getFilename());
$header = array(); $header = array();
$header[] = self::getAuthHeader(); $header[] = self::getAuthHeader();
$url_template = "[InternetShortcut]\nURL=%s"; $url_template = "[InternetShortcut]\nURL=%s";
if (is_a($filedata, "File")) {
$data = $GLOBALS['TMP_PATH']."/file_".md5(uniqid());
if (is_a($file, "URLFile")) {
if ($filedata->getURL()) { if ($filedata->getURL()) {
$data = $GLOBALS['TMP_PATH']."/file_".md5(uniqid()); $data = $GLOBALS['TMP_PATH']."/file_".md5(uniqid());
file_put_contents($data, sprintf($url_template, $filedata->getURL())); file_put_contents($data, sprintf($url_template, $filedata->getURL()));
...@@ -148,7 +153,7 @@ class OwncloudFolder extends VirtualFolderType { ...@@ -148,7 +153,7 @@ class OwncloudFolder extends VirtualFolderType {
curl_setopt($r, CURLOPT_URL, $webdav . $file_ref_id); curl_setopt($r, CURLOPT_URL, $webdav . $file_ref_id);
curl_setopt($r, CURLOPT_HTTPHEADER, ($header)); curl_setopt($r, CURLOPT_HTTPHEADER, ($header));
curl_setopt($r, CURLOPT_INFILE, $fh_res); curl_setopt($r, CURLOPT_INFILE, $fh_res);
curl_setopt($r, CURLOPT_INFILESIZE, filesize($data)); curl_setopt($r, CURLOPT_INFILESIZE, filesize($data));
curl_setopt($r, CURLOPT_RETURNTRANSFER, 1); curl_setopt($r, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($r, CURLOPT_SSL_VERIFYPEER, (bool) Config::get()->OWNCLOUD_SSL_VERIFYPEER); curl_setopt($r, CURLOPT_SSL_VERIFYPEER, (bool) Config::get()->OWNCLOUD_SSL_VERIFYPEER);
curl_setopt($r, CURLOPT_SSL_VERIFYHOST, (bool) Config::get()->OWNCLOUD_SSL_VERIFYPEER); curl_setopt($r, CURLOPT_SSL_VERIFYHOST, (bool) Config::get()->OWNCLOUD_SSL_VERIFYPEER);
...@@ -167,7 +172,7 @@ class OwncloudFolder extends VirtualFolderType { ...@@ -167,7 +172,7 @@ class OwncloudFolder extends VirtualFolderType {
public function copyFile($file_ref_id) public function copyFile($file_ref_id)
{ {
$webdav = $this->getWebDavURL(); $webdav = $this->getWebDavURL();
$tmp_parts = explode('/', $file_ref_id); $tmp_parts = explode('/', $file_ref_id);
$name = end($tmp_parts); $name = end($tmp_parts);
...@@ -262,7 +267,7 @@ class OwncloudFolder extends VirtualFolderType { ...@@ -262,7 +267,7 @@ class OwncloudFolder extends VirtualFolderType {
if (!$name) { if (!$name) {
return false; return false;
} }
$webdav = $this->getWebDavURL(); $webdav = $this->getWebDavURL();
if ($this->fileExists(rawurlencode($name))) { if ($this->fileExists(rawurlencode($name))) {
if (strpos($name, ".")) { if (strpos($name, ".")) {
...@@ -298,7 +303,7 @@ class OwncloudFolder extends VirtualFolderType { ...@@ -298,7 +303,7 @@ class OwncloudFolder extends VirtualFolderType {
curl_exec($r); curl_exec($r);
$status = curl_getinfo($r, CURLINFO_HTTP_CODE); $status = curl_getinfo($r, CURLINFO_HTTP_CODE);
curl_close($r); curl_close($r);
$plugin = PluginManager::getInstance()->getPlugin("OwnCloudPlugin"); $plugin = PluginManager::getInstance()->getPlugin("OwnCloudPlugin");
return $plugin->getPreparedFile($destination); return $plugin->getPreparedFile($destination);
} }
...@@ -480,7 +485,7 @@ class OwncloudFolder extends VirtualFolderType { ...@@ -480,7 +485,7 @@ class OwncloudFolder extends VirtualFolderType {
), $this->plugin_id); ), $this->plugin_id);
} else { } else {
$content_type = $file_attributes['contenttype'] ?: get_mime_type($file_attributes['name']); $content_type = $file_attributes['contenttype'] ?: get_mime_type($file_attributes['name']);
$this->files[] = (object) array( $this->files[] = new OwncloudFile([
'id' => ($this->id ? $this->id . "/" : "") . rawurlencode($file_attributes['name']), 'id' => ($this->id ? $this->id . "/" : "") . rawurlencode($file_attributes['name']),
'name' => $file_attributes['name'], 'name' => $file_attributes['name'],
'size' => $file_attributes['size'], 'size' => $file_attributes['size'],
...@@ -489,10 +494,11 @@ class OwncloudFolder extends VirtualFolderType { ...@@ -489,10 +494,11 @@ class OwncloudFolder extends VirtualFolderType {
'user_id' => $GLOBALS['user']->id, 'user_id' => $GLOBALS['user']->id,
'chdate' => $file_attributes['chdate'], 'chdate' => $file_attributes['chdate'],
'download_url' => URLHelper::getURL("plugins.php/owncloudplugin/download/" . ($this->id ? $this->id . "/" : "") . rawurlencode($file_attributes['name'])) 'download_url' => URLHelper::getURL("plugins.php/owncloudplugin/download/" . ($this->id ? $this->id . "/" : "") . rawurlencode($file_attributes['name']))
); ], $this);
} }
} }
} }
//var_dump($this->files); die();
$this->did_propfind = true; $this->did_propfind = true;
} }
...@@ -510,13 +516,12 @@ class OwncloudFolder extends VirtualFolderType { ...@@ -510,13 +516,12 @@ class OwncloudFolder extends VirtualFolderType {
public function setDataFromEditTemplate($request) public function setDataFromEditTemplate($request)
{ {
if (!$request['name']) { if (!$request['name']) {
return MessageBox::error(_('Die Bezeichnung des Ordners fehlt.')); return MessageBox::error(_('Die Bezeichnung des Ordners fehlt.'));
} }
$plugin = PluginEngine::getPlugin($request["from_plugin"]); $plugin = PluginEngine::getPlugin($request["from_plugin"]);
if (empty($request['parent_id'])) { if (empty($request['parent_id'])) {
$this->folderdata['id'] = $request['name']; $this->folderdata['id'] = $request['name'];
} else { } else {
...@@ -558,8 +563,19 @@ class OwncloudFolder extends VirtualFolderType { ...@@ -558,8 +563,19 @@ class OwncloudFolder extends VirtualFolderType {
return false; return false;
} }
static public function getAuthHeader() { static public function getAuthHeader()
{
return "Authorization: Bearer " . \Owncloud\OAuth::getAccessToken(); return "Authorization: Bearer " . \Owncloud\OAuth::getAccessToken();
} }
public function getAdditionalColumns()
{
return [];
}
public function getAdditionalActionButtons()
{
return [];
}
} }
...@@ -4,13 +4,7 @@ class ConfigureController extends PluginController ...@@ -4,13 +4,7 @@ class ConfigureController extends PluginController
{ {
public function myarea_action() public function myarea_action()
{ {
if (Navigation::hasItem("/profile/files/OwnCloudPlugin")) { Navigation::activateItem('/files/my_files');
Navigation::activateItem('/profile/files/OwnCloudPlugin');
} elseif(Navigation::hasItem('/profile/files')) {
Navigation::activateItem('/profile/files');
} else {
Navigation::activateItem('/files_dashboard/files');
}
PageLayout::setTitle(Config::get()->OWNCLOUD_NAME); PageLayout::setTitle(Config::get()->OWNCLOUD_NAME);
if (Request::isPost() && Request::submitted("remove")) { if (Request::isPost() && Request::submitted("remove")) {
$config = UserConfig::get($GLOBALS['user']->id); $config = UserConfig::get($GLOBALS['user']->id);
...@@ -42,4 +36,4 @@ class ConfigureController extends PluginController ...@@ -42,4 +36,4 @@ class ConfigureController extends PluginController
return; return;
} }
} }
} }
\ No newline at end of file
pluginname=OwnCloudPlugin pluginname=OwnCloudPlugin
pluginclassname=OwnCloudPlugin pluginclassname=OwnCloudPlugin
version=1.2.3 version=2.0
origin=data-quest origin=data-quest
studipMinVersion=4.0 studipMinVersion=4.6
studipMaxVersion=4.5.99 studipMaxVersion=5.0.99
OwnCloud-Plugin für Stud.IP OwnCloud-Plugin für Stud.IP
=========================== ===========================
Mit diesem Plugin kann man ab der Stud.IP-Version 4.0 eine Owncloud (oder Nextcloud) als persönlichen Dateibereich einbinden und von und zu der Owncloud Dateien nach oder von Stud.IP kopieren. Mit diesem Plugin kann man ab der Stud.IP-Version 4.0 eine Owncloud (oder Nextcloud) als persönlichen Dateibereich einbinden und von und zu der Owncloud Dateien nach oder von Stud.IP kopieren.
## Installation ## Installation
1. Das Plugin wird ganz normal in Stud.IP per Drag&Drop installiert. 1. Das Plugin wird ganz normal in Stud.IP per Drag&Drop installiert.
2. Die OwnCloud braucht die [OAuth2-App](https://github.com/owncloud/oauth2/releases), die installiert und aktiviert werden muss. Wer nur Stud.IP gewohnt ist: OAuth2 heißt im Owncloud-Kontext zwar "App", ist aber das gleiche wie bei Stud.IP ein Plugin. Die Dateien müssen in das Owncloud-Verzeichnis unter `./apps/oauth2` abgelegt werden. 2. Die OwnCloud braucht die [OAuth2-App](https://github.com/owncloud/oauth2/releases), die installiert und aktiviert werden muss. Wer nur Stud.IP gewohnt ist: OAuth2 heißt im Owncloud-Kontext zwar "App", ist aber das gleiche wie bei Stud.IP ein Plugin. Die Dateien müssen in das Owncloud-Verzeichnis unter `./apps/oauth2` abgelegt werden. NextCloud hingegen hat OAuth 2 schon eingebaut.
3. Für OAuth in der OwnCloud hinter einem Apache braucht man das mod_rewrite und mod_env Modul, das die Regel `RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]` umsetzt. Wenn das nicht aktiv ist, kann OAuth nicht funktionieren, weil der Apache alle Authorization-Header entfernt. 3. Für OAuth in der OwnCloud hinter einem Apache braucht man das mod_rewrite und mod_env Modul, das die Regel `RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]` umsetzt. Wenn das nicht aktiv ist, kann OAuth nicht funktionieren, weil der Apache alle Authorization-Header entfernt.
4. Die OAuth2 "App" muss als Admin im Webinterface von Owncloud aktiviert werden unter "Einstellungen" (oben rechts unter dem Nutzernamen) -> Apps -> "Deaktivierte Apps anzeigen" -> "aktivieren". 4. Die OAuth2 "App" muss als Admin im Webinterface von Owncloud aktiviert werden unter "Einstellungen" (oben rechts unter dem Nutzernamen) -> Apps -> "Deaktivierte Apps anzeigen" -> "aktivieren".
5. Es muss in Owncloud ein Client angelegt werden. Unter Administration -> "Additional" einen neuen Client anlegen. Name ist dabei egal (vielleicht ja Stud.IP). 5. Es muss in Owncloud ein Client angelegt werden. Unter Administration -> "Additional" einen neuen Client anlegen. Name ist dabei egal (vielleicht ja Stud.IP).
6. Jetzt hat man einen OAuth2-Client erstellt und kopiert Client-ID und das Secret. Wichtig ist dabei, dass man die korrekte Redirect-URI angibt. Owncloud überprüft diese URI penibel. Sie sollte in etwa lauten `https://meinstud.ip/plugins.php/owncloudplugin/oauth/receive_access_token`. Auch sollte HTTPS aktiv sein. 6. Jetzt hat man einen OAuth2-Client erstellt und kopiert Client-ID und das Secret. Wichtig ist dabei, dass man die korrekte Redirect-URI angibt. Owncloud überprüft diese URI penibel. Sie sollte in etwa lauten `https://meinstud.ip/plugins.php/owncloudplugin/oauth/receive_access_token`. Auch sollte HTTPS aktiv sein.
Jetzt muss man sich überlegen, wie das Owncloud-Plugin genutzt werden soll in Stud.IP. Gibt es eine zentrale OwnCloud für alle Stud.IP-Nutzer oder kümmern sich die Nutzer selbst um eine eigene OwnCloud? Jetzt muss man sich überlegen, wie das Owncloud-Plugin genutzt werden soll in Stud.IP. Gibt es eine zentrale OwnCloud für alle Stud.IP-Nutzer oder kümmern sich die Nutzer selbst um eine eigene OwnCloud?
Zentral: Zentral:
1. Melde Dich im Stud.IP als Root an und gehe unter Admin -> System -> Konfiguration -> Owncloud. 1. Melde Dich im Stud.IP als Root an und gehe unter Admin -> System -> Konfiguration -> Owncloud.
2. Trage die oben gewonnene Client-ID beim Parameter `OWNCLOUD_CLIENT_ID` ein. 2. Trage die oben gewonnene Client-ID beim Parameter `OWNCLOUD_CLIENT_ID` ein.
...@@ -22,20 +22,20 @@ Zentral: ...@@ -22,20 +22,20 @@ Zentral:
Individuell: Individuell:
1. Der Nutzer muss dann alleine die obigen Schritte durchführen bzw. seinen OwnCloud-Admin fragen, ob er das für ihn tun kann und die Credentials übergibt. 1. Der Nutzer muss dann alleine die obigen Schritte durchführen bzw. seinen OwnCloud-Admin fragen, ob er das für ihn tun kann und die Credentials übergibt.
2. Im persönlichen Dateibereich von Stud.IP 4.0 gibt es in der Sidebar den Punkt "OwnCloud konfigurieren". Da muss er drauf klicken. Ein Dialog öffnet sich. 2. Im persönlichen Dateibereich von Stud.IP 4.0 gibt es in der Sidebar den Punkt "OwnCloud konfigurieren". Da muss er drauf klicken. Ein Dialog öffnet sich.
3. Man muss die Adresse der OwnCloud eintragen (z.B. `https://meineuni/owncloud`) und App-ID und Secret von oben eintragen und die OwnCloud aktiv schalten und speichern. 3. Man muss die Adresse der OwnCloud eintragen (z.B. `https://meineuni/owncloud`) und App-ID und Secret von oben eintragen und die OwnCloud aktiv schalten und speichern.
Die nächsten Schritte sind für beide Wege wieder dieselben: Die nächsten Schritte sind für beide Wege wieder dieselben:
1. Wer es individuell eingestellt hat, kennt es schon: Im persönlichen Dateibereich von Stud.IP 4.0 gibt es in der Sidebar den Punkt "OwnCloud konfigurieren". Da muss man drauf klicken. 1. Wer es individuell eingestellt hat, kennt es schon: Im persönlichen Dateibereich von Stud.IP 4.0 gibt es in der Sidebar den Punkt "OwnCloud konfigurieren". Da muss man drauf klicken.
2. Man muss das Häkchen für "aktiviert" setzen und speichern. 2. Man muss das Häkchen für "aktiviert" setzen und speichern.
3. Das Fenster lädt sich neu und ein Button erscheint oben "OwnCloud für Stud.IP freigeben". Dort klicken. 3. Das Fenster lädt sich neu und ein Button erscheint oben "OwnCloud für Stud.IP freigeben". Dort klicken.
4. Dann landet man in der OwnCloud und wird aufgefordert sich anzumelden. Vergewissern Sie sich in solchen Situationen immer (nicht nur jetzt), dass die URL stimmt und Sie Ihre Passwörter nicht einer anderen Seite als genau Ihrer OwnCloud zusenden. 4. Dann landet man in der OwnCloud und wird aufgefordert sich anzumelden. Vergewissern Sie sich in solchen Situationen immer (nicht nur jetzt), dass die URL stimmt und Sie Ihre Passwörter nicht einer anderen Seite als genau Ihrer OwnCloud zusenden.
5. Die OwnCloud fragt Sie, ob Stud.IP in Ihrem Namen Daten abrufen und verändern darf. Klicken Sie auf "Authorisieren". 5. Die OwnCloud fragt Sie, ob Stud.IP in Ihrem Namen Daten abrufen und verändern darf. Klicken Sie auf "Authorisieren".
6. Jetzt landen Sie wieder in Stud.IP und die Schnittstelle zwischen Stud.IP und OwnCloud sollte eingerichtet sein. 6. Jetzt landen Sie wieder in Stud.IP und die Schnittstelle zwischen Stud.IP und OwnCloud sollte eingerichtet sein.
Probleme? Probleme?
* Manchmal scheint fast alles zu funktionieren. OAuth-Access-Token ist da, Refresh-Token ist da und der Refresh scheint auch zu klappen, aber es werden keine Dateien und Ordner angezeigt. Es erscheint stattdessen eine Fehlermeldung: "No 'Authorization: Basic' header found. Either the client didn't send one, or the server is misconfigured, No 'Authorization: Basic' header found. Either the client didn't send one, or the server is misconfigured, No 'Authorization: Bearer' header found. Either the client didn't send one, or the server is mis-configured". In dem Fall muss man vermutlich in die Datei .htacess die Zeile einbauen `SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1` * Manchmal scheint fast alles zu funktionieren. OAuth-Access-Token ist da, Refresh-Token ist da und der Refresh scheint auch zu klappen, aber es werden keine Dateien und Ordner angezeigt. Es erscheint stattdessen eine Fehlermeldung: "No 'Authorization: Basic' header found. Either the client didn't send one, or the server is misconfigured, No 'Authorization: Basic' header found. Either the client didn't send one, or the server is misconfigured, No 'Authorization: Bearer' header found. Either the client didn't send one, or the server is mis-configured". In dem Fall muss man vermutlich in die Datei .htaccess die Zeile einbauen `SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1`
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment