1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
|
<?php
/**
* ResourceTemporaryPermission.php
* Contains the ResourceTemporaryPermission class
*
* The ResourceTemporaryPermission class represents temporary permissions
* granted to a user for a resource.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* @author Moritz Strohm <strohm@data-quest.de>
* @copyright 2018-2019
* @license http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
* @category Stud.IP
* @package resources
* @since 4.5
*
* @property int $id database column
* @property string $resource_id database column
* @property string $user_id database column
* @property int $begin database column
* @property int $end database column
* @property string $perms database column
* @property int $mkdate database column
* @property int $chdate database column
* @property Resource $resource belongs_to Resource
* @property User $user belongs_to User
*/
class ResourceTemporaryPermission extends SimpleORMap implements PrivacyObject
{
protected static function configure($config = [])
{
$config['db_table'] = 'resource_temporary_permissions';
$config['belongs_to']['resource'] = [
'class_name' => Resource::class,
'foreign_key' => 'resource_id',
'assoc_func' => 'find'
];
$config['belongs_to']['user'] = [
'class_name' => User::class,
'foreign_key' => 'user_id',
'assoc_func' => 'find'
];
$config['registered_callbacks']['before_store'][] = 'cbLogChanges';
$config['registered_callbacks']['before_delete'][] = 'cbLogDeletion';
$config['registered_callbacks']['after_store'][] = 'cbUpdateCache';
$config['registered_callbacks']['before_delete'][] = 'cbUpdateCache';
parent::configure($config);
}
/**
* @inheritDoc
*/
public static function exportUserData(StoredUserData $storage)
{
$user = User::find($storage->user_id);
$permissions = self::findBySql(
'user_id = :user_id ORDER BY mkdate',
[
'user_id' => $storage->user_id
]
);
$rows = [];
foreach ($permissions as $permission) {
$rows[] = $permission->toRawArray();
}
$storage->addTabularData(
_('Temporäre Berechtigungen an Ressourcen'),
self::$config['db_table'],
$rows,
$user
);
}
/**
* Returns the current permission a user has for a resource.
*
* @param User $user The user whose permission shall be retrieved.
* @param string $resource_id The resource where the user's permission
* shall be retrieved.
*
* @return string The permission level as string or an empty string, if no
* temporary permission exists for the specified user on the
* specified resource.
*/
public static function getCurrentTemporaryPermissions(User $user, string $resource_id)
{
$perm = self::findOneBySql(
'resource_id = :resource_id
AND
user_id = :user_id',
[
'resource_id' => $resource_id,
'user_id' => $user->id
]
);
if ($perm) {
return $perm->perm;
}
return '';
}
public static function userHasPermissionInTimeRange(
User $user,
string $resource_id,
DateTime $begin,
DateTime $end
)
{
//Query explaination: We want exactly one permission object
//for the specified user and the resource.
//The permission must exist during the whole specified time range
//and therefore the begin and end of the permission must either
//meet the time range exactly or it must start earlier and end
//later than the time range. The permission level is checked afterwards
//if a permission object can be found.
$perm = self::findOneBySql(
'user_id = :user_id
AND
resource_id = :resource_id
AND
(begin <= :begin AND end >= :end)',
[
'user_id' => $user->id,
'resource_id' => $resource_id,
'begin' => $begin->getTimestamp(),
'end' => $end->getTimestamp()
]
);
if (!$perm) {
//If no permission object can be found the user obviously
//doesn't have the requested permissions.
return false;
}
return ResourceManager::comparePermissionLevels($perm->perm, $perm) >= 0;
}
/**
* This is a callback method to create an entry in the Stud.IP log
* when a ResourceTemporaryPermission object is stored.
*/
public function cbLogChanges()
{
if ($this->isNew()) {
//Insert
if ($this->resource_id == 'global') {
//Global permissions
StudipLog::log(
'RES_PERM_CHANGE',
$this->resource_id,
$this->user_id,
sprintf(
_('Globale temporäre Berechtigungen für %1$s (Rechtestufe %2$s) hinzugefügt.'),
$this->user->username,
$this->perms
)
);
} elseif ($this->resource_id) {
//Resource-specific permissions
StudipLog::log(
'RES_PERM_CHANGE',
$this->resource_id,
$this->user_id,
sprintf(
_('%1$s: Hinzufügen von temporären Berechtigungen für %2$s (Rechtestufe %3$s).'),
$this->resource->getDerivedClassInstance()->getFullName(),
$this->user->username,
$this->perms
)
);
} else {
throw new ResourcePermissionException(
_('Berechtigungen müssen mit bestimmten Ressourcen verknüpft sein, bevor sie gespeichert werden!')
);
}
} else {
//Update?
if ($this->content_db['perms'] != $this->perms) {
//Update!
if ($this->resource_id == 'global') {
StudipLog::log(
'RES_PERM_CHANGE',
$this->resource_id,
$this->user_id,
sprintf(
_('Globale temporäre Berechtigungen für %1$s von %2$s auf %3$s geändert.'),
$this->user->username,
$this->content_db['perms'],
$this->perms
)
);
} else {
StudipLog::log(
'RES_PERM_CHANGE',
$this->resource_id,
$this->user_id,
sprintf(
_('%1$s: Änderung der temporären Berechtigungen für %2$s von %3$s auf %4$s.'),
$this->resource->getFullName(),
$this->user->username,
$this->content_db['perms'],
$this->perms
)
);
}
}
}
}
/**
* This is a callback method to create an entry in the Stud.IP log
* when a ResourceTemporaryPermission object is deleted.
*/
public function cbLogDeletion()
{
if ($this->resource_id == 'global') {
StudipLog::log(
'RES_PERM_CHANGE',
$this->resource_id,
$this->user_id,
sprintf(
_('Globale temporäre Berechtigungen für %1$s (Rechtestufe %2$s) gelöscht.'),
$this->user->username,
$this->perms
)
);
} else {
StudipLog::log(
'RES_PERM_CHANGE',
$this->resource_id,
$this->user_id,
sprintf(
_('%1$s: Löschen der temporären Berechtigungen für %2$s (Rechtestufe %3$s).'),
$this->resource->getFullName(),
$this->user->username,
$this->perms
)
);
}
}
/**
* This will clear the cache for RoomManager::userHasRooms()
*/
public function cbUpdateCache(): void
{
RoomManager::clearCacheForUser($this->user);
}
}
|