Subversion Repositories oidplus

Rev

Rev 277 | Rev 289 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 277 Rev 288
Line 18... Line 18...
18
 */
18
 */
19
 
19
 
20
class OIDplusLogger {
20
class OIDplusLogger {
21
 
21
 
22
        private static function split_maskcodes($maskcodes) {
22
        private static function split_maskcodes($maskcodes) {
-
 
23
                // This function splits a mask code containing multiple components
-
 
24
                // (delimited by '+' or '/') in single components
-
 
25
                // It takes care that '+' and '/' inside brackets won't be used to split the codes
-
 
26
                // Also, brackets can be escaped.
-
 
27
                // The severity block (optional, must be standing in front of a component)
-
 
28
                // is handled too. Inside the severity block, you may only use '/' to split components.
-
 
29
                // The severity block will be implicitly repeated from the previous components if a component
-
 
30
                // does not feature one.
-
 
31
                //
-
 
32
                // "[S]AAA(BBB)+CCC(DDD)"   ==> array(
-
 
33
                //                                 array(array("S"),"AAA(BBB)"),
-
 
34
                //                                 array(array("S"),"CCC(DDD)")
-
 
35
                //                              )
-
 
36
                // "[S]AAA(B+BB)+CCC(DDD)"  ==> array(
-
 
37
                //                                 array(array("S"),"AAA(B+BB)"),
-
 
38
                //                                 array(array("S"),"CCC(DDD)")
-
 
39
                //                              )
-
 
40
                // "[S]AAA(B\)BB)+CCC(DDD)" ==> array(
-
 
41
                //                                 array(array("S"),"AAA(B\)BB)"),
-
 
42
                //                                 array(array("S"),"CCC(DDD)")
-
 
43
                //                              )
-
 
44
       
23
                $out = array();
45
                $out = array();
-
 
46
                $sevs = array(); // Note: The severity block will repeat for the next components if not changed explicitly
24
 
47
               
25
                $code = '';
48
                $code = '';
-
 
49
                $sev = '';
26
                $bracket_level = 0;
50
                $bracket_level = 0;
-
 
51
                $is_escaping = false;
-
 
52
                $inside_severity_block = false;
27
                for ($i=0; $i<strlen($maskcodes); $i++) {
53
                for ($i=0; $i<strlen($maskcodes); $i++) {
28
                        $char = $maskcodes[$i];
54
                        $char = $maskcodes[$i];
-
 
55
                       
-
 
56
                        if ($inside_severity_block) {
-
 
57
                                // Severity block (optional)
-
 
58
                                // e.g.  [?WARN/!OK] ==> $sevs = array("?WARN", "!OK")
-
 
59
                                if ($char == '\\') {
-
 
60
                                        if ($is_escaping) {
-
 
61
                                                $is_escaping = false;
-
 
62
                                                $sev .= $char;
-
 
63
                                        } else {
-
 
64
                                                $is_escaping = true;
-
 
65
                                        }
-
 
66
                                }
-
 
67
                                else if ($char == '[') {
-
 
68
                                        if ($is_escaping) {
-
 
69
                                                $is_escaping = false;
-
 
70
                                        } else {
-
 
71
                                                $bracket_level++;
-
 
72
                                        }
-
 
73
                                        $sev .= $char;
-
 
74
                                }
-
 
75
                                else if ($char == ']') {
-
 
76
                                        if ($is_escaping) {
-
 
77
                                                $is_escaping = false;
-
 
78
                                                $sev .= $char;
-
 
79
                                        } else {
-
 
80
                                                $bracket_level--;
-
 
81
                                                if ($bracket_level < 0) return false;
-
 
82
                                                if ($bracket_level == 0) {
-
 
83
                                                        $inside_severity_block = false;
-
 
84
                                                        if ($sev != '') $sevs[] = $sev;
-
 
85
                                                        $sev = '';
-
 
86
                                                } else {
-
 
87
                                                        $sev .= $char;
-
 
88
                                                }
-
 
89
                                        }
-
 
90
                                }
29
                        if ($char == '(') $bracket_level++;
91
                                else if ((($char == '/')) && ($bracket_level == 1)) {
-
 
92
                                        if ($is_escaping) {
-
 
93
                                                $is_escaping = false;
-
 
94
                                                $sev .= $char;
-
 
95
                                        } else {
-
 
96
                                                if ($sev != '') $sevs[] = $sev;
-
 
97
                                                $sev = '';
-
 
98
                                        }
-
 
99
                                } else {
-
 
100
                                        if ($is_escaping) {
-
 
101
                                                // This would actually be an error, because we cannot escape this
-
 
102
                                                $is_escaping = false;
-
 
103
                                                $sev .= '\\' . $char;
-
 
104
                                        } else {
-
 
105
                                                $sev .= $char;
-
 
106
                                        }
-
 
107
                                }
-
 
108
                        } else {
-
 
109
                                // Normal data (after the severity block)
-
 
110
                                if (($char == '[') && ($code == '')) {
-
 
111
                                        $inside_severity_block = true;
-
 
112
                                        $bracket_level++;
-
 
113
                                        $sevs = array();
-
 
114
                                }
-
 
115
                                else if ($char == '\\') {
-
 
116
                                        if ($is_escaping) {
-
 
117
                                                $is_escaping = false;
-
 
118
                                                $code .= $char;
-
 
119
                                        } else {
-
 
120
                                                $is_escaping = true;
-
 
121
                                        }
-
 
122
                                }
-
 
123
                                else if ($char == '(') {
-
 
124
                                        if ($is_escaping) {
-
 
125
                                                $is_escaping = false;
-
 
126
                                        } else {
-
 
127
                                                $bracket_level++;
-
 
128
                                        }
-
 
129
                                        $code .= $char;
-
 
130
                                }
30
                        if ($char == ')') {
131
                                else if ($char == ')') {
-
 
132
                                        if ($is_escaping) {
-
 
133
                                                $is_escaping = false;
-
 
134
                                        } else {
31
                                $bracket_level--;
135
                                                $bracket_level--;
32
                                if ($bracket_level < 0) return false;
136
                                                if ($bracket_level < 0) return false;
33
                        }
137
                                        }
-
 
138
                                        $code .= $char;
-
 
139
                                }
34
                        if ((($char == '+') || ($char == '/')) && ($bracket_level == 0)) {
140
                                else if ((($char == '+') || ($char == '/')) && ($bracket_level == 0)) {
-
 
141
                                        if ($is_escaping) {
-
 
142
                                                $is_escaping = false;
35
                                $out[] = $code;
143
                                                $code .= $char;
-
 
144
                                        } else {
-
 
145
                                                if ($code != '') $out[] = array($sevs,$code);
36
                                $code = '';
146
                                                $code = '';
-
 
147
                                        }
-
 
148
                                } else {
-
 
149
                                        if ($is_escaping) {
-
 
150
                                                // This would actually be an error, because we cannot escape this
-
 
151
                                                $is_escaping = false;
-
 
152
                                                $code .= '\\' . $char;
37
                        } else {
153
                                        } else {
38
                                $code .= $char;
154
                                                $code .= $char;
39
                        }
155
                                        }
40
                }
156
                                }
-
 
157
                        }
-
 
158
                }
41
                if ($code != '') $out[] = $code;
159
                if ($code != '') $out[] = array($sevs,$code);
-
 
160
                if ($inside_severity_block) return false;
42
 
161
 
43
                return $out;
162
                return $out;
44
        }
163
        }
45
 
164
 
46
        public static function log($maskcodes, $event) {
165
        public static function log($maskcodes, $event) {
-
 
166
                // What is a mask code?
-
 
167
                // A mask code gives information about the log event:
-
 
168
                // 1. The severity (info, warning, error)
-
 
169
                // 2. In which logbook(s) the event shall be placed
-
 
170
                // Example:
-
 
171
                // The event would be:
-
 
172
                // "Person 'X' moves from house 'A' to house 'B'"
-
 
173
                // This event would affect the person X and the two houses,
-
 
174
                // so, instead of logging into 3 logbooks separately,
-
 
175
                // you would create a mask code that tells the system
-
 
176
                // to put the message into the logbooks of person X,
-
 
177
                // house A and house B.
47
 
178
 
48
                $users = array();
179
                $users = array();
49
                $objects = array();
180
                $objects = array();
50
 
181
 
-
 
182
                // A mask code with multiple components is split into single codes
-
 
183
                // using '+' or '/', e.g. "OID(x)+RA(x)" would be split to "OID(x)" and "RA(x)"
-
 
184
                // which would result in the message being placed in the logbook of OID x,
-
 
185
                // and the logbook of the RA owning OID x.
51
                $maskcodes_ary = self::split_maskcodes($maskcodes);
186
                $maskcodes_ary = self::split_maskcodes($maskcodes);
52
                if ($maskcodes_ary === false) {
187
                if ($maskcodes_ary === false) {
53
                        throw new OIDplusException("Invalid maskcode '$maskcodes'");
188
                        throw new OIDplusException("Invalid maskcode '$maskcodes' (failed to split)");
54
                }
189
                }
55
                foreach ($maskcodes_ary as $maskcode) {
190
                foreach ($maskcodes_ary as list($sevs,$maskcode)) {
-
 
191
                        // At the beginning of each mask code, you can define a severity.
-
 
192
                        // If you have a mask code with multiple components, you don't have to place the
-
 
193
                        // severity for each component. You can just leave it at the beginning.
-
 
194
                        // e.g. "[WARN]OID(x)+RA(x)" is equal to "[WARN]OID(x)+[WARN]RA(x)"
-
 
195
                        // You can also put different severities for the components:
-
 
196
                        // e.g. "[INFO]OID(x)+[WARN]RA(x)" would be a info for the OID, but a warning for the RA.
-
 
197
                        // If you want to make the severity dependent on wheather the user is logged in or not,
-
 
198
                        // prepend "?" or "!" and use '/' as delimiter
-
 
199
                        // Example: "[?WARN/!OK]RA(x)" means: If RA is not logged in, it is a warning; if it is logged in, it is an success
-
 
200
                        $severity = 0; // default severity = none
-
 
201
                        foreach ($sevs as $sev) {
-
 
202
                                switch (strtoupper($sev)) {
-
 
203
                                        // [OK]   = Success
-
 
204
                                        //          Numeric value: 1
-
 
205
                                        //          Rule of thumb: YOU have done something and it was successful
-
 
206
                                        case '?OK':
-
 
207
                                                $severity_online = 1;
-
 
208
                                                break;
-
 
209
                                        case '!OK':
-
 
210
                                        case  'OK':
-
 
211
                                                $severity = 1;
-
 
212
                                                break;
-
 
213
                                        // [INFO] = Informational
-
 
214
                                        //          Numeric value: 2
-
 
215
                                        //          Rule of thumb: Someone else has done something (that affects you) and it was successful
-
 
216
                                        case '?INFO':
-
 
217
                                                $severity_online = 2;
-
 
218
                                                break;
-
 
219
                                        case '!INFO':
-
 
220
                                        case  'INFO':
-
 
221
                                                $severity = 2;
-
 
222
                                                break;
-
 
223
                                        // [WARN] = Warning
-
 
224
                                        //          Numeric value: 3
-
 
225
                                        //          Rule of thumb: Something happened (probably someone did something) and it affects you
-
 
226
                                        case '?WARN':
-
 
227
                                                $severity_online = 3;
-
 
228
                                                break;
-
 
229
                                        case '!WARN':
-
 
230
                                        case  'WARN':
-
 
231
                                                $severity = 3;
-
 
232
                                                break;
-
 
233
                                        // [ERR]  = Error
-
 
234
                                        //          Numeric value: 4
-
 
235
                                        //          Rule of thumb: Something failed (probably someone did something) and it affects you
-
 
236
                                        case '?ERR':
-
 
237
                                                $severity_online = 4;
-
 
238
                                                break;
-
 
239
                                        case '!ERR':
-
 
240
                                        case  'ERR':
-
 
241
                                                $severity = 4;
-
 
242
                                                break;
-
 
243
                                        // [CRIT] = Critical
-
 
244
                                        //          Numeric value: 5
-
 
245
                                        //          Rule of thumb: Something happened (probably someone did something) which is not an error,
-
 
246
                                        //          but some critical situation (e.g. hardware failure), and it affects you
-
 
247
                                        case '?CRIT':
-
 
248
                                                $severity_online = 5;
-
 
249
                                                break;
-
 
250
                                        case '!CRIT':
-
 
251
                                        case  'CRIT':
-
 
252
                                                $severity = 5;
-
 
253
                                                break;
-
 
254
                                        default:
-
 
255
                                                throw new OIDplusException("Invalid maskcode '$maskcodes' (Unknown severity '$sev')");
-
 
256
                                }
-
 
257
                        }
-
 
258
                       
56
                        // OID(x)       Save log entry into the logbook of: Object "x"
259
                        // OID(x)       Save log entry into the logbook of: Object "x"
57
                        if (preg_match('@^OID\((.+)\)$@ismU', $maskcode, $m)) {
260
                        if (preg_match('@^OID\((.+)\)$@ismU', $maskcode, $m)) {
58
                                $object_id = $m[1];
261
                                $object_id = $m[1];
59
                                $objects[] = $object_id;
262
                                $objects[] = array($severity, $object_id);
60
                                if ($object_id == '') throw new OIDplusException("OID logger mask requires OID");
263
                                if ($object_id == '') throw new OIDplusException("OID logger mask requires OID");
61
                        }
264
                        }
62
 
265
 
-
 
266
                        // SUPOID(x)    Save log entry into the logbook of: Parent of object "x"
-
 
267
                        else if (preg_match('@^SUPOID\((.+)\)$@ismU', $maskcode, $m)) {
-
 
268
                                $object_id         = $m[1];
-
 
269
                                if ($object_id == '') throw new OIDplusException("SUPOID logger mask requires OID");
-
 
270
                                $obj = OIDplusObject::parse($object_id);
-
 
271
                                if ($obj) {
-
 
272
                                        $parent = $obj->getParent()->nodeId();
-
 
273
                                        $objects[] = array($severity, $parent);
-
 
274
                                } else {
-
 
275
                                        throw new OIDplusException("SUPOID logger mask: Invalid object '$object_id'");
-
 
276
                                }
-
 
277
                        }
-
 
278
 
63
                        // OIDRA(x)?    Save log entry into the logbook of: Logged in RA of object "x"
279
                        // OIDRA(x)?    Save log entry into the logbook of: Logged in RA of object "x"
64
                        // Replace ? by ! if the entity does not need to be logged in
280
                        // Remove or replace "?" by "!" if the entity does not need to be logged in
65
                        else if (preg_match('@^OIDRA\((.+)\)([\?\!])$@ismU', $maskcode, $m)) {
281
                        else if (preg_match('@^OIDRA\((.+)\)([\?\!])$@ismU', $maskcode, $m)) {
66
                                $object_id         = $m[1];
282
                                $object_id         = $m[1];
67
                                $ra_need_login     = $m[2] == '?';
283
                                $ra_need_login     = $m[2] == '?';
68
                                if ($object_id == '') throw new OIDplusException("OIDRA logger mask requires OID");
284
                                if ($object_id == '') throw new OIDplusException("OIDRA logger mask requires OID");
69
                                $obj = OIDplusObject::parse($object_id);
285
                                $obj = OIDplusObject::parse($object_id);
70
                                if ($obj) {
286
                                if ($obj) {
71
                                        if ($ra_need_login) {
287
                                        if ($ra_need_login) {
72
                                                foreach (OIDplus::authUtils()->loggedInRaList() as $ra) {
288
                                                foreach (OIDplus::authUtils()->loggedInRaList() as $ra) {
73
                                                        if ($obj->userHasWriteRights($ra)) $users[] = $ra->raEmail();
289
                                                        if ($obj->userHasWriteRights($ra)) $users[] = array($severity_online, $ra->raEmail());
74
                                                }
290
                                                }
75
                                        } else {
291
                                        } else {
76
                                                // $users[] = $obj->getRa()->raEmail();
292
                                                // $users[] = array($severity, $obj->getRa()->raEmail());
77
                                                foreach (OIDplusRA::getAllRAs() as $ra) {
293
                                                foreach (OIDplusRA::getAllRAs() as $ra) {
78
                                                        if ($obj->userHasWriteRights($ra)) $users[] = $ra->raEmail();
294
                                                        if ($obj->userHasWriteRights($ra)) $users[] = array($severity, $ra->raEmail());
79
                                                }
295
                                                }
80
                                        }
296
                                        }
-
 
297
                                } else {
-
 
298
                                        throw new OIDplusException("OIDRA logger mask: Invalid object '$object_id'");
81
                                }
299
                                }
82
                        }
300
                        }
83
 
301
 
84
                        // SUPOIDRA(x)? Save log entry into the logbook of: Logged in RA that owns the superior object of "x"
302
                        // SUPOIDRA(x)? Save log entry into the logbook of: Logged in RA that owns the superior object of "x"
85
                        // Replace ? by ! if the entity does not need to be logged in
303
                        // Remove or replace "?" by "!" if the entity does not need to be logged in
86
                        else if (preg_match('@^SUPOIDRA\((.+)\)([\?\!])$@ismU', $maskcode, $m)) {
304
                        else if (preg_match('@^SUPOIDRA\((.+)\)([\?\!])$@ismU', $maskcode, $m)) {
87
                                $object_id         = $m[1];
305
                                $object_id         = $m[1];
88
                                $ra_need_login     = $m[2] == '?';
306
                                $ra_need_login     = $m[2] == '?';
89
                                if ($object_id == '') throw new OIDplusException("SUPOIDRA logger mask requires OID");
307
                                if ($object_id == '') throw new OIDplusException("SUPOIDRA logger mask requires OID");
90
                                $obj = OIDplusObject::parse($object_id);
308
                                $obj = OIDplusObject::parse($object_id);
91
                                if ($obj) {
309
                                if ($obj) {
92
                                        if ($ra_need_login) {
310
                                        if ($ra_need_login) {
93
                                                foreach (OIDplus::authUtils()->loggedInRaList() as $ra) {
311
                                                foreach (OIDplus::authUtils()->loggedInRaList() as $ra) {
94
                                                        if ($obj->userHasParentalWriteRights($ra)) $users[] = $ra->raEmail();
312
                                                        if ($obj->userHasParentalWriteRights($ra)) $users[] = array($severity_online, $ra->raEmail());
95
                                                }
313
                                                }
96
                                        } else {
314
                                        } else {
97
                                                // $users[] = $obj->getParent()->getRa()->raEmail();
315
                                                // $users[] = array($severity, $obj->getParent()->getRa()->raEmail());
98
                                                foreach (OIDplusRA::getAllRAs() as $ra) {
316
                                                foreach (OIDplusRA::getAllRAs() as $ra) {
99
                                                        if ($obj->userHasParentalWriteRights($ra)) $users[] = $ra->raEmail();
317
                                                        if ($obj->userHasParentalWriteRights($ra)) $users[] = array($severity, $ra->raEmail());
100
                                                }
318
                                                }
101
                                        }
319
                                        }
-
 
320
                                } else {
-
 
321
                                        throw new OIDplusException("SUPOIDRA logger mask: Invalid object '$object_id'");
102
                                }
322
                                }
103
                        }
323
                        }
104
 
324
 
105
                        // RA(x)?       Save log entry into the logbook of: Logged in RA "x"
325
                        // RA(x)?       Save log entry into the logbook of: Logged in RA "x"
106
                        // Replace ? by ! if the entity does not need to be logged in
326
                        // Remove or replace "?" by "!" if the entity does not need to be logged in
107
                        else if (preg_match('@^RA\((.+)\)([\?\!])$@ismU', $maskcode, $m)) {
327
                        else if (preg_match('@^RA\((.*)\)([\?\!])$@ismU', $maskcode, $m)) {
108
                                $ra_email          = $m[1];
328
                                $ra_email          = $m[1];
109
                                $ra_need_login     = $m[2] == '?';
329
                                $ra_need_login     = $m[2] == '?';
-
 
330
                                if (!empty($ra_email)) {
110
                                if ($ra_need_login && OIDplus::authUtils()->isRaLoggedIn($ra_email)) {
331
                                        if ($ra_need_login && OIDplus::authUtils()->isRaLoggedIn($ra_email)) {
111
                                        $users[] = $ra_email;
332
                                                $users[] = array($severity_online, $ra_email);
112
                                } else if (!$ra_need_login) {
333
                                        } else if (!$ra_need_login) {
113
                                        $users[] = $ra_email;
334
                                                $users[] = array($severity, $ra_email);
-
 
335
                                        }
114
                                }
336
                                }
115
                        }
337
                        }
116
 
338
 
117
                        // A?   Save log entry into the logbook of: A logged in admin
339
                        // A?   Save log entry into the logbook of: A logged in admin
118
                        // Replace ? by ! if the entity does not need to be logged in
340
                        // Remove or replace "?" by "!" if the entity does not need to be logged in
119
                        else if (preg_match('@^A([\?\!])$@ismU', $maskcode, $m)) {
341
                        else if (preg_match('@^A([\?\!])$@ismU', $maskcode, $m)) {
120
                                $admin_need_login = $m[1] == '?';
342
                                $admin_need_login = $m[1] == '?';
121
                                if ($admin_need_login && OIDplus::authUtils()->isAdminLoggedIn()) {
343
                                if ($admin_need_login && OIDplus::authUtils()->isAdminLoggedIn()) {
122
                                        $users[] = 'admin';
344
                                        $users[] = array($severity_online, 'admin');
123
                                } else if (!$admin_need_login) {
345
                                } else if (!$admin_need_login) {
124
                                        $users[] = 'admin';
346
                                        $users[] = array($severity, 'admin');
125
                                }
347
                                }
126
                        }
348
                        }
127
 
349
 
128
                        // Unexpected
350
                        // Unexpected
129
                        else {
351
                        else {
130
                                throw new OIDplusException("Unexpected logger mask code '$maskcode'");
352
                                throw new OIDplusException("Unexpected logger component '$maskcode' in mask code '$maskcodes'");
131
                        }
353
                        }
132
                }
354
                }
133
 
355
 
134
                // Now write the log message
356
                // Now write the log message
135
 
357
 
Line 139... Line 361...
139
                if ($log_id === false) {
361
                if ($log_id === false) {
140
                        $res = OIDplus::db()->query("select max(id) as last_id from ###log");
362
                        $res = OIDplus::db()->query("select max(id) as last_id from ###log");
141
                        if ($res->num_rows() == 0) throw new OIDplusException("Could not log event");
363
                        if ($res->num_rows() == 0) throw new OIDplusException("Could not log event");
142
                        $row = $res->fetch_array();
364
                        $row = $res->fetch_array();
143
                        $log_id = $row['last_id'];
365
                        $log_id = $row['last_id'];
-
 
366
                        if ($log_id == 0) throw new OIDplusException("Could not log event");
144
                }
367
                }
145
 
368
 
-
 
369
                $object_dupe_check = array();
146
                foreach ($objects as $object) {
370
                foreach ($objects as list($severity, $object)) {
-
 
371
                        if (in_array($object, $object_dupe_check)) continue;
-
 
372
                        $object_dupe_check[] = $object;
147
                        OIDplus::db()->query("insert into ###log_object (log_id, object) values (?, ?)", array($log_id, $object));
373
                        OIDplus::db()->query("insert into ###log_object (log_id, severity, object) values (?, ?, ?)", array($log_id, $severity, $object));
148
                }
374
                }
149
 
375
 
-
 
376
                $user_dupe_check = array();
150
                foreach ($users as $username) {
377
                foreach ($users as list($severity, $username)) {
-
 
378
                        if (in_array($username, $user_dupe_check)) continue;
-
 
379
                        $user_dupe_check[] = $username;
151
                        OIDplus::db()->query("insert into ###log_user (log_id, username) values (?, ?)", array($log_id, $username));
380
                        OIDplus::db()->query("insert into ###log_user (log_id, severity, username) values (?, ?, ?)", array($log_id, $severity, $username));
152
                }
381
                }
153
 
382
 
154
        }
383
        }
155
}
384
}