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

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

Window title now notifies you when you are in surrogate mode.
Window title also now notifies you when you are running demo mode.

File size: 8.6 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.DisplayController;
12import org.expeditee.gui.ItemsList;
13import org.expeditee.items.Item;
14import org.expeditee.items.Text;
15import org.expeditee.settings.identity.secrets.KeyList;
16
17public 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}
Note: See TracBrowser for help on using the repository browser.