source: trunk/src/org/expeditee/encryption/items/surrogates/Label.java@ 1457

Last change on this file since 1457 was 1457, checked in by bnemhaus, 4 years ago

Fixed bug that did not get correct label names and was therefore causing Expeditee to attempt to display encrypted primaries.

Suppressed using MessageBay because the way the code is currently structured this causes recursive infinite loop. Until code restructured, the 'fix' is to use std err instead.

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