1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.bremersee.dccon.repository.cli;
18
19 import java.io.BufferedReader;
20 import java.io.IOException;
21 import java.io.StringReader;
22 import java.util.Optional;
23 import lombok.extern.slf4j.Slf4j;
24 import org.bremersee.dccon.model.PasswordComplexity;
25 import org.bremersee.dccon.model.PasswordInformation;
26
27
28
29
30
31
32 public interface PasswordInformationParser
33 extends CommandExecutorResponseParser<PasswordInformation> {
34
35
36
37
38
39
40 static PasswordInformationParser defaultParser() {
41 return new PasswordInformationParser.Default();
42 }
43
44
45
46
47 @Slf4j
48 class Default implements PasswordInformationParser {
49
50 static final String PASSWORD_COMPLEXITY = "Password complexity:";
51
52 static final String STORE_PLAINTEXT_PASSWORD = "Store plaintext passwords:";
53
54 static final String PASSWORD_HISTORY_LENGTH = "Password history length:";
55
56 static final String MINIMUM_PASSWORD_LENGTH = "Minimum password length:";
57
58 static final String MINIMUM_PASSWORD_AGE = "Minimum password age (days):";
59
60 static final String MAXIMUM_PASSWORD_AGE = "Maximum password age (days):";
61
62 static final String ACCOUNT_LOCKOUT_DURATION = "Account lockout duration (mins):";
63
64 static final String ACCOUNT_LOCKOUT_THRESHOLD = "Account lockout threshold (attempts):";
65
66 static final String RESET_ACCOUNT_LOCKOUT_AFTER = "Reset account lockout after (mins):";
67
68 @Override
69 public PasswordInformation parse(final CommandExecutorResponse response) {
70 if (!response.stdoutHasText()) {
71 log.warn("Password information command did not produce output. Error is [{}].",
72 response.getStderr());
73 return new PasswordInformation();
74 }
75 final String output = response.getStdout();
76 try (final BufferedReader reader = new BufferedReader(new StringReader(output))) {
77 return parse(reader);
78
79 } catch (IOException e) {
80 log.error("Parsing password information failed:\n" + output + "\n", e);
81 return new PasswordInformation();
82 }
83 }
84
85 private PasswordInformation parse(final BufferedReader reader) throws IOException {
86 final PasswordInformation info = new PasswordInformation();
87 String line;
88 while ((line = reader.readLine()) != null) {
89 line = line.trim();
90 findValue(line, PASSWORD_COMPLEXITY)
91 .ifPresent(s -> info.setPasswordComplexity(PasswordComplexity.fromValue(s)));
92 findValue(line, STORE_PLAINTEXT_PASSWORD)
93 .ifPresent(s -> info.setStorePlaintextPasswords(parseBoolean(s)));
94 findValue(line, PASSWORD_HISTORY_LENGTH)
95 .ifPresent(s -> info.setPasswordHistoryLength(parseInt(s)));
96 findValue(line, MINIMUM_PASSWORD_LENGTH)
97 .ifPresent(s -> info.setMinimumPasswordLength(parseInt(s)));
98 findValue(line, MINIMUM_PASSWORD_AGE)
99 .ifPresent(s -> info.setMinimumPasswordAgeInDays(parseInt(s)));
100 findValue(line, MAXIMUM_PASSWORD_AGE)
101 .ifPresent(s -> info.setMaximumPasswordAgeInDays(parseInt(s)));
102 findValue(line, ACCOUNT_LOCKOUT_DURATION)
103 .ifPresent(s -> info.setAccountLockoutDurationInMinutes(parseInt(s)));
104 findValue(line, ACCOUNT_LOCKOUT_THRESHOLD)
105 .ifPresent(s -> info.setAccountLockoutThreshold(parseInt(s)));
106 findValue(line, RESET_ACCOUNT_LOCKOUT_AFTER)
107 .ifPresent(s -> info.setResetAccountLockoutAfter(parseInt(s)));
108 }
109 return info;
110 }
111
112 private Optional<String> findValue(final String line, final String label) {
113 final int index = line.indexOf(label);
114 if (index > -1) {
115 final String value = line.substring(index + label.length()).trim();
116 if (value.length() > 0) {
117 return Optional.of(value);
118 }
119 }
120 return Optional.empty();
121 }
122
123 private Boolean parseBoolean(final String value) {
124 try {
125 return Boolean.parseBoolean(value);
126 } catch (Exception ignored) {
127 return null;
128 }
129 }
130
131 private Integer parseInt(String value) {
132 try {
133 return Integer.parseInt(value);
134 } catch (Exception ignored) {
135 return null;
136 }
137 }
138
139 }
140
141 }