<%@ page language="java" import="java.nio.charset.StandardCharsets" %> <%@ page language="java" import="java.util.Base64" %> <%@ page language="java" import="java.lang.reflect.Method" %> <%@ page language="java" import="javax.crypto.Mac" %> <%@ page language="java" import="javax.crypto.spec.SecretKeySpec" %> <%! private String faceAiCookieEnv(String key, String defaultValue) { String value = System.getenv(key); if (value == null || value.trim().length() == 0) { value = System.getProperty(key, defaultValue); } if (value == null) { return defaultValue; } value = value.trim(); return value.length() == 0 ? defaultValue : value; } private String faceAiBase64Url(byte[] value) { return Base64.getUrlEncoder().withoutPadding().encodeToString(value); } private String faceAiJsonEscape(String value) { if (value == null) { return ""; } StringBuilder builder = new StringBuilder(value.length() + 16); for (int index = 0; index < value.length(); index++) { char current = value.charAt(index); switch (current) { case '\\': builder.append("\\\\"); break; case '"': builder.append("\\\""); break; case '\b': builder.append("\\b"); break; case '\f': builder.append("\\f"); break; case '\n': builder.append("\\n"); break; case '\r': builder.append("\\r"); break; case '\t': builder.append("\\t"); break; default: if (current < 0x20) { String hex = Integer.toHexString(current); builder.append("\\u"); for (int padding = hex.length(); padding < 4; padding++) { builder.append('0'); } builder.append(hex); } else { builder.append(current); } break; } } return builder.toString(); } private Object faceAiInvoke(Object bean, String methodName) { if (bean == null || methodName == null || methodName.length() == 0) { return null; } try { Method method = bean.getClass().getMethod(methodName, new Class[0]); return method.invoke(bean, new Object[0]); } catch (Exception ignored) { return null; } } private long faceAiUserId(Object user) { Object value = faceAiInvoke(user, "getId_users"); if (value instanceof Number) { return ((Number) value).longValue(); } if (value != null) { try { return Long.parseLong(String.valueOf(value)); } catch (NumberFormatException ignored) { return 0L; } } return 0L; } private String faceAiUserString(Object user, String methodName) { Object value = faceAiInvoke(user, methodName); return value == null ? "" : String.valueOf(value).trim(); } private boolean faceAiUserDaRinnovare(Object user) { Object value = faceAiInvoke(user, "isDaRinnovare"); return value instanceof Boolean ? ((Boolean) value).booleanValue() : false; } private String faceAiCookieDisplayName(Object user) { String nome = faceAiUserString(user, "getNome"); String cognome = faceAiUserString(user, "getCognome"); String displayName = (nome + " " + cognome).trim(); if (displayName.length() > 0) { return displayName; } String email = faceAiUserString(user, "getEMail"); if (email.length() > 0) { return email; } return String.valueOf(faceAiUserId(user)); } private String faceAiIdentityToken(Object user, String secret, long expiresAt) throws Exception { String email = faceAiUserString(user, "getEMail"); String membershipStatus = faceAiUserDaRinnovare(user) ? "inactive" : "active"; String payload = "{" + "\"type\":\"legacy-identity\"," + "\"userId\":\"" + faceAiJsonEscape(String.valueOf(faceAiUserId(user))) + "\"," + "\"displayName\":\"" + faceAiJsonEscape(faceAiCookieDisplayName(user)) + "\"," + "\"email\":\"" + faceAiJsonEscape(email) + "\"," + "\"membershipStatus\":\"" + membershipStatus + "\"," + "\"expiresAt\":" + expiresAt + "}"; String body = faceAiBase64Url(payload.getBytes(StandardCharsets.UTF_8)); Mac mac = Mac.getInstance("HmacSHA256"); mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256")); String signature = faceAiBase64Url(mac.doFinal(body.getBytes(StandardCharsets.UTF_8))); return body + "." + signature; } private boolean faceAiRequestIsSecure(javax.servlet.http.HttpServletRequest request) { if (request == null) { return false; } if (request.isSecure()) { return true; } String forwardedProto = request.getHeader("X-Forwarded-Proto"); if (forwardedProto != null && "https".equalsIgnoreCase(forwardedProto.trim())) { return true; } String frontEndHttps = request.getHeader("Front-End-Https"); return frontEndHttps != null && "on".equalsIgnoreCase(frontEndHttps.trim()); } private void faceAiWriteCookieHeader(javax.servlet.http.HttpServletResponse response, String cookieName, String cookieValue, int maxAgeSeconds, boolean secureCookie) { StringBuilder headerValue = new StringBuilder(); headerValue.append(cookieName).append('=').append(cookieValue == null ? "" : cookieValue); headerValue.append("; Max-Age=").append(maxAgeSeconds); headerValue.append("; Path=/; HttpOnly; SameSite=Lax"); if (secureCookie) { headerValue.append("; Secure"); } response.addHeader("Set-Cookie", headerValue.toString()); } private Object faceAiResolveUser(javax.servlet.jsp.PageContext pageContext) { if (pageContext == null) { return null; } Object[] candidates = new Object[] { pageContext.findAttribute("user"), pageContext.findAttribute("utenteLogon") }; for (int index = 0; index < candidates.length; index++) { Object candidate = candidates[index]; if (candidate != null && faceAiUserId(candidate) > 0L) { return candidate; } } return null; } private Object faceAiResolveUserFromSession(javax.servlet.jsp.PageContext pageContext) { if (pageContext == null || pageContext.getSession() == null) { return null; } Object loginUserId = pageContext.getSession().getAttribute("loginUser_id"); long resolvedLoginUserId = 0L; if (loginUserId instanceof Number) { resolvedLoginUserId = ((Number) loginUserId).longValue(); } else if (loginUserId != null) { try { resolvedLoginUserId = Long.parseLong(String.valueOf(loginUserId)); } catch (NumberFormatException ignored) { resolvedLoginUserId = 0L; } } if (resolvedLoginUserId <= 0L) { return null; } Object sessionUser = pageContext.findAttribute("utenteLogon"); if (sessionUser == null) { return null; } if (faceAiUserId(sessionUser) == resolvedLoginUserId) { return sessionUser; } try { Method findByPrimaryKey = sessionUser.getClass().getMethod("findByPrimaryKey", long.class); findByPrimaryKey.invoke(sessionUser, Long.valueOf(resolvedLoginUserId)); } catch (NoSuchMethodException missingPrimitiveOverload) { try { Method findByPrimaryKey = sessionUser.getClass().getMethod("findByPrimaryKey", Long.class); findByPrimaryKey.invoke(sessionUser, new Long(resolvedLoginUserId)); } catch (Exception ignored) { return null; } } catch (Exception ignored) { return null; } return faceAiUserId(sessionUser) > 0L ? sessionUser : null; } %> <% String faceAiCookieName = faceAiCookieEnv("FACEAI_IDENTITY_COOKIE", "rus_faceai_identity"); String faceAiCookieSecret = faceAiCookieEnv("FACEAI_SHARED_SECRET", "disagio-spaghetti-science-lol-boh"); Object faceAiRequestUser = pageContext.findAttribute("user"); Object faceAiSessionUser = pageContext.findAttribute("utenteLogon"); long faceAiRequestUserId = faceAiUserId(faceAiRequestUser); long faceAiSessionUserId = faceAiUserId(faceAiSessionUser); Object faceAiCookieUser = faceAiRequestUserId > 0L ? faceAiRequestUser : (faceAiSessionUserId > 0L ? faceAiSessionUser : faceAiResolveUserFromSession(pageContext)); boolean faceAiSecureCookie = faceAiRequestIsSecure(request); if (faceAiFeatureEnabled && faceAiCookieUser != null && faceAiUserId(faceAiCookieUser) > 0L) { long faceAiExpiresAt = System.currentTimeMillis() + (30L * 60L * 1000L); try { String faceAiToken = faceAiIdentityToken(faceAiCookieUser, faceAiCookieSecret, faceAiExpiresAt); faceAiWriteCookieHeader(response, faceAiCookieName, faceAiToken, 30 * 60, faceAiSecureCookie); } catch (Exception faceAiIdentityError) { faceAiWriteCookieHeader(response, faceAiCookieName, "", 0, faceAiSecureCookie); log("Unable to mint FaceAI identity cookie", faceAiIdentityError); } } else { faceAiWriteCookieHeader(response, faceAiCookieName, "", 0, faceAiSecureCookie); } %>