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