Skip to content

Add Access Control Layer #40

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions src/AccessControl/AccessControlManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

namespace DataKit\DataViews\AccessControl;

use SplStack;

/**
* Manages the current and previously set Access Controllers.
*
* By default, the manager will return a {@see ReadOnlyAccessController}.
*
* @since $ver$
*/
final class AccessControlManager {
/**
* The current stack of Access Control Managers.
*
* @since $ver$
*
* @var SplStack<AccessController>
*/
private static \SplStack $access_controllers;

/**
* Prevent creating multiple instances of the manager.
*
* @since $ver$
*/
private function __construct() {
}

/**
* Lazily initializes the Access Control Manager.
*
* @since $ver$
*
* @return void
*/
private static function initialize(): void {
if ( ! isset( self::$access_controllers ) ) {
self::$access_controllers = new \SplStack();
self::set( new ReadOnlyAccessController() );
}
}

/**
* Sets the current AccessController.
*
* @since $ver$
*
* @param AccessController $access_controller The access controller.
*/
public static function set( AccessController $access_controller ): void {
self::initialize();

self::$access_controllers->push( $access_controller );
}

/**
* Returns the current Access Controller.
*
* @since $ver$
*
* @return AccessController The current AccessController.
*/
public static function current(): AccessController {
self::initialize();

return self::$access_controllers->top();
}

/**
* Resets the current Access Controller to the previous.
*
* @since $ver$
*/
public static function reset(): void {
self::initialize();

if ( self::$access_controllers->count() > 1 ) {
self::$access_controllers->pop();
}
}
}
25 changes: 25 additions & 0 deletions src/AccessControl/AccessController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace DataKit\DataViews\AccessControl;

use DataKit\DataViews\AccessControl\Capability\Capability;
use DataKit\DataViews\DataView\DataView;
use DataKit\DataViews\Field\Field;

/**
* Manages the access the current user has on {@see DataView} and {@see Field} objects.
*
* @since $ver$
*/
interface AccessController {
/**
* Returns whether the user has the provided capability.
*
* @since $ver$
*
* @param Capability $capability The capability to test.
*
* @return bool Whether the user has the capability.
*/
public function can( Capability $capability ): bool;
}
28 changes: 28 additions & 0 deletions src/AccessControl/Capability/Capability.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace DataKit\DataViews\AccessControl\Capability;

/**
* Represents a capability a user can have.
*
* @since $ver$
*/
interface Capability {
/**
* Returns whether the capability is related to mutation.
*
* @since $ver$
*
* @return bool Whether the capability is related to mutation.
*/
public function is_mutative(): bool;

/**
* Returns whether the capability is related to destruction.
*
* @since $ver$
*
* @return bool Whether the capability is related to destruction.
*/
public function is_destructive(): bool;
}
57 changes: 57 additions & 0 deletions src/AccessControl/Capability/DataViewCapability.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

namespace DataKit\DataViews\AccessControl\Capability;

use DataKit\DataViews\DataView\DataView;

/**
* Represents a capability that is connected to a DataView.
*
* @since $ver$
*/
abstract class DataViewCapability implements Capability {
/**
* The DataView.
*
* @since $ver$
*
* @var DataView
*/
protected DataView $dataview;

/**
* Creates the Capability.
*
* @since $ver$
*/
public function __construct( DataView $dataview ) {
$this->dataview = $dataview;
}

/**
* Returns the DataView connected to the capability.
*
* @since $ver$
*/
public function dataview(): DataView {
return $this->dataview;
}

/**
* {@inheritDoc}
*
* @since $ver$
*/
public function is_mutative(): bool {
return false;
}

/**
* {@inheritDoc}
*
* @since $ver$
*/
public function is_destructive(): bool {
return false;
}
}
19 changes: 19 additions & 0 deletions src/AccessControl/Capability/DeleteDataView.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace DataKit\DataViews\AccessControl\Capability;

/**
* A capability representing a user can delete a DataView.
*
* @since $ver$
*/
final class DeleteDataView extends DataViewCapability {
/**
* {@inheritDoc}
*
* @since $ver$
*/
public function is_destructive(): bool {
return true;
}
}
19 changes: 19 additions & 0 deletions src/AccessControl/Capability/EditDataView.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace DataKit\DataViews\AccessControl\Capability;

/**
* A capability representing a user can edit a DataView.
*
* @since $ver$
*/
final class EditDataView extends DataViewCapability {
/**
* {@inheritDoc}
*
* @since $ver$
*/
public function is_mutative(): bool {
return true;
}
}
11 changes: 11 additions & 0 deletions src/AccessControl/Capability/ViewDataView.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace DataKit\DataViews\AccessControl\Capability;

/**
* A capability representing a user can view a DataView.
*
* @since $ver$
*/
final class ViewDataView extends DataViewCapability {
}
47 changes: 47 additions & 0 deletions src/AccessControl/Capability/ViewField.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace DataKit\DataViews\AccessControl\Capability;

use DataKit\DataViews\DataView\DataView;
use DataKit\DataViews\Field\Field;

/**
* A capability representing a user can view a DataView field.
*
* @since $ver$
*/
final class ViewField extends DataViewCapability {
/**
* The Field.
*
* @since $ver$
*
* @var Field
*/
private Field $field;

/**
* Creates the capability.
*
* @since $ver$
*
* @param DataView $dataview The DataView.
* @param Field $field The Field.
*/
public function __construct( DataView $dataview, Field $field ) {
parent::__construct( $dataview );

$this->field = $field;
}

/**
* Returns the Field to view.
*
* @since $ver$
*
* @return Field The Field.
*/
public function field(): Field {
return $this->field;
}
}
21 changes: 21 additions & 0 deletions src/AccessControl/ReadOnlyAccessController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace DataKit\DataViews\AccessControl;

use DataKit\DataViews\AccessControl\Capability\Capability;

/**
* AccessControlManager that allows read access to anyone.
*
* @since $ver$
*/
final class ReadOnlyAccessController implements AccessController {
/**
* {@inheritDoc}
*
* @since $ver$
*/
public function can( Capability $capability ): bool {
return ! $capability->is_mutative() && ! $capability->is_destructive();
}
}
Loading