1 | package org.expeditee.encryption.items.surrogates;
|
---|
2 |
|
---|
3 | import java.util.ArrayList;
|
---|
4 | import java.util.Arrays;
|
---|
5 | import java.util.Base64;
|
---|
6 | import java.util.List;
|
---|
7 | import java.util.function.Predicate;
|
---|
8 | import java.util.stream.Collectors;
|
---|
9 | import java.util.stream.Stream;
|
---|
10 |
|
---|
11 | import org.expeditee.gui.DisplayController;
|
---|
12 | import org.expeditee.gui.ItemsList;
|
---|
13 | import org.expeditee.items.Item;
|
---|
14 | import org.expeditee.items.Text;
|
---|
15 | import org.expeditee.settings.identity.secrets.KeyList;
|
---|
16 |
|
---|
17 | public class Label {
|
---|
18 | private static List<String> userLabels = new ArrayList<String>();
|
---|
19 | private static List<LabelInfo> labelsInfo = new ArrayList<LabelInfo>();
|
---|
20 | private static int surrogateStep = 0;
|
---|
21 | private static boolean isInSurrogateMode = false;
|
---|
22 | private static boolean isUnprivileged = false;
|
---|
23 |
|
---|
24 | public static LabelInfo getLabel(String labelName) {
|
---|
25 | // Maintain the local cache of user labels
|
---|
26 | ensureUserLabels();
|
---|
27 |
|
---|
28 | int indexOfLabel = userLabels.indexOf(labelName);
|
---|
29 | if (indexOfLabel == -1) {
|
---|
30 | //A label by the specified name does not exist.
|
---|
31 | return unableToFindLabelResult(labelName);
|
---|
32 | } else {
|
---|
33 | //A label by the specified name is in the local cache and can be used.
|
---|
34 | LabelInfo labelResult = labelsInfo.get(indexOfLabel);
|
---|
35 | return labelResult;
|
---|
36 | }
|
---|
37 | }
|
---|
38 |
|
---|
39 | public static boolean isInSurrogateMode() {
|
---|
40 | return isInSurrogateMode;
|
---|
41 | }
|
---|
42 |
|
---|
43 | /**
|
---|
44 | * Progresses surrogate mode and returns a list of labels that are currently in effect.
|
---|
45 | * @param context The list of expeditee Items to be considered for context. These are checked for labels.
|
---|
46 | * @return Returns either:
|
---|
47 | * <ol type='a'>
|
---|
48 | * <li> A list of length 1 specifying the label that the current surrogate mode accepts or </li>
|
---|
49 | * <li> A list of length 0 which specifies that surrogate mode is in unprivileged view or </li>
|
---|
50 | * <li> Null, which means there are no labels in play on this frame
|
---|
51 | * (so asking for surrogate mode does not make sense) </li>
|
---|
52 | * </ol>
|
---|
53 | */
|
---|
54 | public static List<String> progressSurrogateMode(ItemsList context) {
|
---|
55 | // Maintain the local cache of user labels
|
---|
56 | ensureUserLabels();
|
---|
57 |
|
---|
58 | List<String> ret;
|
---|
59 |
|
---|
60 | List<String> localLabels = getLabelsFromContext(context);
|
---|
61 | if (localLabels.isEmpty()) {
|
---|
62 | // If there are no labels on this Frame return null;
|
---|
63 | return null;
|
---|
64 | }
|
---|
65 |
|
---|
66 | ArrayList<String> intersection = new ArrayList<String>(userLabels);
|
---|
67 | intersection.retainAll(localLabels);
|
---|
68 | if (!isInSurrogateMode) {
|
---|
69 | isInSurrogateMode = true;
|
---|
70 | // Priming surrogate step to become zero in the loop below.
|
---|
71 | surrogateStep = -1;
|
---|
72 | }
|
---|
73 |
|
---|
74 | // We are already in surrogate mode, progress it.
|
---|
75 | int index = surrogateStep + 1;
|
---|
76 | boolean found = false;
|
---|
77 | while (index < userLabels.size()) {
|
---|
78 | String surrogateMode = userLabels.get(index);
|
---|
79 | if (intersection.contains(surrogateMode)) {
|
---|
80 | found = true;
|
---|
81 | break;
|
---|
82 | }
|
---|
83 | index++;
|
---|
84 | }
|
---|
85 |
|
---|
86 | if (found) {
|
---|
87 | isUnprivileged = false;
|
---|
88 | surrogateStep = index;
|
---|
89 | String chosenSurrogateMode = userLabels.get(surrogateStep);
|
---|
90 | ret = Arrays.asList(chosenSurrogateMode);
|
---|
91 | } else {
|
---|
92 | if (surrogateStep >= userLabels.size()) {
|
---|
93 | surrogateStep = 0;
|
---|
94 | isInSurrogateMode = false;
|
---|
95 | isUnprivileged = false;
|
---|
96 | ret = intersection;
|
---|
97 | } else {
|
---|
98 | ret = new ArrayList<String>();
|
---|
99 | surrogateStep = index;
|
---|
100 | isUnprivileged = true;
|
---|
101 | }
|
---|
102 | }
|
---|
103 |
|
---|
104 | return ret;
|
---|
105 | }
|
---|
106 |
|
---|
107 | public static void resetSurrogateMode() {
|
---|
108 | // Maintain the local cache of user labels
|
---|
109 | ensureUserLabels();
|
---|
110 |
|
---|
111 | surrogateStep = 0;
|
---|
112 | isInSurrogateMode = false;
|
---|
113 | }
|
---|
114 |
|
---|
115 | public static List<String> getAccessibleLabelsNames(ItemsList itemsList) {
|
---|
116 | // Maintain the local cache of user labels
|
---|
117 | ensureUserLabels();
|
---|
118 |
|
---|
119 | if (isInSurrogateMode) {
|
---|
120 | if (isUnprivileged) {
|
---|
121 | return new ArrayList<String>();
|
---|
122 | } else {
|
---|
123 | return Arrays.asList(userLabels.get(surrogateStep));
|
---|
124 | }
|
---|
125 | } else {
|
---|
126 | List<String> labelsFromContext = getLabelsFromContext(itemsList);
|
---|
127 | ArrayList<String> copy = new ArrayList<String>(labelsFromContext);
|
---|
128 | copy.retainAll(userLabels);
|
---|
129 | return copy;
|
---|
130 | }
|
---|
131 | }
|
---|
132 |
|
---|
133 | private static void ensureUserLabels() {
|
---|
134 | List<String> userSettingsLabelNames = KeyList.getLabelsNameOnly();
|
---|
135 | boolean hasNoKeys = userLabels.isEmpty() && userSettingsLabelNames.isEmpty();
|
---|
136 | boolean hasNotChanged = userLabels.equals(userSettingsLabelNames) || hasNoKeys;
|
---|
137 |
|
---|
138 | if (hasNotChanged) { return; }
|
---|
139 |
|
---|
140 | // Deal with the fact that the position of our current surrogate mode
|
---|
141 | // might have moved in the users list of labels.
|
---|
142 | if (userLabels.size() > surrogateStep) {
|
---|
143 | String surrogateMode = userLabels.get(surrogateStep);
|
---|
144 | int newIndexOfSurrogateMode = userSettingsLabelNames.indexOf(surrogateMode);
|
---|
145 | if (newIndexOfSurrogateMode >= 0) {
|
---|
146 | surrogateStep = newIndexOfSurrogateMode;
|
---|
147 | } else {
|
---|
148 | surrogateStep = 0;
|
---|
149 | isInSurrogateMode = false;
|
---|
150 | // MessageBay.displayMessage("You have lost access to the encryption label "
|
---|
151 | // + surrogateMode + ". Dropping out of surrogate mode.");
|
---|
152 | System.out.println("You have lost access to the encryption label "
|
---|
153 | + surrogateMode + ". Dropping out of surrogate mode.");
|
---|
154 | }
|
---|
155 | }
|
---|
156 |
|
---|
157 | // (Re)Initialise the userLabels list and labelResultsCache.
|
---|
158 | userLabels.clear();
|
---|
159 | labelsInfo.clear();
|
---|
160 | Text[] userSettings = KeyList.UserLabels.get();
|
---|
161 | for (Text userSetting: userSettings) {
|
---|
162 | String labelName = userSetting.getName();
|
---|
163 | List<String> data = userSetting.getData();
|
---|
164 | if (data == null || data.isEmpty()) {
|
---|
165 | continue;
|
---|
166 | }
|
---|
167 |
|
---|
168 | // Extract the data and check if we have a full or partial key.
|
---|
169 | String dataEntry = data.get(0);
|
---|
170 | if (dataEntry.contains("{")) {
|
---|
171 | userLabels.add(labelName);
|
---|
172 | LabelInfo labelInfo = new LabelInfo(LabelResult.SuccessResolveLabelToPartialKey, labelName, null);
|
---|
173 | labelsInfo.add(labelInfo);
|
---|
174 | } else {
|
---|
175 | userLabels.add(labelName);
|
---|
176 | byte[] key = Base64.getDecoder().decode(dataEntry);
|
---|
177 | LabelInfo labelInfo = new LabelInfo(LabelResult.SuccessResolveLabelToKey, labelName, key);
|
---|
178 | labelsInfo.add(labelInfo);
|
---|
179 | }
|
---|
180 | }
|
---|
181 | }
|
---|
182 |
|
---|
183 | private static List<String> getLabelsFromContext(ItemsList context) {
|
---|
184 | Predicate<Item> hasEncryptionLabel = item -> item.getEncryptionLabel() != null && !item.getEncryptionLabel().isEmpty();
|
---|
185 | List<Item> local = context.cloneList();
|
---|
186 | Stream<Item> itemsWithLabel = local.stream().filter(hasEncryptionLabel);
|
---|
187 | Stream<String> labels = itemsWithLabel.map(item -> item.getEncryptionLabel()).distinct();
|
---|
188 | return labels.collect(Collectors.toList());
|
---|
189 | }
|
---|
190 |
|
---|
191 | private static LabelInfo unableToFindLabelResult(String label) {
|
---|
192 | LabelInfo info = new LabelInfo(LabelResult.ErrorUnableToFindLabel, label, null);
|
---|
193 | return info;
|
---|
194 | }
|
---|
195 |
|
---|
196 | public static class LabelInfo {
|
---|
197 |
|
---|
198 | public byte[] key;
|
---|
199 | public String name;
|
---|
200 | public LabelResult type;
|
---|
201 |
|
---|
202 | public LabelInfo(LabelResult type, String name, byte[] key) {
|
---|
203 | this.type = type;
|
---|
204 | this.name = name;
|
---|
205 | this.key = key;
|
---|
206 | }
|
---|
207 |
|
---|
208 | public boolean is(LabelResult type) {
|
---|
209 | return this.type == type;
|
---|
210 | }
|
---|
211 |
|
---|
212 | public String toString() {
|
---|
213 | switch(type) {
|
---|
214 | case SuccessResolveLabelToKey:
|
---|
215 | return "Resolved label to key: " + Base64.getEncoder().encodeToString(key);
|
---|
216 | case SuccessResolveLabelToPartialKey:
|
---|
217 | return "Resolved label to slice of a key: " + Base64.getEncoder().encodeToString(key);
|
---|
218 | case ErrorUnableToFindSecretsFrame:
|
---|
219 | return "Unable to find your Secrets Frame.";
|
---|
220 | case ErrorUnableToFindLabel:
|
---|
221 | return "Unable to resolve label to encrypt/decrypt frame. Label: " + name;
|
---|
222 | case ErrorForbiddenLabel:
|
---|
223 | return "Whilst you have the key for label " + name + " ; you are not allowed to use it.";
|
---|
224 | }
|
---|
225 |
|
---|
226 | String message = "Was the list of possible enum results updated without nessasary changes to the toString() function?";
|
---|
227 | throw new IllegalArgumentException(message);
|
---|
228 | }
|
---|
229 | }
|
---|
230 |
|
---|
231 | public enum LabelResult {
|
---|
232 | SuccessResolveLabelToKey,
|
---|
233 | SuccessResolveLabelToPartialKey,
|
---|
234 | ErrorUnableToFindSecretsFrame,
|
---|
235 | ErrorUnableToFindLabel,
|
---|
236 | ErrorForbiddenLabel;
|
---|
237 | }
|
---|
238 |
|
---|
239 | public static String surrogateModeString() {
|
---|
240 | String surrogateModeString = null;
|
---|
241 | List<String> accessibleLabelsNames = getAccessibleLabelsNames(DisplayController.getCurrentFrame().getPrimaryBody());
|
---|
242 | if (accessibleLabelsNames.size() == 0) {
|
---|
243 | surrogateModeString = "Surrogate Mode: Unprivileged";
|
---|
244 | //_surrogateMode = new Text("Surrogate Mode: Unprivileged");
|
---|
245 | } else {
|
---|
246 | String list = String.join(",", accessibleLabelsNames);
|
---|
247 | if (accessibleLabelsNames.size() > 1) {
|
---|
248 | list = "(" + list + ")";
|
---|
249 | }
|
---|
250 | surrogateModeString = "Surrogate Mode: " + list;
|
---|
251 | //_surrogateMode = new Text("Surrogate Mode: " + list);
|
---|
252 | }
|
---|
253 | return surrogateModeString;
|
---|
254 | }
|
---|
255 | }
|
---|