1 package com.acumenvelocity.ath.security;
2
3 import java.io.IOException;
4 import java.util.HashSet;
5 import java.util.Set;
6
7 import javax.servlet.Filter;
8 import javax.servlet.FilterChain;
9 import javax.servlet.FilterConfig;
10 import javax.servlet.ServletException;
11 import javax.servlet.ServletRequest;
12 import javax.servlet.ServletResponse;
13 import javax.servlet.http.HttpServletRequest;
14 import javax.servlet.http.HttpServletResponse;
15
16 import com.acumenvelocity.ath.common.Const;
17 import com.acumenvelocity.ath.common.Log;
18
19 import net.sf.okapi.common.Util;
20
21
22
23
24
25 public class ApiKeyAuthFilter implements Filter {
26
27 private static final String API_KEY_HEADER = "X-API-Key";
28 private static final Set<String> VALID_API_KEYS = new HashSet<>();
29
30
31 private static final Set<String> PUBLIC_PATHS = new HashSet<>();
32
33 static {
34
35
36 if (!Util.isEmpty(Const.ATH_API_KEY)) {
37 VALID_API_KEYS.add(Const.ATH_API_KEY);
38 }
39
40
41 PUBLIC_PATHS.add("/public");
42 PUBLIC_PATHS.add("/site");
43 PUBLIC_PATHS.add("/api/version");
44 PUBLIC_PATHS.add("/api/openapi.json");
45 }
46
47 @Override
48 public void init(FilterConfig filterConfig) throws ServletException {
49 }
50
51 @Override
52 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
53 throws IOException, ServletException {
54
55 HttpServletRequest httpRequest = (HttpServletRequest) request;
56 HttpServletResponse httpResponse = (HttpServletResponse) response;
57
58 String path = httpRequest.getRequestURI();
59
60
61 if (isPublicPath(path)) {
62 chain.doFilter(request, response);
63 return;
64 }
65
66
67 if (Util.isEmpty(Const.ATH_API_KEY)) {
68 chain.doFilter(request, response);
69 return;
70 }
71
72
73 String apiKey = httpRequest.getHeader(API_KEY_HEADER);
74
75
76 if (Util.isEmpty(apiKey)) {
77 sendUnauthorizedResponse(httpResponse, "Missing API key");
78 return;
79 }
80
81 if (!VALID_API_KEYS.contains(apiKey)) {
82 sendUnauthorizedResponse(httpResponse, "Invalid API key");
83 return;
84 }
85
86
87 chain.doFilter(request, response);
88 }
89
90 @Override
91 public void destroy() {
92
93 }
94
95
96
97
98 private boolean isPublicPath(String path) {
99 for (String publicPath : PUBLIC_PATHS) {
100 if (path.startsWith(publicPath)) {
101 return true;
102 }
103 }
104
105 return false;
106 }
107
108
109
110
111 private void sendUnauthorizedResponse(HttpServletResponse response, String message)
112 throws IOException {
113
114 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
115 response.setContentType("application/json");
116
117 response.getWriter().write(
118 Log.format("{\"code\": 401, \"message\": \"{}\"}", message));
119 }
120 }