karadav/lib/KaraDAV/NextCloud.php

182 lines
3.9 KiB
PHP
Raw Normal View History

2022-09-29 23:39:24 +00:00
<?php
namespace KaraDAV;
use KD2\WebDAV\NextCloud as WebDAV_NextCloud;
2022-09-30 13:17:47 +00:00
use KD2\WebDAV\Exception as WebDAV_Exception;
2022-09-29 23:39:24 +00:00
class NextCloud extends WebDAV_NextCloud
{
protected Users $users;
2022-09-30 13:17:47 +00:00
protected string $temporary_chunks_path;
2022-09-29 23:39:24 +00:00
public function __construct(Users $users)
2022-09-29 23:39:24 +00:00
{
$this->users = $users;
$this->temporary_chunks_path = sprintf(STORAGE_PATH, '_chunks');
$this->setRootURL(WWW_URL);
2022-09-29 23:39:24 +00:00
}
public function auth(?string $login, ?string $password): bool
{
$user = $this->users->login($login, $password);
if (!$user) {
// Try app session
$user = $this->users->appSessionLogin($login, $password);
}
2022-09-29 23:39:24 +00:00
if (!$user) {
return false;
}
$this->user = $user;
return true;
}
public function getUserName(): ?string
{
return $this->users->current()->login ?? null;
}
public function setUserName(string $login): bool
{
$ok = $this->users->setCurrent($login);
if ($ok) {
$this->user = $this->users->current();
}
return $ok;
}
public function getUserQuota(): array
{
return (array) $this->users->quota($this->users->current());
}
public function generateToken(): string
{
return sha1(random_bytes(16));
}
public function validateToken(string $token): ?array
{
$session = $this->users->appSessionValidateToken($token);
if (!$session) {
return null;
}
2022-10-24 22:34:50 +00:00
return ['login' => $session->user->login, 'password' => $session->password];
2022-09-29 23:39:24 +00:00
}
public function getLoginURL(?string $token): string
{
if ($token) {
return sprintf('%slogin.php?nc=%s', WWW_URL, $token);
}
else {
return sprintf('%slogin.php?nc=redirect', WWW_URL);
}
}
public function getDirectDownloadSecret(string $uri, string $login): string
{
$user = $this->users->get($login);
if (!$user) {
throw new WebDAV_Exception('No user with that name', 401);
}
return WebDAV::hmac([$uri, $user->login, $user->password]);
2022-09-29 23:39:24 +00:00
}
2022-09-30 13:17:47 +00:00
protected function cleanChunks(): void
{
$expire = time() - 36*3600;
foreach (glob($this->temporary_chunks_path . '/*/*') as $dir) {
$first_file = current(glob($dir . '/*'));
if (filemtime($first_file) < $expire) {
Storage::deleteDirectory($dir);
2022-09-30 13:17:47 +00:00
}
}
}
public function storeChunk(string $login, string $name, string $part, $pointer): void
{
$this->cleanChunks();
$path = $this->temporary_chunks_path . '/' . $login . '/' . $name;
@mkdir($path, 0777, true);
$file_path = $path . '/' . $part;
$out = fopen($file_path, 'wb');
$quota = $this->getUserQuota();
$used = $quota['used'] + Storage::getDirectorySize($path);
while (!feof($pointer)) {
$data = fread($pointer, 8192);
$used += strlen($used);
if ($used > $quota['free']) {
$this->deleteChunks($login, $name);
throw new WebDAV_Exception('Your quota does not allow for the upload of this file', 403);
}
fwrite($out, $data);
}
fclose($out);
fclose($pointer);
}
public function deleteChunks(string $login, string $name): void
{
$path = $this->temporary_chunks_path . '/' . $login . '/' . $name;
Storage::deleteDirectory($path);
}
public function assembleChunks(string $login, string $name, string $target, ?int $mtime): array
2022-09-30 13:17:47 +00:00
{
$target = $this->users->current()->path . $target;
$parent = dirname($target);
if (!is_dir($parent)) {
throw new WebDAV_Exception('Target parent directory does not exist', 409);
}
$path = $this->temporary_chunks_path . '/' . $login . '/' . $name;
$exists = file_exists($target);
if ($exists && is_dir($target)) {
throw new WebDAV_Exception('Target exists and is a directory', 409);
2022-09-30 13:17:47 +00:00
}
$out = fopen($target, 'wb');
foreach (glob($path . '/*') as $file) {
$in = fopen($file, 'rb');
while (!feof($in)) {
fwrite($out, fread($in, 8192));
}
fclose($in);
}
fclose($out);
$this->deleteChunks($login, $name);
if ($mtime) {
touch($target, $mtime);
}
return ['created' => !$exists, 'etag' => md5(filemtime($target) . filesize($target))];
2022-09-30 13:17:47 +00:00
}
2022-09-29 23:39:24 +00:00
}