Roles Folder

This commit is contained in:
Evann Regnault 2024-06-19 16:47:56 +02:00
parent 4979ec6ca5
commit 3ab65d1c51
5 changed files with 97 additions and 27 deletions

View file

@ -1,6 +1,8 @@
<?php <?php
use Collections\HomeCollection; use Collections\HomeCollection;
use Collections\RolesCollection;
use Principal\RolesBackend;
use Sabre\DAV; use Sabre\DAV;
use Dotenv\Dotenv; use Dotenv\Dotenv;
@ -10,18 +12,17 @@ require 'vendor/autoload.php';
$dotenv = Dotenv::createImmutable(__DIR__); $dotenv = Dotenv::createImmutable(__DIR__);
$dotenv->load(); $dotenv->load();
$principalBackend = new RolesBackend();
$aclPlugin = new \Sabre\DAVACL\Plugin();
// Set Auth // Set Auth
$authBackend = new Keycloak\KeycloakAuth($aclPlugin,$_ENV['client_id'], $_ENV['client_secret'], $_ENV['keycloak_token_url'] ); $authBackend = new Keycloak\KeycloakAuth($principalBackend,$_ENV['client_id'], $_ENV['client_secret'], $_ENV['keycloak_token_url'] );
$authBackend->setRealm($_ENV['realm']); $authBackend->setRealm($_ENV['realm']);
$authPlugin = new DAV\Auth\Plugin($authBackend); $authPlugin = new DAV\Auth\Plugin($authBackend);
$path = $_ENV['users_path'];
// The server object is responsible for making sense out of the WebDAV protocol // The server object is responsible for making sense out of the WebDAV protocol
$server = new DAV\Server([new HomeCollection($authPlugin, $_ENV['users_path'])]); $server = new DAV\Server([new HomeCollection($authPlugin, $path), new RolesCollection($principalBackend, $path)]);
// If your server is not on your webroot, make sure the following line has the // If your server is not on your webroot, make sure the following line has the
// correct information // correct information
@ -34,12 +35,12 @@ $lockPlugin = new DAV\Locks\Plugin($lockBackend);
$server->addPlugin($lockPlugin); $server->addPlugin($lockPlugin);
$principalPlugin = new Sabre\DAVACL\Plugin($principalBackend);
// This ensures that we get a pretty index in the browser, but it is
// optional.
$server->addPlugin(new DAV\Browser\Plugin());
$server->addPlugin($authPlugin); $server->addPlugin($authPlugin);
$server->addPlugin($aclPlugin); $server->addPlugin($principalPlugin);
$server->addPlugin(new DAV\Browser\Plugin());
// All we need to do now, is to fire up the server // All we need to do now, is to fire up the server
$server->start(); $server->start();

View file

@ -12,13 +12,13 @@ class HomeCollection extends Collection
private $userPath; private $userPath;
public function __construct(AuthPlugin $authPlugin, $userPath) public function __construct(AuthPlugin $authPlugin, string $userPath)
{ {
$this->plugin = $authPlugin; $this->plugin = $authPlugin;
$this->userPath = $userPath; $this->userPath = $userPath;
} }
public function getChildren() public function getChildren(): array
{ {
$principal = $this->plugin->getCurrentPrincipal(); $principal = $this->plugin->getCurrentPrincipal();
$username = explode("/", $principal)[1]; $username = explode("/", $principal)[1];
@ -31,7 +31,7 @@ class HomeCollection extends Collection
return [new Directory($path.$username, $username)]; return [new Directory($path.$username, $username)];
} }
public function getName() public function getName(): string
{ {
return "Home"; return "Home";
} }

View file

@ -0,0 +1,38 @@
<?php
namespace Collections;
use Principal\RolesBackend;
use Sabre\DAV\Collection;
use Sabre\DAV\FSExt\Directory as SabreDirectory;
class RolesCollection extends Collection {
private RolesBackend $principalBackend;
private $dataRoot;
public function __construct(RolesBackend $principal_backend, string $dataRoot)
{
$this->$dataRoot = $dataRoot;
$this->principalBackend = $principal_backend;
}
public function getChildren() : array {
$path = $this->dataRoot;
$dirs = [];
foreach ($this->principalBackend->roles as $role) {
if (!is_dir($path . 'public/' . $role)){
mkdir($path . 'public/' . $role, 0777, true);
}
$dirs[] = new SabreDirectory($path . 'public/' . $role, $role);
}
return $dirs;
}
public function getName() : string
{
return "Groups";
}
}

