1 package com.atlassian.security.auth.trustedapps;
2
3 import java.text.MessageFormat;
4 import java.util.HashMap;
5 import java.util.Map;
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 public class TransportErrorMessage
25 {
26 static final Parser PARSER = new Parser();
27
28
29
30 private final Code code;
31 private final String message;
32 private final String[] params;
33
34
35
36 TransportErrorMessage(final Code code, final String message, final String[] params)
37 {
38 Null.not("code", code);
39 Null.not("params", params);
40 Null.not("message", message);
41 for (int i = 0; i < params.length; i++)
42 {
43 Null.not(String.valueOf(i), params[i]);
44 }
45
46 this.code = code;
47 this.message = message;
48 this.params = params;
49 }
50
51 TransportErrorMessage(final Code code, final String message)
52 {
53 this(code, message, new String[0]);
54 }
55
56 TransportErrorMessage(final Code code, final String message, final String param)
57 {
58 this(code, message, new String[] { param });
59 }
60
61 TransportErrorMessage(final Code code, final String message, final String one, final String two)
62 {
63 this(code, message, new String[] { one, two });
64 }
65
66 TransportErrorMessage(final Code code, final String message, final String one, final String two, final String three)
67 {
68 this(code, message, new String[] { one, two, three });
69 }
70
71
72
73 public Code getCode()
74 {
75 return code;
76 }
77
78 public String[] getParameters()
79 {
80 return params.clone();
81 }
82
83 public String getFormattedMessage()
84 {
85 return MessageFormat.format(message, (Object[]) params);
86 }
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102 @Override
103 public String toString()
104 {
105 return PARSER.toString(this);
106 }
107
108
109
110 static class System extends TransportErrorMessage
111 {
112 System(final Throwable cause, final String appId)
113 {
114 super(Code.SYSTEM, "Exception: {0} occurred serving request for application: {1}", cause.toString(), appId);
115 }
116 }
117
118 static class BadMagicNumber extends TransportErrorMessage
119 {
120 public BadMagicNumber(final String keyName, final String appId)
121 {
122 super(Code.BAD_MAGIC, "Unable to decrypt certificate {0} for application {1}", keyName, appId);
123 }
124 }
125
126 public static class BadProtocolVersion extends TransportErrorMessage
127 {
128 public BadProtocolVersion(final String versionString)
129 {
130 super(Code.BAD_PROTOCOL_VERSION, "Bad protocol version: {0}", versionString);
131 }
132 }
133
134
135
136
137 public static class ApplicationIdNotFoundInRequest extends TransportErrorMessage
138 {
139 public ApplicationIdNotFoundInRequest()
140 {
141 super(Code.APP_ID_NOT_FOUND, "Application ID not found in request");
142 }
143 }
144
145 public static class SecretKeyNotFoundInRequest extends TransportErrorMessage
146 {
147 public SecretKeyNotFoundInRequest()
148 {
149 super(Code.SECRET_KEY_NOT_FOUND, "Secret Key not found in request");
150 }
151 }
152
153 public static class MagicNumberNotFoundInRequest extends TransportErrorMessage
154 {
155 public MagicNumberNotFoundInRequest()
156 {
157 super(Code.MAGIC_NUMBER_NOT_FOUND, "Magic Number not found in request");
158 }
159 }
160
161 public static class ApplicationUnknown extends TransportErrorMessage
162 {
163 public ApplicationUnknown(final String appId)
164 {
165 super(Code.APP_UNKNOWN, "Unknown Application: {0}", appId);
166 }
167 }
168
169 public static class UserUnknown extends TransportErrorMessage
170 {
171 public UserUnknown(final String userName)
172 {
173 super(Code.USER_UNKNOWN, "Unknown User: {0}", userName);
174 }
175 }
176
177 public static class PermissionDenied extends TransportErrorMessage
178 {
179 public PermissionDenied()
180 {
181 super(Code.PERMISSION_DENIED, "Permission Denied");
182 }
183 }
184
185 public static class BadSignature extends TransportErrorMessage
186 {
187 public BadSignature(String url)
188 {
189 super(Code.BAD_SIGNATURE, "Bad signature for URL: {0}", url);
190 }
191
192 public BadSignature()
193 {
194 super(Code.BAD_SIGNATURE, "Missing signature in a v2 request");
195 }
196 }
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213 static class Parser
214 {
215 static final String SEPARATOR = ";\t";
216
217 TransportErrorMessage parse(final String inputItring) throws IllegalArgumentException
218 {
219 Null.not("inputString", inputItring);
220 final String[] args = inputItring.split(SEPARATOR);
221 if (args.length != 3)
222 {
223 throw new IllegalArgumentException("Cannot split message into Code, Message, Parameters:" + inputItring);
224 }
225 final Code code = Code.get(args[0]);
226 final String[] params = StringUtil.split(args[2]);
227 return new TransportErrorMessage(code, args[1], params);
228 }
229
230
231
232
233
234
235
236
237
238 String toString(final TransportErrorMessage msg)
239 {
240 return new StringBuffer(msg.code.getCode()).append(Parser.SEPARATOR).append(msg.message).append(Parser.SEPARATOR).append(
241 StringUtil.toString(msg.params)).toString();
242 }
243 }
244
245
246
247
248
249
250
251 public static final class Code
252 {
253 private static final Map<String, Code> ALL = new HashMap<String, Code>();
254
255 public static final Code UNKNOWN = new Code(Severity.ERROR, "UNKNOWN");
256
257 public static final Code APP_UNKNOWN = new Code(Severity.ERROR, "APP_UNKNOWN");
258 public static final Code SYSTEM = new Code(Severity.ERROR, "SYSTEM");
259 public static final Code BAD_PROTOCOL_VERSION = new Code(Severity.ERROR, "BAD_PROTOCOL_VERSION");
260 public static final Code APP_ID_NOT_FOUND = new Code(Severity.ERROR, "APP_ID_NOT_FOUND");
261 public static final Code SECRET_KEY_NOT_FOUND = new Code(Severity.ERROR, "SECRET_KEY_NOT_FOUND");
262 public static final Code MAGIC_NUMBER_NOT_FOUND = new Code(Severity.ERROR, "MAGIC_NUMBER_NOT_FOUND");
263
264 public static final Code BAD_REMOTE_IP = new Code(Severity.FAIL, "BAD_REMOTE_IP");
265 public static final Code BAD_XFORWARD_IP = new Code(Severity.FAIL, "BAD_XFORWARD_IP");
266 public static final Code BAD_URL = new Code(Severity.FAIL, "BAD_URL");
267 public static final Code OLD_CERT = new Code(Severity.FAIL, "OLD_CERT");
268 public static final Code MISSING_CERT = new Code(Severity.FAIL, "MISSING_CERT");
269 public static final Code BAD_MAGIC = new Code(Severity.FAIL, "BAD_MAGIC");
270 public static final Code USER_UNKNOWN = new Code(Severity.ERROR, "USER_UNKNOWN");
271 public static final Code PERMISSION_DENIED = new Code(Severity.ERROR, "PERMISSION_DENIED");
272 public static final Code BAD_SIGNATURE = new Code(Severity.FAIL, "BAD_SIGNATURE");
273
274 static Code get(final String code)
275 {
276 final Code result = ALL.get(code);
277 return (result == null) ? Code.UNKNOWN : result;
278 }
279
280 private final Severity severity;
281 private final String code;
282
283 private Code(final Severity severity, final String code)
284 {
285 Null.not("severity", severity);
286 Null.not("code", code);
287 this.severity = severity;
288 this.code = code;
289 if (ALL.containsKey(code))
290 {
291 throw new IllegalArgumentException(code + " is already mapped as a " + this.getClass().getName());
292 }
293 ALL.put(code, this);
294 }
295
296 public Severity getSeverity()
297 {
298 return severity;
299 }
300
301 public String getCode()
302 {
303 return code;
304 }
305
306 public static final class Severity
307 {
308 static final Severity ERROR = new Severity("ERROR");
309 static final Severity FAIL = new Severity("FAIL");
310
311 private final String name;
312
313 private Severity(final String name)
314 {
315 this.name = name;
316 }
317
318 @Override
319 public String toString()
320 {
321 return name;
322 }
323 }
324 }
325 }