Skip to content

Commit dc89bc1

Browse files
authored
Merge pull request #40 from UseDataKit/feature/acl
Add Access Control Layer
2 parents 27fea2c + 7e64e72 commit dc89bc1

16 files changed

+440
-12
lines changed
+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
namespace DataKit\DataViews\AccessControl;
4+
5+
use SplStack;
6+
7+
/**
8+
* Manages the current and previously set Access Controllers.
9+
*
10+
* By default, the manager will return a {@see ReadOnlyAccessController}.
11+
*
12+
* @since $ver$
13+
*/
14+
final class AccessControlManager {
15+
/**
16+
* The current stack of Access Control Managers.
17+
*
18+
* @since $ver$
19+
*
20+
* @var SplStack<AccessController>
21+
*/
22+
private static \SplStack $access_controllers;
23+
24+
/**
25+
* Prevent creating multiple instances of the manager.
26+
*
27+
* @since $ver$
28+
*/
29+
private function __construct() {
30+
}
31+
32+
/**
33+
* Lazily initializes the Access Control Manager.
34+
*
35+
* @since $ver$
36+
*
37+
* @return void
38+
*/
39+
private static function initialize(): void {
40+
if ( ! isset( self::$access_controllers ) ) {
41+
self::$access_controllers = new \SplStack();
42+
self::set( new ReadOnlyAccessController() );
43+
}
44+
}
45+
46+
/**
47+
* Sets the current AccessController.
48+
*
49+
* @since $ver$
50+
*
51+
* @param AccessController $access_controller The access controller.
52+
*/
53+
public static function set( AccessController $access_controller ): void {
54+
self::initialize();
55+
56+
self::$access_controllers->push( $access_controller );
57+
}
58+
59+
/**
60+
* Returns the current Access Controller.
61+
*
62+
* @since $ver$
63+
*
64+
* @return AccessController The current AccessController.
65+
*/
66+
public static function current(): AccessController {
67+
self::initialize();
68+
69+
return self::$access_controllers->top();
70+
}
71+
72+
/**
73+
* Resets the current Access Controller to the previous.
74+
*
75+
* @since $ver$
76+
*/
77+
public static function reset(): void {
78+
self::initialize();
79+
80+
if ( self::$access_controllers->count() > 1 ) {
81+
self::$access_controllers->pop();
82+
}
83+
}
84+
}
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace DataKit\DataViews\AccessControl;
4+
5+
use DataKit\DataViews\AccessControl\Capability\Capability;
6+
use DataKit\DataViews\DataView\DataView;
7+
use DataKit\DataViews\Field\Field;
8+
9+
/**
10+
* Manages the access the current user has on {@see DataView} and {@see Field} objects.
11+
*
12+
* @since $ver$
13+
*/
14+
interface AccessController {
15+
/**
16+
* Returns whether the user has the provided capability.
17+
*
18+
* @since $ver$
19+
*
20+
* @param Capability $capability The capability to test.
21+
*
22+
* @return bool Whether the user has the capability.
23+
*/
24+
public function can( Capability $capability ): bool;
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace DataKit\DataViews\AccessControl\Capability;
4+
5+
/**
6+
* Represents a capability a user can have.
7+
*
8+
* @since $ver$
9+
*/
10+
interface Capability {
11+
/**
12+
* Returns whether the capability is related to mutation.
13+
*
14+
* @since $ver$
15+
*
16+
* @return bool Whether the capability is related to mutation.
17+
*/
18+
public function is_mutative(): bool;
19+
20+
/**
21+
* Returns whether the capability is related to destruction.
22+
*
23+
* @since $ver$
24+
*
25+
* @return bool Whether the capability is related to destruction.
26+
*/
27+
public function is_destructive(): bool;
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
namespace DataKit\DataViews\AccessControl\Capability;
4+
5+
use DataKit\DataViews\DataView\DataView;
6+
7+
/**
8+
* Represents a capability that is connected to a DataView.
9+
*
10+
* @since $ver$
11+
*/
12+
abstract class DataViewCapability implements Capability {
13+
/**
14+
* The DataView.
15+
*
16+
* @since $ver$
17+
*
18+
* @var DataView
19+
*/
20+
protected DataView $dataview;
21+
22+
/**
23+
* Creates the Capability.
24+
*
25+
* @since $ver$
26+
*/
27+
public function __construct( DataView $dataview ) {
28+
$this->dataview = $dataview;
29+
}
30+
31+
/**
32+
* Returns the DataView connected to the capability.
33+
*
34+
* @since $ver$
35+
*/
36+
public function dataview(): DataView {
37+
return $this->dataview;
38+
}
39+
40+
/**
41+
* {@inheritDoc}
42+
*
43+
* @since $ver$
44+
*/
45+
public function is_mutative(): bool {
46+
return false;
47+
}
48+
49+
/**
50+
* {@inheritDoc}
51+
*
52+
* @since $ver$
53+
*/
54+
public function is_destructive(): bool {
55+
return false;
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace DataKit\DataViews\AccessControl\Capability;
4+
5+
/**
6+
* A capability representing a user can delete a DataView.
7+
*
8+
* @since $ver$
9+
*/
10+
final class DeleteDataView extends DataViewCapability {
11+
/**
12+
* {@inheritDoc}
13+
*
14+
* @since $ver$
15+
*/
16+
public function is_destructive(): bool {
17+
return true;
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace DataKit\DataViews\AccessControl\Capability;
4+
5+
/**
6+
* A capability representing a user can edit a DataView.
7+
*
8+
* @since $ver$
9+
*/
10+
final class EditDataView extends DataViewCapability {
11+
/**
12+
* {@inheritDoc}
13+
*
14+
* @since $ver$
15+
*/
16+
public function is_mutative(): bool {
17+
return true;
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace DataKit\DataViews\AccessControl\Capability;
4+
5+
/**
6+
* A capability representing a user can view a DataView.
7+
*
8+
* @since $ver$
9+
*/
10+
final class ViewDataView extends DataViewCapability {
11+
}
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace DataKit\DataViews\AccessControl\Capability;
4+
5+
use DataKit\DataViews\DataView\DataView;
6+
use DataKit\DataViews\Field\Field;
7+
8+
/**
9+
* A capability representing a user can view a DataView field.
10+
*
11+
* @since $ver$
12+
*/
13+
final class ViewField extends DataViewCapability {
14+
/**
15+
* The Field.
16+
*
17+
* @since $ver$
18+
*
19+
* @var Field
20+
*/
21+
private Field $field;
22+
23+
/**
24+
* Creates the capability.
25+
*
26+
* @since $ver$
27+
*
28+
* @param DataView $dataview The DataView.
29+
* @param Field $field The Field.
30+
*/
31+
public function __construct( DataView $dataview, Field $field ) {
32+
parent::__construct( $dataview );
33+
34+
$this->field = $field;
35+
}
36+
37+
/**
38+
* Returns the Field to view.
39+
*
40+
* @since $ver$
41+
*
42+
* @return Field The Field.
43+
*/
44+
public function field(): Field {
45+
return $this->field;
46+
}
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace DataKit\DataViews\AccessControl;
4+
5+
use DataKit\DataViews\AccessControl\Capability\Capability;
6+
7+
/**
8+
* AccessControlManager that allows read access to anyone.
9+
*
10+
* @since $ver$
11+
*/
12+
final class ReadOnlyAccessController implements AccessController {
13+
/**
14+
* {@inheritDoc}
15+
*
16+
* @since $ver$
17+
*/
18+
public function can( Capability $capability ): bool {
19+
return ! $capability->is_mutative() && ! $capability->is_destructive();
20+
}
21+
}

0 commit comments

Comments
 (0)