nextcloud: add support for upstream LDAP accounts (#4103)

This commit is contained in:
Fabian Franz BSc 2020-05-14 19:59:07 +02:00 committed by GitHub
parent 9effd6afda
commit ef1bd41789
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -107,14 +107,15 @@ class Nextcloud extends Base implements IBackupProvider
* @param array $conf configuration array
* @return array of validation errors when not saved
* @throws \OPNsense\Base\ModelException
* @throws \ReflectionException
*/
public function setConfiguration($conf)
{
$nextcloud = new NextcloudSettings();
$this->setModelProperties($nextcloud, $conf);
$validation_messages = $this->validateModel($nextcloud);
$nextCloud = new NextcloudSettings();
$this->setModelProperties($nextCloud, $conf);
$validation_messages = $this->validateModel($nextCloud);
if (empty($validation_messages)) {
$nextcloud->serializeToConfig();
$nextCloud->serializeToConfig();
Config::getInstance()->save();
}
return $validation_messages;
@ -124,6 +125,7 @@ class Nextcloud extends Base implements IBackupProvider
* perform backup
* @return array filelist
* @throws \OPNsense\Base\ModelException
* @throws \ReflectionException
*/
public function backup()
{
@ -144,21 +146,23 @@ class Nextcloud extends Base implements IBackupProvider
$confdata = $this->encrypt($confdata, $crypto_password);
}
try {
$directories = $this->listFiles($url, $username, $password, '/');
$internal_username = $this->getInternalUsername($url, $username, $password);
$directories = $this->listFiles($url, $username, $password, $internal_username, '/');
if (!in_array("/$backupdir/", $directories)) {
$this->create_directory($url, $username, $password, $backupdir);
$this->create_directory($url, $username, $password, $internal_username, $backupdir);
}
$this->upload_file_content(
$url,
$username,
$password,
$internal_username,
$backupdir,
$configname,
$confdata
);
// do not list directories
return array_filter(
$this->listFiles($url, $username, $password, "/$backupdir/", false),
$this->listFiles($url, $username, $password, $internal_username, "/$backupdir/", false),
function ($filename) {
return (substr($filename, -1) !== '/');
}
@ -174,15 +178,16 @@ class Nextcloud extends Base implements IBackupProvider
* @param string $url remote location
* @param string $username username
* @param string $password password to use
* @param string $internal_username internal username for the webdav directory
* @param string $directory location to list
* @param bool $only_dirs only list directories
* @return array
* @throws \Exception
*/
public function listFiles($url, $username, $password, $directory = '/', $only_dirs = true)
public function listFiles($url, $username, $password, $internal_username, $directory = '/', $only_dirs = true)
{
$result = $this->curl_request(
"$url/remote.php/dav/files/$username$directory",
"$url/remote.php/dav/files/$internal_username$directory",
$username,
$password,
'PROPFIND',
@ -195,7 +200,7 @@ class Nextcloud extends Base implements IBackupProvider
// d:response
if ($response->getName() == 'response') {
$fileurl = (string)$response->href;
$dirname = explode("/remote.php/dav/files/$username", $fileurl, 2)[1];
$dirname = explode("/remote.php/dav/files/$internal_username", $fileurl, 2)[1];
if (
$response->propstat->prop->resourcetype->children()->count() > 0 &&
$response->propstat->prop->resourcetype->children()[0]->getName() == 'collection' &&
@ -220,10 +225,10 @@ class Nextcloud extends Base implements IBackupProvider
* @param string $local_file_content contents to save
* @throws \Exception when upload fails
*/
public function upload_file_content($url, $username, $password, $backupdir, $filename, $local_file_content)
public function upload_file_content($url, $username, $password, $internal_username, $backupdir, $filename, $local_file_content)
{
$this->curl_request(
$url . "/remote.php/dav/files/$username/$backupdir/$filename",
$url . "/remote.php/dav/files/$internal_username/$backupdir/$filename",
$username,
$password,
'PUT',
@ -240,10 +245,10 @@ class Nextcloud extends Base implements IBackupProvider
* @param string $backupdir remote directory
* @throws \Exception when create dir fails
*/
public function create_directory($url, $username, $password, $backupdir)
public function create_directory($url, $username, $password, $internal_username, $backupdir)
{
$this->curl_request(
$url . "/remote.php/dav/files/$username/$backupdir",
$url . "/remote.php/dav/files/$internal_username/$backupdir",
$username,
$password,
'MKCOL',
@ -251,6 +256,30 @@ class Nextcloud extends Base implements IBackupProvider
);
}
public function getInternalUsername($url, $username, $password) : string {
$xml_response = $this->ocs_request(
"$url/ocs/v1.php/cloud/user",
$username,
$password,
"GET",
"Cannot get real username"
);
try {
$data = $xml_response->data;
if ($data == null) {
return $username; // no data found, return the old username
}
$real_username = $data->id;
if ($real_username == null) {
return $username;
}
return $real_username;
} catch (\Exception $exception) {
return $username; // error - continue with old username
}
}
/**
* @param string $url remote location
* @param string $username remote user
@ -258,10 +287,12 @@ class Nextcloud extends Base implements IBackupProvider
* @param string $method http method, PUT, GET, ...
* @param string $error_message message to log on failure
* @param null|string $postdata http body
* @param array $headers HTTP headers
* @return array response status
* @throws \Exception when request fails
*/
public function curl_request($url, $username, $password, $method, $error_message, $postdata = null)
public function curl_request($url, $username, $password, $method, $error_message, $postdata = null,
$headers = array("User-Agent: OPNsense Firewall"))
{
$curl = curl_init();
curl_setopt_array($curl, array(
@ -273,9 +304,7 @@ class Nextcloud extends Base implements IBackupProvider
CURLOPT_TIMEOUT => 60, // maximum time: 1 min
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_USERPWD => $username . ":" . $password,
CURLOPT_HTTPHEADER => array(
"User-Agent: OPNsense Firewall"
)
CURLOPT_HTTPHEADER => $headers
));
if ($postdata != null) {
curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
@ -292,13 +321,42 @@ class Nextcloud extends Base implements IBackupProvider
return array('response' => $response, 'info' => $info);
}
/**
* @param $url string URL to call
* @param $username string username
* @param $password string password
* @param $method string HTTP verb
* @param $error_message string error message to forward to the http calling method
* @param null $postdata post data if any (can be null)
* @return array|\SimpleXMLElement|null
* @throws \Exception
*/
public function ocs_request($url, $username, $password, $method, $error_message, $postdata = null) {
$headers = $headers = array("User-Agent: OPNsense Firewall", "OCS-APIRequest: true");
$result = $this->curl_request($url, $username, $password, $method, $error_message, $postdata, $headers);
if (array_key_exists('content_type', $result['info'])) {
if (stripos($result['info']['content_type'], 'xml') !== FALSE) {
return new \SimpleXMLElement($result['response']);
}
if (stripos($result['info']['content_type'], 'json') !== FALSE) {
return json_decode($result['response'], true);
}
throw new \Exception();
}
return null;
}
/**
* Is this provider enabled
* @return boolean enabled status
* @throws \OPNsense\Base\ModelException
* @throws \ReflectionException
*/
public function isEnabled()
{
$nextcloud = new NextcloudSettings();
return (string)$nextcloud->enabled === "1";
$nextCloud = new NextcloudSettings();
return (string)$nextCloud->enabled === "1";
}
}