From e44e9f860b11a50b3e39e3895ea9ea5624282b78 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 15 May 2023 12:06:14 -0700 Subject: Add HTML branding overrides --- src/main/java/org/traccar/api/MediaFilter.java | 11 +-- src/main/java/org/traccar/model/ExtendedModel.java | 8 ++- .../java/org/traccar/web/CharResponseWrapper.java | 82 ++++++++++++++++++++++ src/main/java/org/traccar/web/OverrideFilter.java | 71 +++++++++++++++++++ src/main/java/org/traccar/web/WebModule.java | 4 +- 5 files changed, 163 insertions(+), 13 deletions(-) create mode 100644 src/main/java/org/traccar/web/CharResponseWrapper.java create mode 100644 src/main/java/org/traccar/web/OverrideFilter.java (limited to 'src/main/java') diff --git a/src/main/java/org/traccar/api/MediaFilter.java b/src/main/java/org/traccar/api/MediaFilter.java index ab75bdc5d..e6556189a 100644 --- a/src/main/java/org/traccar/api/MediaFilter.java +++ b/src/main/java/org/traccar/api/MediaFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2023 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -32,7 +32,6 @@ import javax.inject.Inject; import javax.inject.Singleton; import javax.servlet.Filter; import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; @@ -57,10 +56,6 @@ public class MediaFilter implements Filter { this.permissionsServiceProvider = permissionsServiceProvider; } - @Override - public void init(FilterConfig filterConfig) throws ServletException { - } - @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { @@ -99,8 +94,4 @@ public class MediaFilter implements Filter { } } - @Override - public void destroy() { - } - } diff --git a/src/main/java/org/traccar/model/ExtendedModel.java b/src/main/java/org/traccar/model/ExtendedModel.java index 7a61eda8c..6a4f502f7 100644 --- a/src/main/java/org/traccar/model/ExtendedModel.java +++ b/src/main/java/org/traccar/model/ExtendedModel.java @@ -89,14 +89,18 @@ public class ExtendedModel extends BaseModel { } } - public String getString(String key) { + public String getString(String key, String defaultValue) { if (attributes.containsKey(key)) { return attributes.get(key).toString(); } else { - return null; + return defaultValue; } } + public String getString(String key) { + return getString(key, null); + } + public double getDouble(String key) { if (attributes.containsKey(key)) { Object value = attributes.get(key); diff --git a/src/main/java/org/traccar/web/CharResponseWrapper.java b/src/main/java/org/traccar/web/CharResponseWrapper.java new file mode 100644 index 000000000..0e7976ce0 --- /dev/null +++ b/src/main/java/org/traccar/web/CharResponseWrapper.java @@ -0,0 +1,82 @@ +/* + * Copyright 2023 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.web; + +import javax.servlet.ServletOutputStream; +import javax.servlet.WriteListener; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServletResponseWrapper; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +public class CharResponseWrapper extends HttpServletResponseWrapper { + + private final ByteArrayOutputStream capture; + private ServletOutputStream output; + + public CharResponseWrapper(HttpServletResponse response) { + super(response); + capture = new ByteArrayOutputStream(response.getBufferSize()); + } + + @Override + public ServletOutputStream getOutputStream() { + if (output == null) { + output = new ServletOutputStream() { + @Override + public boolean isReady() { + return true; + } + + @Override + public void setWriteListener(WriteListener writeListener) { + } + + @Override + public void write(int b) { + capture.write(b); + } + + @Override + public void flush() throws IOException { + capture.flush(); + } + + @Override + public void close() throws IOException { + capture.close(); + } + }; + } + return output; + } + + @Override + public void flushBuffer() throws IOException { + super.flushBuffer(); + if (output != null) { + output.flush(); + } + } + + public String getCaptureAsString() throws IOException { + if (output != null) { + output.close(); + } + return capture.toString(getCharacterEncoding()); + } + +} diff --git a/src/main/java/org/traccar/web/OverrideFilter.java b/src/main/java/org/traccar/web/OverrideFilter.java new file mode 100644 index 000000000..cb69dfbfa --- /dev/null +++ b/src/main/java/org/traccar/web/OverrideFilter.java @@ -0,0 +1,71 @@ +/* + * Copyright 2023 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.web; + +import com.google.inject.Provider; +import org.traccar.api.security.PermissionsService; +import org.traccar.model.Server; +import org.traccar.storage.StorageException; + +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@Singleton +public class OverrideFilter implements Filter { + + private final Provider permissionsServiceProvider; + + @Inject + public OverrideFilter(Provider permissionsServiceProvider) { + this.permissionsServiceProvider = permissionsServiceProvider; + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + + CharResponseWrapper wrapper = new CharResponseWrapper((HttpServletResponse) response); + + chain.doFilter(request, wrapper); + + Server server; + try { + server = permissionsServiceProvider.get().getServer(); + } catch (StorageException e) { + throw new RuntimeException(e); + } + + String title = server.getString("serverTitle", "Traccar"); + String description = server.getString("serverDescription", "Traccar GPS Tracking System"); + String colorPrimary = server.getString("serverColorPrimary", "#1a237e"); + + String alteredContent = wrapper.getCaptureAsString() + .replace("${title}", title) + .replace("${description}", description) + .replace("${colorPrimary}", colorPrimary); + + response.setContentLength(alteredContent.length()); + response.getWriter().write(alteredContent); + } + +} diff --git a/src/main/java/org/traccar/web/WebModule.java b/src/main/java/org/traccar/web/WebModule.java index 0722c5d1e..f06abf0b5 100644 --- a/src/main/java/org/traccar/web/WebModule.java +++ b/src/main/java/org/traccar/web/WebModule.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2022 - 2023 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,8 @@ public class WebModule extends ServletModule { @Override protected void configureServlets() { + filter("/").through(OverrideFilter.class); + filter("/manifest.json").through(OverrideFilter.class); filter("/api/*").through(ThrottlingFilter.class); filter("/api/media/*").through(MediaFilter.class); serve("/api/socket").with(AsyncSocketServlet.class); -- cgit v1.2.3