5
5
import java .io .IOException ;
6
6
import java .io .OutputStream ;
7
7
import java .io .Serializable ;
8
+ import java .util .ArrayList ;
8
9
import java .util .List ;
9
10
import java .util .Objects ;
11
+ import java .util .regex .Pattern ;
10
12
import java .util .stream .Collectors ;
11
13
import org .jenkinsci .plugins .credentialsbinding .masking .SecretPatterns ;
12
14
@@ -18,33 +20,37 @@ public class MaskingConsoleLogFilter extends ConsoleLogFilter
18
20
19
21
private final String charsetName ;
20
22
private final List <String > valuesToMask ;
21
-
23
+ private Pattern pattern ;
24
+ private List <String > valuesToMaskInUse ;
22
25
23
26
public MaskingConsoleLogFilter (final String charsetName ,
24
27
List <String > valuesToMask ) {
25
28
this .charsetName = charsetName ;
26
29
this .valuesToMask = valuesToMask ;
30
+ updatePattern ();
31
+ }
32
+
33
+ private synchronized Pattern updatePattern () {
34
+ if (!valuesToMask .equals (valuesToMaskInUse )) {
35
+ List <String > values = valuesToMask .stream ().filter (Objects ::nonNull ).collect (Collectors .toList ());
36
+ pattern = values .isEmpty () ? null : SecretPatterns .getAggregateSecretPattern (values );
37
+ valuesToMaskInUse = new ArrayList <>(valuesToMask );
38
+ }
39
+ return pattern ;
27
40
}
28
41
29
42
@ Override
30
43
public OutputStream decorateLogger (Run run ,
31
44
final OutputStream logger ) throws IOException , InterruptedException {
32
45
return new SecretPatterns .MaskingOutputStream (logger ,
33
- () -> {
34
46
// Only return a non-null pattern once there are secrets to mask. When a non-null
35
47
// pattern is returned it is cached and not supplied again. In cases like
36
48
// VaultBuildWrapper the secrets are added to the "valuesToMasker" list AFTER
37
49
// construction AND AFTER the decorateLogger method is initially called, therefore
38
50
// the Pattern should only be returned once the secrets have been made available.
39
51
// Not to mention it is also a slight optimization when there is are no secrets
40
52
// to mask.
41
- List <String > values = valuesToMask .stream ().filter (Objects ::nonNull ).collect (Collectors .toList ());
42
- if (!values .isEmpty ()) {
43
- return SecretPatterns .getAggregateSecretPattern (values );
44
- } else {
45
- return null ;
46
- }
47
- },
53
+ this ::updatePattern ,
48
54
charsetName );
49
55
}
50
56
0 commit comments