View file

@ -2,19 +2,21 @@
namespace Keycloak; namespace Keycloak;
use Principal\RolesBackend;
use Sabre\DAV\Auth\Backend\AbstractBasic; use Sabre\DAV\Auth\Backend\AbstractBasic;
use Sabre\DAVACL\Plugin as AclPlugin;
class KeycloakAuth extends AbstractBasic class KeycloakAuth extends AbstractBasic
{ {
private $aclPlugin;
private $client_id;
private $client_secret;
private $keycloakTokenUrl;
public function __construct(AclPlugin $plugin, string $client_id, string $client_secret, string $keycloakTokenUrl) private RolesBackend $principal_backend;
private string $client_id;
private string $client_secret;
private string $keycloakTokenUrl;
public function __construct(RolesBackend $principal_backend, string $client_id,
string $client_secret, string $keycloakTokenUrl)
{ {
$this->aclPlugin = $plugin; $this->principal_backend = $principal_backend;
$this->client_id = $client_id; $this->client_id = $client_id;
$this->client_secret = $client_secret; $this->client_secret = $client_secret;
$this->keycloakTokenUrl = $keycloakTokenUrl; $this->keycloakTokenUrl = $keycloakTokenUrl;
@ -26,7 +28,7 @@ class KeycloakAuth extends AbstractBasic
curl_setopt_array($curl, [ curl_setopt_array($curl, [
CURLOPT_URL => $this->keycloakTokenUrl, CURLOPT_URL => $this->keycloakTokenUrl,
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "", CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10, CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30, CURLOPT_TIMEOUT => 30,
@ -38,17 +40,32 @@ class KeycloakAuth extends AbstractBasic
], ],
]); ]);
curl_exec($curl); $body = curl_exec($curl);
$err = curl_error($curl); $err = curl_error($curl);
$data = curl_getinfo($curl); $data = curl_getinfo($curl);
curl_close($curl); curl_close($curl);
if ($err || $data['http_code'] != 200) { if ($err || $data['http_code'] != 200) {
return false; return false;
} else { } else {
$x = json_decode($body);
$user_data = json_decode(base64_decode(explode(".",$x->access_token)[1]), true);
$resource_data = $user_data["resource_access"];
if (is_null($resource_data) || !array_key_exists($this->client_id, $resource_data)) return true;
$client_data = $resource_data[$this->client_id];
if (is_null($client_data)) return true;
$roles = $client_data["roles"];
if (is_null($client_data)) return true;
$this->principal_backend->setPrincipals($roles);
return true; return true;
} }

View file

@ -4,17 +4,21 @@ namespace Principal;
use Sabre\DAVACL\PrincipalBackend\AbstractBackend; use Sabre\DAVACL\PrincipalBackend\AbstractBackend;
class CustomBackend extends AbstractBackend class RolesBackend extends AbstractBackend
{ {
public array $roles = [];
public array $principals = [];
public function getPrincipalsByPrefix($prefixPath) public function getPrincipalsByPrefix($prefixPath)
{ {
// TODO: Implement getPrincipalsByPrefix() method. return array_filter(array: $this->principals, callback: function($k) use($prefixPath) {
return str_starts_with($prefixPath, $k);
});
} }
public function getPrincipalByPath($path) public function getPrincipalByPath($path)
{ {
// TODO: Implement getPrincipalByPath() method. return $path;
} }
public function updatePrincipal($path, \Sabre\DAV\PropPatch $propPatch) public function updatePrincipal($path, \Sabre\DAV\PropPatch $propPatch)
@ -34,11 +38,21 @@ class CustomBackend extends AbstractBackend
public function getGroupMembership($principal) public function getGroupMembership($principal)
{ {
// TODO: Implement getGroupMembership() method. if (!str_contains("groups")) {
return $this->principals;
}
else return [$principal];
} }
public function setGroupMemberSet($principal, array $members) public function setGroupMemberSet($principal, array $members)
{ {
// TODO: Implement setGroupMemberSet() method. // TODO: Implement setGroupMemberSet() method.
} }
public function setPrincipals(array $roles) {
$this->roles = $roles;
$this->principals = array_map(array: $roles, callback: function($r) {
return "/principals/groups/" . $r;
});
}
} }