2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.jellyfin.internal.servlet;
15 import java.io.IOException;
17 import javax.servlet.http.HttpServlet;
18 import javax.servlet.http.HttpServletRequest;
19 import javax.servlet.http.HttpServletResponse;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.jellyfin.sdk.api.client.exception.ApiClientException;
23 import org.jetbrains.annotations.NotNull;
24 import org.openhab.binding.jellyfin.internal.handler.JellyfinServerHandler;
25 import org.openhab.binding.jellyfin.internal.util.SyncCallback;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
30 * The {@link JellyfinBridgeServlet} is responsible for handling user login.
32 * @author Miguel Álvarez - Initial contribution
35 public class JellyfinBridgeServlet extends HttpServlet {
36 private final Logger logger = LoggerFactory.getLogger(JellyfinBridgeServlet.class);
37 private static final long serialVersionUID = 2157912759968949550L;
38 private final JellyfinServerHandler server;
40 public JellyfinBridgeServlet(JellyfinServerHandler server) {
45 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
46 String requestUri = req.getRequestURI();
47 if (requestUri == null) {
50 String user = req.getParameter("username");
51 String password = req.getParameter("password");
52 if (user != null && password != null && !user.isBlank() && !password.isBlank()) {
54 server.updateCredentials(server.login(user, password));
55 } catch (SyncCallback.SyncCallbackError | ApiClientException e) {
56 logger.warn("Server error while login: {}", e.getMessage());
59 String newUri = req.getServletPath() + "/";
60 resp.sendRedirect(newUri);
64 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
65 String requestUri = req.getRequestURI();
66 if (requestUri == null) {
69 String uri = requestUri.substring(this.getServletContext().getContextPath().length());
70 logger.debug("doGet {}", uri);
71 if (!uri.endsWith("/")) {
72 String newUri = req.getServletPath() + "/";
73 resp.sendRedirect(newUri);
76 String serverUrl = server.getServerUrl();
77 String label = server.getThing().getLabel();
78 String serverName = label != null ? label : "Jellyfin Binding";
79 boolean online = server.isOnline();
80 boolean authenticated = online && server.isAuthenticated();
81 String html = renderPage(serverUrl, serverName, online, authenticated);
82 resp.addHeader("content-type", "text/html;charset=UTF-8");
84 resp.getWriter().write(html);
85 } catch (IOException e) {
86 logger.warn("return html failed with uri syntax error", e);
91 private String renderPage(String serverUrl, String serverName, boolean online, boolean authenticated) {
92 StringBuilder html = new StringBuilder();
93 html.append("<html><head><title>OpenHAB Jellyfin Binding</title><style>");
96 "*{box-sizing:border-box}body{background-color:#101010;font-family:Arial,sans-serif;padding:50px}.container{margin:20px auto;padding:10px;padding-bottom:0px;width:300px;background-color:#fff;border-radius:5px}h1{color:#777;font-size:32px;margin:15px auto;text-align:center}form{text-align:center}input{padding:12px 0;margin-bottom:10px;border-radius:3px;border:2px solid transparent;text-align:center;width:90%;font-size:16px;transition:border .2s,background-color .2s}form .field{background-color:#ecf0f1}form .field:focus{border:2px solid #3498db}form .btn{background-color:#00a4dc;color:#fff;line-height:25px;cursor:pointer}form .btn:active,form .btn:hover{background-color:#1f78b4;border:2px solid #1f78b4}.pass-link{text-align:center}.pass-link a:link,.pass-link a:visited{font-size:12px;color:#777} .status{padding-bottom: 18px;}");
98 ".oh-logo{background-image: url(/images/openhab-logo.svg);background-size: 89px;background-repeat: no-repeat;height: 44px; width: 144px; margin-left: 40px;}");
99 html.append(".logo{background-image: url(").append(serverUrl).append(
100 "/web/assets/img/banner-light.png);background-size: 140px;margin: 10px auto;background-repeat: no-repeat;width: 44px;height: 44px;}");
101 html.append("</style></head><body>");
103 html.append("<div class=\"container\">");
104 // add logos and title
105 html.append("<h2 class=\"logo\"><p class=\"oh-logo\"><p></h2><h1>").append(serverName).append("</h1>");
107 if (!authenticated) {
110 "<form action=\"#\" method=\"POST\"><input name=\"username\" type=\"text\" placeholder=\"username\" class=\"field\"><input name=\"password\" type=\"password\" placeholder=\"password\" class=\"field\"><input type=\"submit\" value=\"Login\" class=\"btn\"></form>");
112 html.append("<h1 class=\"status\">✅ Connected</h1>");
115 html.append("<h1 class=\"status\">❌ Offline</h1>");
118 html.append("</div>");
120 html.append("<div class=\"pass-link\"><a target=\"_blank\" href=\"").append(serverUrl)
121 .append("\" >Server Url: ").append(serverUrl).append("</a></div>");
122 html.append("</body></html>");
123 return html.toString();