Repository navigation
Add global VoteSites synchronization workflow #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
761c4a0
46b7052
8a5a407
c3c749d
9eae0dc
a1629d5
22603b2
909afcd
3724ddb
9142c8b
9bbee68
368c9c7
74d6d62
0fbded0
4f247b7
6bf086c
4ff12f3
3fb3956
0c71946
54f7e8a
16a1f43
055caa9
78d205a
65a14bb
c486ef6
1384f31
32c3c4e
aa3785a
7d64339
dba2815
1cbbd96
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,7 @@ public record ManagedConfiguration(String domain, Boolean sendVotesToAllServers, | |
| public static final String PROXY_ROUTING = "proxy-routing"; | ||
| public static final String FILE = "file"; | ||
| public static final String QUICK_SETUP = "quick-setup"; | ||
| public static final String VOTE_SITES_SYNC = "sync-vote-sites"; | ||
| public static final int MAX_CONTENT = 512 * 1024; | ||
|
|
||
| public ManagedConfiguration { | ||
|
|
@@ -39,7 +40,7 @@ public record ManagedConfiguration(String domain, Boolean sendVotesToAllServers, | |
| } | ||
| if (options.size() > 20 || options.entrySet().stream().anyMatch(entry -> entry.getKey() == null | ||
| || !entry.getKey().matches("[a-z][A-Za-z0-9]{0,39}") || entry.getValue() == null | ||
| || entry.getValue().length() > 500 || entry.getValue().indexOf('\0') >= 0)) { | ||
| || invalidOption(entry.getKey(), entry.getValue(), VOTE_SITES_SYNC.equals(preset)))) { | ||
| throw new IllegalArgumentException("quick setup options are invalid"); | ||
| } | ||
| } | ||
|
|
@@ -54,18 +55,39 @@ public static ManagedConfiguration file(String fileName, String content) { | |
| return new ManagedConfiguration(FILE, null, List.of(), fileName, content, null, Map.of()); | ||
| } | ||
|
|
||
| public void validateProposal() { | ||
| if (QUICK_SETUP.equals(domain) && VOTE_SITES_SYNC.equals(preset) | ||
| && (options.size() != 1 || !options.containsKey("sourceContent"))) { | ||
| throw new IllegalArgumentException("VoteSites sync requires sourceContent"); | ||
| } | ||
| } | ||
|
|
||
| public String capability() { | ||
| return switch (domain) { | ||
| case PROXY_ROUTING -> "config.proxy-routing.v1"; | ||
| case FILE -> "config.files.v1"; | ||
| case QUICK_SETUP -> "config.quick-setup.v1"; | ||
| case QUICK_SETUP -> VOTE_SITES_SYNC.equals(preset) | ||
| ? "config.vote-sites-sync.v1" : "config.quick-setup.v1"; | ||
| default -> throw new IllegalStateException("unsupported configuration domain"); | ||
| }; | ||
| } | ||
|
|
||
| /** Omits file contents so proposals, including newly entered secrets, are never echoed by operation APIs. */ | ||
| public ManagedConfiguration publicView() { | ||
| return FILE.equals(domain) ? file(fileName, null) : this; | ||
| if (FILE.equals(domain)) return file(fileName, null); | ||
| if (QUICK_SETUP.equals(domain) && VOTE_SITES_SYNC.equals(preset) && options.containsKey("sourceContent")) { | ||
| Map<String, String> visible = new LinkedHashMap<>(options); | ||
| visible.remove("sourceContent"); | ||
| return new ManagedConfiguration(domain, sendVotesToAllServers, blockedServers, fileName, content, | ||
| preset, visible); | ||
|
Comment on lines
+78
to
+82
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a sync target returns its successful typed configuration with the submitted Useful? React with 👍 / 👎.
Comment on lines
+81
to
+82
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For every Useful? React with 👍 / 👎. |
||
| } | ||
| return this; | ||
| } | ||
|
|
||
| private static boolean invalidOption(String name, String value, boolean voteSitesSync) { | ||
| boolean sourceContent = voteSitesSync && "sourceContent".equals(name); | ||
| int maximum = sourceContent ? MAX_CONTENT : 500; | ||
| return value.indexOf('\0') >= 0 || value.length() > maximum; | ||
| } | ||
|
|
||
| private static void validateFileName(String value) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When an API client submits the new
sync-vote-sitespreset directly, this validation still accepts empty options or unrelated options because it only changes the limit when an entry happens to be namedsourceContent. Such a request negotiatesconfig.vote-sites-sync.v1and is queued to targets without any source YAML, leaving node handlers to fail or interpret an incomplete sync task; require the preset's options to contain exactly one non-nullsourceContentdocument.Useful? React with 👍 / 👎.