Passed
Push — master ( 416efc...991aca )
by Julius
16:27 queued 13s
created
lib/private/Log/ExceptionSerializer.php 1 patch
Indentation   +264 added lines, -264 removed lines patch added patch discarded remove patch
@@ -42,268 +42,268 @@
 block discarded – undo
42 42
 use OCP\HintException;
43 43
 
44 44
 class ExceptionSerializer {
45
-	public const SENSITIVE_VALUE_PLACEHOLDER = '*** sensitive parameters replaced ***';
46
-
47
-	public const methodsWithSensitiveParameters = [
48
-		// Session/User
49
-		'completeLogin',
50
-		'login',
51
-		'checkPassword',
52
-		'checkPasswordNoLogging',
53
-		'loginWithPassword',
54
-		'updatePrivateKeyPassword',
55
-		'validateUserPass',
56
-		'loginWithToken',
57
-		'{closure}',
58
-		'createSessionToken',
59
-
60
-		// Provisioning
61
-		'addUser',
62
-
63
-		// TokenProvider
64
-		'getToken',
65
-		'isTokenPassword',
66
-		'getPassword',
67
-		'decryptPassword',
68
-		'logClientIn',
69
-		'generateToken',
70
-		'validateToken',
71
-
72
-		// TwoFactorAuth
73
-		'solveChallenge',
74
-		'verifyChallenge',
75
-
76
-		// ICrypto
77
-		'calculateHMAC',
78
-		'encrypt',
79
-		'decrypt',
80
-
81
-		// LoginController
82
-		'tryLogin',
83
-		'confirmPassword',
84
-
85
-		// LDAP
86
-		'bind',
87
-		'areCredentialsValid',
88
-		'invokeLDAPMethod',
89
-
90
-		// Encryption
91
-		'storeKeyPair',
92
-		'setupUser',
93
-		'checkSignature',
94
-
95
-		// files_external: OCA\Files_External\MountConfig
96
-		'getBackendStatus',
97
-
98
-		// files_external: UserStoragesController
99
-		'update',
100
-
101
-		// Preview providers, don't log big data strings
102
-		'imagecreatefromstring',
103
-
104
-		// text: PublicSessionController, SessionController and ApiService
105
-		'create',
106
-		'close',
107
-		'push',
108
-		'sync',
109
-		'updateSession',
110
-		'mention',
111
-		'loginSessionUser',
112
-
113
-	];
114
-
115
-	/** @var SystemConfig */
116
-	private $systemConfig;
117
-
118
-	public function __construct(SystemConfig $systemConfig) {
119
-		$this->systemConfig = $systemConfig;
120
-	}
121
-
122
-	protected array $methodsWithSensitiveParametersByClass = [
123
-		SetupController::class => [
124
-			'run',
125
-			'display',
126
-			'loadAutoConfig',
127
-		],
128
-		Setup::class => [
129
-			'install'
130
-		],
131
-		Key::class => [
132
-			'__construct'
133
-		],
134
-		\Redis::class => [
135
-			'auth'
136
-		],
137
-		\RedisCluster::class => [
138
-			'__construct'
139
-		],
140
-		Crypt::class => [
141
-			'symmetricEncryptFileContent',
142
-			'encrypt',
143
-			'generatePasswordHash',
144
-			'encryptPrivateKey',
145
-			'decryptPrivateKey',
146
-			'isValidPrivateKey',
147
-			'symmetricDecryptFileContent',
148
-			'checkSignature',
149
-			'createSignature',
150
-			'decrypt',
151
-			'multiKeyDecrypt',
152
-			'multiKeyEncrypt',
153
-		],
154
-		RecoveryController::class => [
155
-			'adminRecovery',
156
-			'changeRecoveryPassword'
157
-		],
158
-		SettingsController::class => [
159
-			'updatePrivateKeyPassword',
160
-		],
161
-		Encryption::class => [
162
-			'encrypt',
163
-			'decrypt',
164
-		],
165
-		KeyManager::class => [
166
-			'checkRecoveryPassword',
167
-			'storeKeyPair',
168
-			'setRecoveryKey',
169
-			'setPrivateKey',
170
-			'setFileKey',
171
-			'setAllFileKeys',
172
-		],
173
-		Session::class => [
174
-			'setPrivateKey',
175
-			'prepareDecryptAll',
176
-		],
177
-		\OCA\Encryption\Users\Setup::class => [
178
-			'setupUser',
179
-		],
180
-		UserHooks::class => [
181
-			'login',
182
-			'postCreateUser',
183
-			'postDeleteUser',
184
-			'prePasswordReset',
185
-			'postPasswordReset',
186
-			'preSetPassphrase',
187
-			'setPassphrase',
188
-		],
189
-	];
190
-
191
-	private function editTrace(array &$sensitiveValues, array $traceLine): array {
192
-		if (isset($traceLine['args'])) {
193
-			$sensitiveValues = array_merge($sensitiveValues, $traceLine['args']);
194
-		}
195
-		$traceLine['args'] = [self::SENSITIVE_VALUE_PLACEHOLDER];
196
-		return $traceLine;
197
-	}
198
-
199
-	private function filterTrace(array $trace) {
200
-		$sensitiveValues = [];
201
-		$trace = array_map(function (array $traceLine) use (&$sensitiveValues) {
202
-			$className = $traceLine['class'] ?? '';
203
-			if ($className && isset($this->methodsWithSensitiveParametersByClass[$className])
204
-				&& in_array($traceLine['function'], $this->methodsWithSensitiveParametersByClass[$className], true)) {
205
-				return $this->editTrace($sensitiveValues, $traceLine);
206
-			}
207
-			foreach (self::methodsWithSensitiveParameters as $sensitiveMethod) {
208
-				if (strpos($traceLine['function'], $sensitiveMethod) !== false) {
209
-					return $this->editTrace($sensitiveValues, $traceLine);
210
-				}
211
-			}
212
-			return $traceLine;
213
-		}, $trace);
214
-		return array_map(function (array $traceLine) use ($sensitiveValues) {
215
-			if (isset($traceLine['args'])) {
216
-				$traceLine['args'] = $this->removeValuesFromArgs($traceLine['args'], $sensitiveValues);
217
-			}
218
-			return $traceLine;
219
-		}, $trace);
220
-	}
221
-
222
-	private function removeValuesFromArgs($args, $values) {
223
-		$workArgs = [];
224
-		foreach ($args as $arg) {
225
-			if (in_array($arg, $values, true)) {
226
-				$arg = self::SENSITIVE_VALUE_PLACEHOLDER;
227
-			} elseif (is_array($arg)) {
228
-				$arg = $this->removeValuesFromArgs($arg, $values);
229
-			}
230
-			$workArgs[] = $arg;
231
-		}
232
-		return $workArgs;
233
-	}
234
-
235
-	private function encodeTrace($trace) {
236
-		$trace = array_map(function (array $line) {
237
-			if (isset($line['args'])) {
238
-				$line['args'] = array_map([$this, 'encodeArg'], $line['args']);
239
-			}
240
-			return $line;
241
-		}, $trace);
242
-		return $this->filterTrace($trace);
243
-	}
244
-
245
-	private function encodeArg($arg, $nestingLevel = 5) {
246
-		if (is_object($arg)) {
247
-			if ($nestingLevel === 0) {
248
-				return [
249
-					'__class__' => get_class($arg),
250
-					'__properties__' => 'Encoding skipped as the maximum nesting level was reached',
251
-				];
252
-			}
253
-
254
-			$objectInfo = [ '__class__' => get_class($arg) ];
255
-			$objectVars = get_object_vars($arg);
256
-			return array_map(function ($arg) use ($nestingLevel) {
257
-				return $this->encodeArg($arg, $nestingLevel - 1);
258
-			}, array_merge($objectInfo, $objectVars));
259
-		}
260
-
261
-		if (is_array($arg)) {
262
-			if ($nestingLevel === 0) {
263
-				return ['Encoding skipped as the maximum nesting level was reached'];
264
-			}
265
-
266
-			// Only log the first 5 elements of an array unless we are on debug
267
-			if ((int)$this->systemConfig->getValue('loglevel', 2) !== 0) {
268
-				$elemCount = count($arg);
269
-				if ($elemCount > 5) {
270
-					$arg = array_slice($arg, 0, 5);
271
-					$arg[] = 'And ' . ($elemCount - 5) . ' more entries, set log level to debug to see all entries';
272
-				}
273
-			}
274
-			return array_map(function ($e) use ($nestingLevel) {
275
-				return $this->encodeArg($e, $nestingLevel - 1);
276
-			}, $arg);
277
-		}
278
-
279
-		return $arg;
280
-	}
281
-
282
-	public function serializeException(\Throwable $exception) {
283
-		$data = [
284
-			'Exception' => get_class($exception),
285
-			'Message' => $exception->getMessage(),
286
-			'Code' => $exception->getCode(),
287
-			'Trace' => $this->encodeTrace($exception->getTrace()),
288
-			'File' => $exception->getFile(),
289
-			'Line' => $exception->getLine(),
290
-		];
291
-
292
-		if ($exception instanceof HintException) {
293
-			$data['Hint'] = $exception->getHint();
294
-		}
295
-
296
-		if ($exception->getPrevious()) {
297
-			$data['Previous'] = $this->serializeException($exception->getPrevious());
298
-		}
299
-
300
-		return $data;
301
-	}
302
-
303
-	public function enlistSensitiveMethods(string $class, array $methods): void {
304
-		if (!isset($this->methodsWithSensitiveParametersByClass[$class])) {
305
-			$this->methodsWithSensitiveParametersByClass[$class] = [];
306
-		}
307
-		$this->methodsWithSensitiveParametersByClass[$class] = array_merge($this->methodsWithSensitiveParametersByClass[$class], $methods);
308
-	}
45
+    public const SENSITIVE_VALUE_PLACEHOLDER = '*** sensitive parameters replaced ***';
46
+
47
+    public const methodsWithSensitiveParameters = [
48
+        // Session/User
49
+        'completeLogin',
50
+        'login',
51
+        'checkPassword',
52
+        'checkPasswordNoLogging',
53
+        'loginWithPassword',
54
+        'updatePrivateKeyPassword',
55
+        'validateUserPass',
56
+        'loginWithToken',
57
+        '{closure}',
58
+        'createSessionToken',
59
+
60
+        // Provisioning
61
+        'addUser',
62
+
63
+        // TokenProvider
64
+        'getToken',
65
+        'isTokenPassword',
66
+        'getPassword',
67
+        'decryptPassword',
68
+        'logClientIn',
69
+        'generateToken',
70
+        'validateToken',
71
+
72
+        // TwoFactorAuth
73
+        'solveChallenge',
74
+        'verifyChallenge',
75
+
76
+        // ICrypto
77
+        'calculateHMAC',
78
+        'encrypt',
79
+        'decrypt',
80
+
81
+        // LoginController
82
+        'tryLogin',
83
+        'confirmPassword',
84
+
85
+        // LDAP
86
+        'bind',
87
+        'areCredentialsValid',
88
+        'invokeLDAPMethod',
89
+
90
+        // Encryption
91
+        'storeKeyPair',
92
+        'setupUser',
93
+        'checkSignature',
94
+
95
+        // files_external: OCA\Files_External\MountConfig
96
+        'getBackendStatus',
97
+
98
+        // files_external: UserStoragesController
99
+        'update',
100
+
101
+        // Preview providers, don't log big data strings
102
+        'imagecreatefromstring',
103
+
104
+        // text: PublicSessionController, SessionController and ApiService
105
+        'create',
106
+        'close',
107
+        'push',
108
+        'sync',
109
+        'updateSession',
110
+        'mention',
111
+        'loginSessionUser',
112
+
113
+    ];
114
+
115
+    /** @var SystemConfig */
116
+    private $systemConfig;
117
+
118
+    public function __construct(SystemConfig $systemConfig) {
119
+        $this->systemConfig = $systemConfig;
120
+    }
121
+
122
+    protected array $methodsWithSensitiveParametersByClass = [
123
+        SetupController::class => [
124
+            'run',
125
+            'display',
126
+            'loadAutoConfig',
127
+        ],
128
+        Setup::class => [
129
+            'install'
130
+        ],
131
+        Key::class => [
132
+            '__construct'
133
+        ],
134
+        \Redis::class => [
135
+            'auth'
136
+        ],
137
+        \RedisCluster::class => [
138
+            '__construct'
139
+        ],
140
+        Crypt::class => [
141
+            'symmetricEncryptFileContent',
142
+            'encrypt',
143
+            'generatePasswordHash',
144
+            'encryptPrivateKey',
145
+            'decryptPrivateKey',
146
+            'isValidPrivateKey',
147
+            'symmetricDecryptFileContent',
148
+            'checkSignature',
149
+            'createSignature',
150
+            'decrypt',
151
+            'multiKeyDecrypt',
152
+            'multiKeyEncrypt',
153
+        ],
154
+        RecoveryController::class => [
155
+            'adminRecovery',
156
+            'changeRecoveryPassword'
157
+        ],
158
+        SettingsController::class => [
159
+            'updatePrivateKeyPassword',
160
+        ],
161
+        Encryption::class => [
162
+            'encrypt',
163
+            'decrypt',
164
+        ],
165
+        KeyManager::class => [
166
+            'checkRecoveryPassword',
167
+            'storeKeyPair',
168
+            'setRecoveryKey',
169
+            'setPrivateKey',
170
+            'setFileKey',
171
+            'setAllFileKeys',
172
+        ],
173
+        Session::class => [
174
+            'setPrivateKey',
175
+            'prepareDecryptAll',
176
+        ],
177
+        \OCA\Encryption\Users\Setup::class => [
178
+            'setupUser',
179
+        ],
180
+        UserHooks::class => [
181
+            'login',
182
+            'postCreateUser',
183
+            'postDeleteUser',
184
+            'prePasswordReset',
185
+            'postPasswordReset',
186
+            'preSetPassphrase',
187
+            'setPassphrase',
188
+        ],
189
+    ];
190
+
191
+    private function editTrace(array &$sensitiveValues, array $traceLine): array {
192
+        if (isset($traceLine['args'])) {
193
+            $sensitiveValues = array_merge($sensitiveValues, $traceLine['args']);
194
+        }
195
+        $traceLine['args'] = [self::SENSITIVE_VALUE_PLACEHOLDER];
196
+        return $traceLine;
197
+    }
198
+
199
+    private function filterTrace(array $trace) {
200
+        $sensitiveValues = [];
201
+        $trace = array_map(function (array $traceLine) use (&$sensitiveValues) {
202
+            $className = $traceLine['class'] ?? '';
203
+            if ($className && isset($this->methodsWithSensitiveParametersByClass[$className])
204
+                && in_array($traceLine['function'], $this->methodsWithSensitiveParametersByClass[$className], true)) {
205
+                return $this->editTrace($sensitiveValues, $traceLine);
206
+            }
207
+            foreach (self::methodsWithSensitiveParameters as $sensitiveMethod) {
208
+                if (strpos($traceLine['function'], $sensitiveMethod) !== false) {
209
+                    return $this->editTrace($sensitiveValues, $traceLine);
210
+                }
211
+            }
212
+            return $traceLine;
213
+        }, $trace);
214
+        return array_map(function (array $traceLine) use ($sensitiveValues) {
215
+            if (isset($traceLine['args'])) {
216
+                $traceLine['args'] = $this->removeValuesFromArgs($traceLine['args'], $sensitiveValues);
217
+            }
218
+            return $traceLine;
219
+        }, $trace);
220
+    }
221
+
222
+    private function removeValuesFromArgs($args, $values) {
223
+        $workArgs = [];
224
+        foreach ($args as $arg) {
225
+            if (in_array($arg, $values, true)) {
226
+                $arg = self::SENSITIVE_VALUE_PLACEHOLDER;
227
+            } elseif (is_array($arg)) {
228
+                $arg = $this->removeValuesFromArgs($arg, $values);
229
+            }
230
+            $workArgs[] = $arg;
231
+        }
232
+        return $workArgs;
233
+    }
234
+
235
+    private function encodeTrace($trace) {
236
+        $trace = array_map(function (array $line) {
237
+            if (isset($line['args'])) {
238
+                $line['args'] = array_map([$this, 'encodeArg'], $line['args']);
239
+            }
240
+            return $line;
241
+        }, $trace);
242
+        return $this->filterTrace($trace);
243
+    }
244
+
245
+    private function encodeArg($arg, $nestingLevel = 5) {
246
+        if (is_object($arg)) {
247
+            if ($nestingLevel === 0) {
248
+                return [
249
+                    '__class__' => get_class($arg),
250
+                    '__properties__' => 'Encoding skipped as the maximum nesting level was reached',
251
+                ];
252
+            }
253
+
254
+            $objectInfo = [ '__class__' => get_class($arg) ];
255
+            $objectVars = get_object_vars($arg);
256
+            return array_map(function ($arg) use ($nestingLevel) {
257
+                return $this->encodeArg($arg, $nestingLevel - 1);
258
+            }, array_merge($objectInfo, $objectVars));
259
+        }
260
+
261
+        if (is_array($arg)) {
262
+            if ($nestingLevel === 0) {
263
+                return ['Encoding skipped as the maximum nesting level was reached'];
264
+            }
265
+
266
+            // Only log the first 5 elements of an array unless we are on debug
267
+            if ((int)$this->systemConfig->getValue('loglevel', 2) !== 0) {
268
+                $elemCount = count($arg);
269
+                if ($elemCount > 5) {
270
+                    $arg = array_slice($arg, 0, 5);
271
+                    $arg[] = 'And ' . ($elemCount - 5) . ' more entries, set log level to debug to see all entries';
272
+                }
273
+            }
274
+            return array_map(function ($e) use ($nestingLevel) {
275
+                return $this->encodeArg($e, $nestingLevel - 1);
276
+            }, $arg);
277
+        }
278
+
279
+        return $arg;
280
+    }
281
+
282
+    public function serializeException(\Throwable $exception) {
283
+        $data = [
284
+            'Exception' => get_class($exception),
285
+            'Message' => $exception->getMessage(),
286
+            'Code' => $exception->getCode(),
287
+            'Trace' => $this->encodeTrace($exception->getTrace()),
288
+            'File' => $exception->getFile(),
289
+            'Line' => $exception->getLine(),
290
+        ];
291
+
292
+        if ($exception instanceof HintException) {
293
+            $data['Hint'] = $exception->getHint();
294
+        }
295
+
296
+        if ($exception->getPrevious()) {
297
+            $data['Previous'] = $this->serializeException($exception->getPrevious());
298
+        }
299
+
300
+        return $data;
301
+    }
302
+
303
+    public function enlistSensitiveMethods(string $class, array $methods): void {
304
+        if (!isset($this->methodsWithSensitiveParametersByClass[$class])) {
305
+            $this->methodsWithSensitiveParametersByClass[$class] = [];
306
+        }
307
+        $this->methodsWithSensitiveParametersByClass[$class] = array_merge($this->methodsWithSensitiveParametersByClass[$class], $methods);
308
+    }
309 309
 }
Please login to merge, or discard this patch.