|
9 | 9 | import java.nio.file.Path; |
10 | 10 | import java.nio.file.Paths; |
11 | 11 | import java.util.List; |
| 12 | +import java.util.stream.Collectors; |
12 | 13 |
|
13 | 14 | /** |
14 | 15 | * Implementation of {@link IDTokenSource} that reads the ID token from a file. The token is read |
15 | | - * using UTF-8 encoding and any leading/trailing whitespace is trimmed. |
| 16 | + * using UTF-8 encoding and any leading/trailing whitespace is trimmed. The file should contain |
| 17 | + * exactly one non-empty line with the token value. Files with multiple non-empty lines or only |
| 18 | + * empty lines will result in an error. |
16 | 19 | * |
17 | 20 | * @see IDTokenSource |
18 | 21 | */ |
19 | 22 | public class FileIDTokenSource implements IDTokenSource { |
| 23 | + private static final String ERROR_FILE_NOT_FOUND = "File %s does not exist"; |
| 24 | + private static final String ERROR_SECURITY_CHECK = |
| 25 | + "Security permission denied when checking if file %s exists: %s"; |
| 26 | + private static final String ERROR_READ_FAILED = "Failed to read ID token from file %s: %s"; |
| 27 | + private static final String ERROR_SECURITY_READ = |
| 28 | + "Security permission denied when reading file %s: %s"; |
| 29 | + private static final String ERROR_EMPTY_FILE = "File %s contains only empty lines"; |
| 30 | + private static final String ERROR_MULTIPLE_LINES = |
| 31 | + "The token should be a single line but the file %s contains %d non-empty lines"; |
| 32 | + private static final String ERROR_EMPTY_TOKEN = "Received empty ID token from file %s"; |
| 33 | + |
20 | 34 | /* The path to the file containing the ID token. */ |
21 | 35 | private final String filePath; |
22 | 36 |
|
@@ -64,43 +78,45 @@ public IDToken getIDToken(String audience) { |
64 | 78 |
|
65 | 79 | try { |
66 | 80 | if (!Files.exists(path)) { |
67 | | - throw new DatabricksException("File " + filePath + " does not exist"); |
| 81 | + throw new DatabricksException(String.format(ERROR_FILE_NOT_FOUND, filePath)); |
68 | 82 | } |
69 | 83 | } catch (SecurityException e) { |
70 | 84 | throw new DatabricksException( |
71 | | - "Security permission denied when checking if file " |
72 | | - + filePath |
73 | | - + " exists: " |
74 | | - + e.getMessage(), |
75 | | - e); |
| 85 | + String.format(ERROR_SECURITY_CHECK, filePath, e.getMessage()), e); |
76 | 86 | } |
77 | 87 |
|
78 | | - List<String> lines; |
| 88 | + List<String> rawLines; |
79 | 89 | try { |
80 | | - lines = Files.readAllLines(path, StandardCharsets.UTF_8); |
| 90 | + rawLines = Files.readAllLines(path, StandardCharsets.UTF_8); |
81 | 91 | } catch (IOException e) { |
82 | | - throw new DatabricksException( |
83 | | - "Failed to read ID token from file " + filePath + ": " + e.getMessage(), e); |
| 92 | + throw new DatabricksException(String.format(ERROR_READ_FAILED, filePath, e.getMessage()), e); |
84 | 93 | } catch (SecurityException e) { |
85 | 94 | throw new DatabricksException( |
86 | | - "Security permission denied when reading file " + filePath + ": " + e.getMessage(), e); |
| 95 | + String.format(ERROR_SECURITY_READ, filePath, e.getMessage()), e); |
87 | 96 | } |
88 | 97 |
|
89 | | - if (lines.isEmpty()) { |
90 | | - throw new DatabricksException("File " + filePath + " is empty"); |
| 98 | + // Filter out empty lines |
| 99 | + List<String> nonEmptyLines = |
| 100 | + rawLines.stream() |
| 101 | + .map(String::trim) |
| 102 | + .filter(line -> !line.isEmpty()) |
| 103 | + .collect(Collectors.toList()); |
| 104 | + |
| 105 | + if (nonEmptyLines.isEmpty()) { |
| 106 | + throw new DatabricksException(String.format(ERROR_EMPTY_FILE, filePath)); |
91 | 107 | } |
92 | 108 |
|
93 | | - String token; |
94 | | - try { |
95 | | - token = lines.get(0).trim(); |
96 | | - } catch (IndexOutOfBoundsException e) { |
97 | | - throw new DatabricksException("Invalid token format in file " + filePath); |
| 109 | + if (nonEmptyLines.size() > 1) { |
| 110 | + throw new DatabricksException( |
| 111 | + String.format(ERROR_MULTIPLE_LINES, filePath, nonEmptyLines.size())); |
98 | 112 | } |
99 | 113 |
|
| 114 | + String token = nonEmptyLines.get(0); |
| 115 | + |
100 | 116 | try { |
101 | 117 | return new IDToken(token); |
102 | 118 | } catch (IllegalArgumentException e) { |
103 | | - throw new DatabricksException("Received empty ID token from file " + filePath); |
| 119 | + throw new DatabricksException(String.format(ERROR_EMPTY_TOKEN, filePath)); |
104 | 120 | } |
105 | 121 | } |
106 | 122 | } |
0 commit comments