Skip to content

Commit fe0dad1

Browse files
author
Christopher Stebe
committed
updated access trait, added option to use single access checks and define own column names, WIP
1 parent 166657b commit fe0dad1

File tree

2 files changed

+120
-75
lines changed

2 files changed

+120
-75
lines changed

README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ Traits
109109

110110
### [dmstr\db\traits\ActiveRecordAccessTrait](https://github.com/dmstr/yii2-db/blob/master/db/traits/ActiveRecordAccessTrait.php)
111111

112+
**Option 1:**
113+
112114
How to equip your active record model with access control
113115

114116
- Use update migration in `db/migrations/m160609_090908_add_access_columns`
@@ -130,6 +132,39 @@ This migrations adds the available access check columns to your database table(s
130132
- *(update your cruds)*
131133

132134

135+
136+
**Option 2:**
137+
138+
Simply override this method in our AR model and set the access fields you have/want to the field names you have/want!
139+
140+
*Default:*
141+
```
142+
public static function accessColumnAttributes()
143+
{
144+
return [
145+
'owner' => 'access_owner',
146+
'read' => 'access_read',
147+
'update' => 'access_update',
148+
'delete' => 'access_delete',
149+
'domain' => 'access_domain',
150+
];
151+
}
152+
```
153+
154+
*Customize:*
155+
```
156+
public static function accessColumnAttributes()
157+
{
158+
return [
159+
'owner' => 'user_id', // the column name with owner permissions
160+
'read' => 'read_permission', // the column name with read permissions
161+
'update' => false, // will do no access checks for update
162+
'delete' => false, // will do no access checks for delete
163+
'domain' => 'language', // the column name with the access domain permission
164+
];
165+
}
166+
```
167+
133168
**:secret: Congrats, you are now ready to manage specific access checks on your active records!**
134169

135170
:bulb: Access options:

db/traits/ActiveRecordAccessTrait.php

Lines changed: 85 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,6 @@
1414
/**
1515
* Trait ActiveRecordAccessTrait
1616
*
17-
* @property integer $access_owner
18-
* @property string $access_read
19-
* @property string $access_update
20-
* @property string $access_delete
21-
* @property string $access_domain
22-
*
23-
*
24-
*
2517
* @package dmstr\db\traits
2618
* @author Christopher Stebe <[email protected]>
2719
*/
@@ -46,15 +38,18 @@ trait ActiveRecordAccessTrait
4638
private static $_public = '*';
4739

4840
/**
49-
* @var array with access field names
41+
* @return array with access field names
5042
*/
51-
private static $_availableAccessColumns = [
52-
'access_owner',
53-
'access_read',
54-
'access_update',
55-
'access_delete',
56-
'access_domain',
57-
];
43+
public static function accessColumnAttributes()
44+
{
45+
return [
46+
'owner' => 'access_owner',
47+
'read' => 'access_read',
48+
'update' => 'access_update',
49+
'delete' => 'access_delete',
50+
'domain' => 'access_domain',
51+
];
52+
}
5853

5954
/**
6055
* @inheritdoc
@@ -64,17 +59,28 @@ public static function find()
6459
/** @var $query \yii\db\ActiveQuery */
6560
$query = parent::find();
6661

62+
$accessOwner = self::accessColumnAttributes()['owner'];
63+
$accessRead = self::accessColumnAttributes()['read'];
64+
$accessDomain = self::accessColumnAttributes()['domain'];
65+
6766
if (self::$activeAccessTrait) {
67+
6868
// access owner check
69-
$query->where(['access_owner' => \Yii::$app->user->id]);
69+
if ($accessOwner) {
70+
$query->where([$accessOwner => \Yii::$app->user->id]);
71+
}
7072

7173
// access read check
72-
foreach (array_keys(self::getUsersAuthItems()) as $authItem) {
73-
$query->orWhere('FIND_IN_SET("' . $authItem . '", access_read)');
74+
if ($accessRead) {
75+
foreach (array_keys(self::getUsersAuthItems()) as $authItem) {
76+
$query->orWhere('FIND_IN_SET("' . $authItem . '", ' . $accessRead . ')');
77+
}
7478
}
7579

7680
// access domain check
77-
$query->andWhere(['access_domain' => \Yii::$app->language]);
81+
if ($accessDomain) {
82+
$query->andWhere([$accessDomain => \Yii::$app->language]);
83+
}
7884
}
7985

8086
return $query;
@@ -85,14 +91,57 @@ public static function find()
8591
*/
8692
public function rules()
8793
{
94+
$accessOwner = self::accessColumnAttributes()['owner'];
95+
$accessRead = self::accessColumnAttributes()['read'];
96+
$accessUpdate = self::accessColumnAttributes()['update'];
97+
$accessDelete = self::accessColumnAttributes()['delete'];
98+
$accessDomain = self::accessColumnAttributes()['domain'];
99+
100+
// safe validator
101+
$safe = [];
102+
103+
// string validator
104+
$string = [];
105+
106+
// default validator
107+
$default = [];
108+
109+
// integer validator
110+
$integer = [];
111+
112+
// add used attributes to validation rules
113+
if ($accessOwner) {
114+
array_push($safe, $accessOwner);
115+
array_push($integer, $accessOwner);
116+
}
117+
if ($accessRead) {
118+
array_push($safe, $accessRead);
119+
array_push($string, $accessRead);
120+
array_push($default, $accessRead);
121+
}
122+
if ($accessUpdate) {
123+
array_push($safe, $accessUpdate);
124+
array_push($string, $accessUpdate);
125+
array_push($default, $accessUpdate);
126+
}
127+
if ($accessDelete) {
128+
array_push($safe, $accessDelete);
129+
array_push($string, $accessDelete);
130+
array_push($default, $accessDelete);
131+
}
132+
if ($accessDomain) {
133+
array_push($safe, $accessDomain);
134+
array_push($string, $accessDomain);
135+
array_push($default, $accessDomain);
136+
}
137+
88138
return ArrayHelper::merge(
89139
parent::rules(),
90140
[
91-
[['access_owner', 'access_domain', 'access_read', 'access_update', 'access_delete'], 'safe'],
92-
[['access_domain', 'access_read', 'access_update', 'access_delete'], 'string', 'max' => 255],
93-
[['access_domain', 'access_read', 'access_update', 'access_delete'], 'default', 'value' => null],
94-
[['access_domain'], 'default', 'value' => \Yii::$app->language],
95-
[['access_owner'], 'integer'],
141+
[$safe, 'safe'],
142+
[$string, 'string', 'max' => 255],
143+
[$default, 'default', 'value' => null],
144+
[$integer, 'integer']
96145
]
97146
);
98147
}
@@ -111,10 +160,11 @@ public function beforeSave($insert)
111160
}
112161
return true;
113162
}
114-
115-
if (self::$activeAccessTrait) {
116-
if (!$this->hasPermission('access_update')) {
163+
$accessUpdate = self::accessColumnAttributes()['update'];
164+
if (self::$activeAccessTrait && $accessUpdate) {
165+
if (!$this->hasPermission($accessUpdate)) {
117166
$this->addAccessError('update');
167+
return false;
118168
} else {
119169
return true;
120170
}
@@ -130,9 +180,11 @@ public function beforeDelete()
130180
{
131181
parent::beforeDelete();
132182

133-
if (self::$activeAccessTrait) {
134-
if (!$this->hasPermission('access_delete')) {
183+
$accessDelete = self::accessColumnAttributes()['delete'];
184+
if (self::$activeAccessTrait && $accessDelete) {
185+
if (!$this->hasPermission($accessDelete)) {
135186
$this->addAccessError('delete');
187+
return false;
136188
} else {
137189
return true;
138190
}
@@ -210,47 +262,6 @@ public static function getUsersAuthItems()
210262
return $publicAuthItem;
211263
}
212264

213-
/**
214-
* For use with yii2-giiant OptsProvider
215-
* @return array available access domains
216-
*/
217-
public static function optsAccessDomain()
218-
{
219-
$languages = self::allAccess();
220-
foreach (\Yii::$app->urlManager->languages as $language) {
221-
$languages[$language] = $language;
222-
}
223-
224-
return $languages;
225-
}
226-
227-
/**
228-
* For use with yii2-giiant OptsProvider
229-
* @return array available read accesses
230-
*/
231-
public static function optsAccessRead()
232-
{
233-
return self::getUsersAuthItems();
234-
}
235-
236-
/**
237-
* For use with yii2-giiant OptsProvider
238-
* @return array available update accesses
239-
*/
240-
public static function optsAccessUpdate()
241-
{
242-
return self::getUsersAuthItems();
243-
}
244-
245-
/**
246-
* For use with yii2-giiant OptsProvider
247-
* @return array available delete accesses
248-
*/
249-
public static function optsAccessDelete()
250-
{
251-
return self::getUsersAuthItems();
252-
}
253-
254265
/**
255266
* Decode access column by action from csv to array
256267
*
@@ -261,7 +272,7 @@ public static function optsAccessDelete()
261272
*/
262273
public function authItemArrayToString($action, array $authItems)
263274
{
264-
if (!in_array($action, self::$_availableAccessColumns)) {
275+
if (!in_array($action, self::accessColumnAttributes())) {
265276
return null;
266277
}
267278

@@ -276,7 +287,7 @@ public function authItemArrayToString($action, array $authItems)
276287
*/
277288
public function authItemStringToArray($action)
278289
{
279-
if (!in_array($action, self::$_availableAccessColumns)) {
290+
if (!in_array($action, self::accessColumnAttributes())) {
280291
return null;
281292
}
282293
$arr = explode(',', $this->$action);
@@ -292,7 +303,7 @@ public function authItemStringToArray($action)
292303
*/
293304
public function hasPermission($action = null)
294305
{
295-
if ($action === null && !in_array($action, self::$_availableAccessColumns)) {
306+
if ($action === null && !in_array($action, self::accessColumnAttributes())) {
296307
return false;
297308
}
298309
// owner check
@@ -330,6 +341,5 @@ private function addAccessError($action)
330341
} else {
331342
\Yii::error($msg, __METHOD__);
332343
}
333-
return false;
334344
}
335345
}

0 commit comments

Comments
 (0)