|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
declare(strict_types=1); |
|
4
|
|
|
|
|
5
|
|
|
namespace GraphQLAPI\GraphQLAPI\ModuleResolvers; |
|
6
|
|
|
|
|
7
|
|
|
use GraphQLAPI\GraphQLAPI\Plugin; |
|
8
|
|
|
use PoP\AccessControl\Schema\SchemaModes; |
|
9
|
|
|
use GraphQLAPI\GraphQLAPI\ComponentConfiguration; |
|
10
|
|
|
use GraphQLAPI\GraphQLAPI\ModuleSettings\Properties; |
|
11
|
|
|
use GraphQLAPI\GraphQLAPI\Facades\ModuleRegistryFacade; |
|
12
|
|
|
use GraphQLAPI\GraphQLAPI\ModuleResolvers\ModuleResolverTrait; |
|
13
|
|
|
|
|
14
|
|
|
class AccessControlFunctionalityModuleResolver extends AbstractFunctionalityModuleResolver |
|
15
|
|
|
{ |
|
16
|
|
|
use ModuleResolverTrait { |
|
17
|
|
|
ModuleResolverTrait::hasDocumentation as upstreamHasDocumentation; |
|
18
|
|
|
} |
|
19
|
|
|
|
|
20
|
|
|
public const PUBLIC_PRIVATE_SCHEMA = Plugin::NAMESPACE . '\public-private-schema'; |
|
21
|
|
|
public const ACCESS_CONTROL = Plugin::NAMESPACE . '\access-control'; |
|
22
|
|
|
public const ACCESS_CONTROL_RULE_DISABLE_ACCESS = Plugin::NAMESPACE . '\access-control-rule-disable-access'; |
|
23
|
|
|
public const ACCESS_CONTROL_RULE_USER_STATE = Plugin::NAMESPACE . '\access-control-rule-user-state'; |
|
24
|
|
|
public const ACCESS_CONTROL_RULE_USER_ROLES = Plugin::NAMESPACE . '\access-control-rule-user-roles'; |
|
25
|
|
|
public const ACCESS_CONTROL_RULE_USER_CAPABILITIES = Plugin::NAMESPACE . '\access-control-rule-user-capabilities'; |
|
26
|
|
|
|
|
27
|
|
|
/** |
|
28
|
|
|
* Setting options |
|
29
|
|
|
*/ |
|
30
|
|
|
public const OPTION_MODE = 'mode'; |
|
31
|
|
|
public const OPTION_ENABLE_GRANULAR = 'granular'; |
|
32
|
|
|
|
|
33
|
|
|
public static function getModulesToResolve(): array |
|
34
|
|
|
{ |
|
35
|
|
|
return [ |
|
36
|
|
|
self::ACCESS_CONTROL, |
|
37
|
|
|
self::ACCESS_CONTROL_RULE_DISABLE_ACCESS, |
|
38
|
|
|
self::ACCESS_CONTROL_RULE_USER_STATE, |
|
39
|
|
|
self::ACCESS_CONTROL_RULE_USER_ROLES, |
|
40
|
|
|
self::ACCESS_CONTROL_RULE_USER_CAPABILITIES, |
|
41
|
|
|
self::PUBLIC_PRIVATE_SCHEMA, |
|
42
|
|
|
]; |
|
43
|
|
|
} |
|
44
|
|
|
|
|
45
|
|
|
/** |
|
46
|
|
|
* Enable to customize a specific UI for the module |
|
47
|
|
|
*/ |
|
48
|
|
|
public function getModuleSubtype(string $module): ?string |
|
49
|
|
|
{ |
|
50
|
|
|
return 'accesscontrol'; |
|
51
|
|
|
} |
|
52
|
|
|
|
|
53
|
|
|
public function getDependedModuleLists(string $module): array |
|
54
|
|
|
{ |
|
55
|
|
|
switch ($module) { |
|
56
|
|
|
case self::ACCESS_CONTROL: |
|
57
|
|
|
return [ |
|
58
|
|
|
[ |
|
59
|
|
|
FunctionalityModuleResolver::SCHEMA_CONFIGURATION, |
|
60
|
|
|
], |
|
61
|
|
|
]; |
|
62
|
|
|
case self::PUBLIC_PRIVATE_SCHEMA: |
|
63
|
|
|
case self::ACCESS_CONTROL_RULE_DISABLE_ACCESS: |
|
64
|
|
|
case self::ACCESS_CONTROL_RULE_USER_STATE: |
|
65
|
|
|
case self::ACCESS_CONTROL_RULE_USER_ROLES: |
|
66
|
|
|
case self::ACCESS_CONTROL_RULE_USER_CAPABILITIES: |
|
67
|
|
|
return [ |
|
68
|
|
|
[ |
|
69
|
|
|
self::ACCESS_CONTROL, |
|
70
|
|
|
], |
|
71
|
|
|
]; |
|
72
|
|
|
} |
|
73
|
|
|
return parent::getDependedModuleLists($module); |
|
74
|
|
|
} |
|
75
|
|
|
|
|
76
|
|
|
public function getName(string $module): string |
|
77
|
|
|
{ |
|
78
|
|
|
$names = [ |
|
79
|
|
|
self::PUBLIC_PRIVATE_SCHEMA => \__('Public/Private Schema', 'graphql-api'), |
|
80
|
|
|
self::ACCESS_CONTROL => \__('Access Control', 'graphql-api'), |
|
81
|
|
|
self::ACCESS_CONTROL_RULE_DISABLE_ACCESS => \__('Access Control Rule: Disable Access', 'graphql-api'), |
|
82
|
|
|
self::ACCESS_CONTROL_RULE_USER_STATE => \__('Access Control Rule: User State', 'graphql-api'), |
|
83
|
|
|
self::ACCESS_CONTROL_RULE_USER_ROLES => \__('Access Control Rule: User Roles', 'graphql-api'), |
|
84
|
|
|
self::ACCESS_CONTROL_RULE_USER_CAPABILITIES => \__('Access Control Rule: User Capabilities', 'graphql-api'), |
|
85
|
|
|
]; |
|
86
|
|
|
return $names[$module] ?? $module; |
|
87
|
|
|
} |
|
88
|
|
|
|
|
89
|
|
|
public function getDescription(string $module): string |
|
90
|
|
|
{ |
|
91
|
|
|
switch ($module) { |
|
92
|
|
|
case self::PUBLIC_PRIVATE_SCHEMA: |
|
93
|
|
|
return \__('Enable to communicate the existence of some field from the schema to certain users only (private mode) or to everyone (public mode). If disabled, fields are always available to everyone (public mode)', 'graphql-api'); |
|
94
|
|
|
case self::ACCESS_CONTROL: |
|
95
|
|
|
return \__('Set-up rules to define who can access the different fields and directives from a schema', 'graphql-api'); |
|
96
|
|
|
case self::ACCESS_CONTROL_RULE_DISABLE_ACCESS: |
|
97
|
|
|
return \__('Remove access to the fields and directives', 'graphql-api'); |
|
98
|
|
|
case self::ACCESS_CONTROL_RULE_USER_STATE: |
|
99
|
|
|
return \__('Allow or reject access to the fields and directives based on the user being logged-in or not', 'graphql-api'); |
|
100
|
|
|
case self::ACCESS_CONTROL_RULE_USER_ROLES: |
|
101
|
|
|
return \__('Allow or reject access to the fields and directives based on the user having a certain role', 'graphql-api'); |
|
102
|
|
|
case self::ACCESS_CONTROL_RULE_USER_CAPABILITIES: |
|
103
|
|
|
return \__('Allow or reject access to the fields and directives based on the user having a certain capability', 'graphql-api'); |
|
104
|
|
|
} |
|
105
|
|
|
return parent::getDescription($module); |
|
106
|
|
|
} |
|
107
|
|
|
|
|
108
|
|
|
/** |
|
109
|
|
|
* Does the module have HTML Documentation? |
|
110
|
|
|
* |
|
111
|
|
|
* @param string $module |
|
112
|
|
|
* @return bool |
|
113
|
|
|
*/ |
|
114
|
|
|
public function hasDocumentation(string $module): bool |
|
115
|
|
|
{ |
|
116
|
|
|
switch ($module) { |
|
117
|
|
|
case self::ACCESS_CONTROL_RULE_DISABLE_ACCESS: |
|
118
|
|
|
case self::ACCESS_CONTROL_RULE_USER_STATE: |
|
119
|
|
|
case self::ACCESS_CONTROL_RULE_USER_ROLES: |
|
120
|
|
|
case self::ACCESS_CONTROL_RULE_USER_CAPABILITIES: |
|
121
|
|
|
return false; |
|
122
|
|
|
} |
|
123
|
|
|
return $this->upstreamHasDocumentation($module); |
|
124
|
|
|
} |
|
125
|
|
|
|
|
126
|
|
|
/** |
|
127
|
|
|
* Default value for an option set by the module |
|
128
|
|
|
* |
|
129
|
|
|
* @param string $module |
|
130
|
|
|
* @param string $option |
|
131
|
|
|
* @return mixed Anything the setting might be: an array|string|bool|int|null |
|
132
|
|
|
*/ |
|
133
|
|
|
public function getSettingsDefaultValue(string $module, string $option) |
|
134
|
|
|
{ |
|
135
|
|
|
$defaultValues = [ |
|
136
|
|
|
self::PUBLIC_PRIVATE_SCHEMA => [ |
|
137
|
|
|
self::OPTION_MODE => SchemaModes::PUBLIC_SCHEMA_MODE, |
|
138
|
|
|
self::OPTION_ENABLE_GRANULAR => true, |
|
139
|
|
|
], |
|
140
|
|
|
]; |
|
141
|
|
|
return $defaultValues[$module][$option]; |
|
142
|
|
|
} |
|
143
|
|
|
|
|
144
|
|
|
/** |
|
145
|
|
|
* Array with the inputs to show as settings for the module |
|
146
|
|
|
* |
|
147
|
|
|
* @param string $module |
|
148
|
|
|
* @return array |
|
149
|
|
|
*/ |
|
150
|
|
|
public function getSettings(string $module): array |
|
151
|
|
|
{ |
|
152
|
|
|
$moduleSettings = parent::getSettings($module); |
|
153
|
|
|
$moduleRegistry = ModuleRegistryFacade::getInstance(); |
|
154
|
|
|
// Do the if one by one, so that the SELECT do not get evaluated unless needed |
|
155
|
|
|
if ($module == self::PUBLIC_PRIVATE_SCHEMA) { |
|
156
|
|
|
$whereModules = [ |
|
157
|
|
|
FunctionalityModuleResolver::SCHEMA_CONFIGURATION, |
|
158
|
|
|
self::ACCESS_CONTROL, |
|
159
|
|
|
]; |
|
160
|
|
|
$whereModuleNames = array_map( |
|
161
|
|
|
function ($whereModule) use ($moduleRegistry) { |
|
162
|
|
|
return '▹ ' . $moduleRegistry->getModuleResolver($whereModule)->getName($whereModule); |
|
163
|
|
|
}, |
|
164
|
|
|
$whereModules |
|
165
|
|
|
); |
|
166
|
|
|
$option = self::OPTION_MODE; |
|
167
|
|
|
$moduleSettings[] = [ |
|
168
|
|
|
Properties::INPUT => $option, |
|
169
|
|
|
Properties::NAME => $this->getSettingOptionName( |
|
170
|
|
|
$module, |
|
171
|
|
|
$option |
|
172
|
|
|
), |
|
173
|
|
|
Properties::TITLE => \__('Default visibility', 'graphql-api'), |
|
174
|
|
|
Properties::DESCRIPTION => sprintf( |
|
175
|
|
|
\__('Visibility to use for fields and directives in the schema when option <code>"%s"</code> is selected (in %s)', 'graphql-api'), |
|
176
|
|
|
ComponentConfiguration::getSettingsValueLabel(), |
|
177
|
|
|
implode( |
|
178
|
|
|
\__(', ', 'graphql-api'), |
|
179
|
|
|
$whereModuleNames |
|
180
|
|
|
) |
|
181
|
|
|
), |
|
182
|
|
|
Properties::TYPE => Properties::TYPE_STRING, |
|
183
|
|
|
Properties::POSSIBLE_VALUES => [ |
|
184
|
|
|
SchemaModes::PUBLIC_SCHEMA_MODE => \__('Public', 'graphql-api'), |
|
185
|
|
|
SchemaModes::PRIVATE_SCHEMA_MODE => \__('Private', 'graphql-api'), |
|
186
|
|
|
], |
|
187
|
|
|
]; |
|
188
|
|
|
$option = self::OPTION_ENABLE_GRANULAR; |
|
189
|
|
|
$moduleSettings[] = [ |
|
190
|
|
|
Properties::INPUT => $option, |
|
191
|
|
|
Properties::NAME => $this->getSettingOptionName( |
|
192
|
|
|
$module, |
|
193
|
|
|
$option |
|
194
|
|
|
), |
|
195
|
|
|
Properties::TITLE => \__('Enable granular control?', 'graphql-api'), |
|
196
|
|
|
Properties::DESCRIPTION => \__('Enable to select the visibility for a set of fields/directives when editing the Access Control List', 'graphql-api'), |
|
197
|
|
|
Properties::TYPE => Properties::TYPE_BOOL, |
|
198
|
|
|
]; |
|
199
|
|
|
} |
|
200
|
|
|
return $moduleSettings; |
|
201
|
|
|
} |
|
202
|
|
|
} |
|
203
|
|
|
|