Line data Source code
1 : // Copyright (C) 2009 The Android Open Source Project
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : package com.google.gerrit.pgm.init.api;
16 :
17 : import com.google.gerrit.common.Nullable;
18 : import com.google.gerrit.server.config.SitePaths;
19 : import com.google.gerrit.server.securestore.SecureStore;
20 : import com.google.inject.Inject;
21 : import com.google.inject.assistedinject.Assisted;
22 : import java.nio.file.Path;
23 : import java.util.ArrayList;
24 : import java.util.Arrays;
25 : import java.util.EnumSet;
26 : import java.util.List;
27 : import java.util.Objects;
28 : import java.util.Set;
29 :
30 : /** Helper to edit a section of the configuration files. */
31 : public class Section {
32 : public interface Factory {
33 : Section get(@Assisted("section") String section, @Assisted("subsection") String subsection);
34 : }
35 :
36 : private final InitFlags flags;
37 : private final SitePaths site;
38 : private final ConsoleUI ui;
39 : private final String section;
40 : private final String subsection;
41 : private final SecureStore secureStore;
42 :
43 : @Inject
44 : public Section(
45 : final InitFlags flags,
46 : final SitePaths site,
47 : final SecureStore secureStore,
48 : final ConsoleUI ui,
49 : @Assisted("section") final String section,
50 16 : @Assisted("subsection") @Nullable final String subsection) {
51 16 : this.flags = flags;
52 16 : this.site = site;
53 16 : this.ui = ui;
54 16 : this.section = section;
55 16 : this.subsection = subsection;
56 16 : this.secureStore = secureStore;
57 16 : }
58 :
59 : public String get(String name) {
60 16 : return flags.cfg.getString(section, subsection, name);
61 : }
62 :
63 : public String[] getList(String name) {
64 15 : return flags.cfg.getStringList(section, subsection, name);
65 : }
66 :
67 : public void set(String name, String value) {
68 15 : final ArrayList<String> all = new ArrayList<>();
69 15 : all.addAll(Arrays.asList(flags.cfg.getStringList(section, subsection, name)));
70 :
71 15 : if (value != null) {
72 15 : if (all.isEmpty() || all.size() == 1) {
73 15 : flags.cfg.setString(section, subsection, name, value);
74 : } else {
75 0 : all.set(0, value);
76 0 : flags.cfg.setStringList(section, subsection, name, all);
77 : }
78 :
79 15 : } else if (all.size() == 1) {
80 0 : flags.cfg.unset(section, subsection, name);
81 15 : } else if (!all.isEmpty()) {
82 0 : all.remove(0);
83 0 : flags.cfg.setStringList(section, subsection, name, all);
84 : }
85 15 : }
86 :
87 : public void setList(String name, List<String> values) {
88 15 : flags.cfg.setStringList(section, subsection, name, values);
89 15 : }
90 :
91 : public <T extends Enum<?>> void set(String name, T value) {
92 15 : if (value != null) {
93 15 : set(name, value.name());
94 : } else {
95 0 : unset(name);
96 : }
97 15 : }
98 :
99 : public void unset(String name) {
100 15 : set(name, (String) null);
101 15 : }
102 :
103 : public String string(String title, String name, String dv) {
104 15 : return string(title, name, dv, false);
105 : }
106 :
107 : public String string(final String title, String name, String dv, boolean nullIfDefault) {
108 15 : final String ov = get(name);
109 15 : String nv = ui.readString(ov != null ? ov : dv, "%s", title);
110 15 : if (nullIfDefault && nv.equals(dv)) {
111 15 : nv = null;
112 : }
113 15 : if (!Objects.equals(ov, nv)) {
114 15 : set(name, nv);
115 : }
116 15 : return nv;
117 : }
118 :
119 : public Path path(String title, String name, String defValue) {
120 15 : return site.resolve(string(title, name, defValue));
121 : }
122 :
123 : public <T extends Enum<?>, E extends EnumSet<? extends T>> T select(
124 : String title, String name, T defValue) {
125 15 : return select(title, name, defValue, false);
126 : }
127 :
128 : public <T extends Enum<?>, E extends EnumSet<? extends T>> T select(
129 : String title, String name, T defValue, boolean nullIfDefault) {
130 : @SuppressWarnings("rawtypes")
131 15 : Class<? extends Enum> declaringClass = defValue.getDeclaringClass();
132 : @SuppressWarnings("unchecked")
133 15 : E allowedValues = (E) EnumSet.allOf(declaringClass);
134 15 : return select(title, name, defValue, allowedValues, nullIfDefault);
135 : }
136 :
137 : public <T extends Enum<?>, E extends EnumSet<? extends T>> T select(
138 : String title, String name, T defValue, E allowedValues) {
139 0 : return select(title, name, defValue, allowedValues, false);
140 : }
141 :
142 : public <T extends Enum<?>, A extends EnumSet<? extends T>> T select(
143 : String title, String name, T defValue, A allowedValues, boolean nullIfDefault) {
144 15 : final boolean set = get(name) != null;
145 15 : T oldValue = flags.cfg.getEnum(section, subsection, name, defValue);
146 15 : T newValue = ui.readEnum(oldValue, allowedValues, "%s", title);
147 15 : if (nullIfDefault && newValue == defValue) {
148 15 : newValue = null;
149 : }
150 15 : if (!set || oldValue != newValue) {
151 15 : if (newValue != null) {
152 15 : set(name, newValue);
153 : } else {
154 15 : unset(name);
155 : }
156 : }
157 15 : return newValue;
158 : }
159 :
160 : public String select(final String title, String name, String dv, Set<String> allowedValues) {
161 15 : final String ov = get(name);
162 15 : String nv = ui.readString(ov != null ? ov : dv, allowedValues, "%s", title);
163 15 : if (!Objects.equals(ov, nv)) {
164 0 : set(name, nv);
165 : }
166 15 : return nv;
167 : }
168 :
169 : @Nullable
170 : public String password(String username, String password) {
171 15 : final String ov = getSecure(password);
172 :
173 15 : String user = flags.sec.get(section, subsection, username);
174 15 : if (user == null) {
175 15 : user = get(username);
176 : }
177 :
178 15 : if (user == null) {
179 15 : flags.sec.unset(section, subsection, password);
180 15 : return null;
181 : }
182 :
183 0 : if (ov != null) {
184 : // If the user already has a password stored, try to reuse it
185 : // rather than prompting for a whole new one.
186 : //
187 0 : if (ui.isBatch() || !ui.yesno(false, "Change %s's password", user)) {
188 0 : return ov;
189 : }
190 : }
191 :
192 0 : final String nv = ui.password("%s's password", user);
193 0 : if (!Objects.equals(ov, nv)) {
194 0 : setSecure(password, nv);
195 : }
196 0 : return nv;
197 : }
198 :
199 : public String passwordForKey(String prompt, String passwordKey) {
200 0 : String ov = getSecure(passwordKey);
201 0 : if (ov != null) {
202 : // If the password is already stored, try to reuse it
203 : // rather than prompting for a whole new one.
204 : //
205 0 : if (ui.isBatch() || !ui.yesno(false, "Change %s", passwordKey)) {
206 0 : return ov;
207 : }
208 : }
209 :
210 0 : final String nv = ui.password("%s", prompt);
211 0 : if (!Objects.equals(ov, nv)) {
212 0 : setSecure(passwordKey, nv);
213 : }
214 0 : return nv;
215 : }
216 :
217 : public String getSecure(String name) {
218 15 : return flags.sec.get(section, subsection, name);
219 : }
220 :
221 : public void setSecure(String name, String value) {
222 15 : if (value != null) {
223 15 : secureStore.set(section, subsection, name, value);
224 : } else {
225 0 : secureStore.unset(section, subsection, name);
226 : }
227 15 : }
228 :
229 : String getName() {
230 0 : return section;
231 : }
232 : }
|